1
1

Integration of Pavel Machek's vfs code split and vfs syntax change.

The VFS code can now be used by other applications (if you compile the
libvfs.a target and link against this).

Syntax has changes internally from the url-like syntax to a new syntax
that does not have ambiguities.  A default conversor for the new syntax
will be provided in the future, also dealing with the user ~/.mc/ext files
is currently in a non-optimal state.

Keep an eye on this mailing list.

Miguel.
Этот коммит содержится в:
Miguel de Icaza 1998-05-26 00:53:24 +00:00
родитель fa9cc8e6a9
Коммит 7a7f7a3d85
29 изменённых файлов: 1050 добавлений и 1892 удалений

Просмотреть файл

@ -1 +1 @@
#define VERSION "4.1.34"
#define VERSION "4.1.35"

Просмотреть файл

@ -1089,8 +1089,8 @@ AC_DEFUN(AC_WITH_VFS, [
if $use_net_code; then
AC_DEFINE(USE_NETCODE)
fi
LIBVFS="libvfs.a"
LVFS="-lvfs"
LIBVFS="libvfs-mc.a"
LVFS="-lvfs-mc"
fastdepvfs=fastdepvfs
if test $have_socket = yes; then
mcserv="mcserv"

Просмотреть файл

@ -12,6 +12,7 @@
#include <string.h>
#include <ctype.h>
#define WANT_WIDGETS
#include "tty.h" /* for KEY_BACKSPACE */
#include "x.h"
#include "main.h"
#include "key.h"
@ -19,7 +20,6 @@
#include "dir.h"
#include "panel.h"
#include "gscreen.h"
#include "tty.h" /* for KEY_BACKSPACE */
#include "command.h"
#include "cmd.h"
#include "gdesktop.h"

Просмотреть файл

@ -4,12 +4,12 @@
* Written by Miguel de Icaza
*/
#include <config.h>
#include "myslang.h"
#include "util.h"
#include <gnome.h>
#include <gdk/gdkkeysyms.h>
#include <string.h>
#include "gconf.h"
#include "myslang.h"
#include "dlg.h"
#undef HAVE_LIBGPM
#include "mouse.h"

Просмотреть файл

@ -56,7 +56,7 @@
# then the file will be temporarily copied into a local directory
# and %f will be the full path to this local temporal file.
# If you don't want to get a local copy and want to get the
# virtual fs path (like ftp://ftp.cvut.cz/pub/hungry/xword), then
# virtual fs path (like /#ftp:ftp.cvut.cz/pub/hungry/xword), then
# use %d/%p instead of %f.
# %d -> name of the current directory (pwd, without trailing slash)
# %s -> "selected files", i.e. space separated list of tagged files if any
@ -70,8 +70,7 @@
#
# %cd -> the rest is not command, but a path which will mc cd internally
# into (cd wouldn't work, since it is a child process, and %cd handles
# even the vfs names (e.g. tar:archive.tar/path or
# ftp://tsx-11.mit.edu/
# even the vfs names
#
# %view -> the command you type will be piped into mc's internal file viewer
# if you type only the %view and no command, viewer will load %f file
@ -104,26 +103,26 @@
# .tgz, .tpz, .tar.gz, .tar.z, .tar.Z
regex/\.t([gp]?z|ar\.g?[zZ])$
Open=%cd tar:%d/%p/
Open=%cd %p#utar
View=%view{ascii} gzip -dc %f 2>/dev/null | tar tvvf -
Extract=gzip -dc %f 2>/dev/null | tar xf -
Icon=compressed.xpm
regex/\.tar\.bz$
# Open=%cd tar:%d/%p/
# Open=%cd %p#utar
View=%view{ascii} bzip -dc %f 2>/dev/null | tar tvvf -
Extract=bzip -dc %f 2>/dev/null | tar xf -
Icon=compressed.xpm
regex/\.tar\.bz2$
Open=%cd tar:%d/%p/
Open=%cd %p#utar
View=%view{ascii} bzip2 -dc %f 2>/dev/null | tar tvvf -
Extract=bzip2 -dc %f 2>/dev/null | tar xf -
Icon=compressed.xpm
# .tar
shell/.tar
Open=%cd tar:%d/%p/
Open=%cd %p#utar
View=%view{ascii} tar tvvf %f
Extract=tar xf %f
Icon=tar.xpm
@ -208,32 +207,32 @@ directory/^.*$
# ls-lR
regex/^ls-?lR$
Open=%cd lslR:%d/%p/
Open=%cd %p#lslR
View=%view{ascii}
Icon=plain_dir.xpm
regex/^ls-?lR\.(g?z|Z)$
Open=%cd lslR:%d/%p/
Open=%cd %p#lslR
View=%view{ascii} gunzip -c %f
Icon=plain_dir.xpm
# ftplist
regex/\.ftplist$
Open=%cd ftplist:%d/%p/
Open=%cd %p#ftplist
# rpm
regex/\.rpm$
Open=%cd rpm:%d/%p/
Open=%cd %p#rpm
Install this RPM=rpm -i %f
Upgrade this RPM=rpm -U %f
# deb
regex/\.deb$
Open=%cd deb:%d/%p/
Open=%cd %p#deb
View=%view{ascii} dpkg-deb -c %f
# zip
regex/\.(zip|ZIP)$
Open=%cd zip:%d/%p/
Open=%cd %p#uzip
View=%view{ascii} unzip -v %f
Icon=zip.xpm
Extract=unzip %f
@ -242,14 +241,14 @@ regex/\.(zip|ZIP)$
# zoo
shell/.zoo
Open=%cd zoo:%d/%p/
Open=%cd %p#uzoo
View=%view{ascii} zoo l %f
Icon=zoo.xpm
Extract=zoo x %f '*'
# lha
regex/\.(lha|LHA|lzh|LZH)$
Open=%cd lha:%d/%p/
Open=%cd %p#ulha
View=%view{ascii} lharc l %f
Icon=lharc.xpm
Extract=lharc x %f '*'
@ -257,7 +256,7 @@ regex/\.(lha|LHA|lzh|LZH)$
# arj
regex/\.a(rj|[0-9][0-9])$
Open=unarj l %f | %var{PAGER:more}
Open=%cd %p#uarj
View=%view{ascii} unarj l %f
Icon=zip.xpm
Extract=unarj x %f '*'
@ -265,7 +264,7 @@ regex/\.a(rj|[0-9][0-9])$
# ar library
regex/\.s?a$
Open=%cd arfs:%d/%p/
Open=%cd %p#uar
View=%view{ascii} nm %f
# C
@ -506,7 +505,7 @@ regex/\.html?$
# rar
regex/\.[rR]([aA][rR]|[0-9][0-9])$
Open=%cd rar:%d/%p/
Open=%cd %p#urar
View=%view{ascii} rar v -c- %f
Extract=rar x -c- %f '*'
Extract (with flags)=I=%{Enter any RAR flags:}; if test -n "$I";then rar x $I %f; fi

299
po/mc.pot
Просмотреть файл

@ -1,13 +1,62 @@
msgid ""
msgstr ""
"Date: 1998-05-25 00:45:01-0500\n"
"Date: 1998-05-25 07:34:02-0500\n"
"From: Miguel de Icaza,computo,622-4680 <miguel@metropolis.nuclecu.unam.mx>\n"
"Content-Type: text/plain; charset=\n"
"Xgettext-Options: --default-domain=mc --directory=.. --add-comments --keyword=_ --keyword=N_ --files-from=./POTFILES.in\n"
"Files: vfs/ftpfs.c vfs/mcfs.c edit/edit.c edit/edit_key_translator.c edit/editcmd.c edit/editmenu.c edit/editoptions.c edit/editwidget.c src/fixhlp.c src/achown.c src/background.c src/boxes.c src/chmod.c src/chown.c src/cmd.c src/command.c src/dialog.c src/dir.c src/ext.c src/file.c src/find.c src/help.c src/hotlist.c src/info.c src/layout.c src/learn.c src/main.c src/menu.c src/option.c src/panelize.c src/screen.c src/subshell.c src/tree.c src/user.c src/util.c src/utilunix.c src/view.c src/win.c src/wtools.c gnome/gcmd.c gnome/gdesktop.c gnome/glayout.c gnome/gprop.c gnome/gscreen.c gnome/gtools.c gnome/gview.c gnome/gwidget.c\n"
#: src/wtools.c:609 vfs/ftpfs.c:444 vfs/ftpfs.c:478 vfs/mcfs.c:184
msgid "Password:"
#: vfs/ftpfs.c:602
msgid " Could not set source routing (%s)"
msgstr ""
#: vfs/ftpfs.c:2778 vfs/ftpfs.c:2793
msgid ""
"~/.netrc file has not correct mode.\n"
"Remove password or correct mode."
msgstr ""
#: vfs/mcfs.c:156
msgid " MCFS "
msgstr ""
#: vfs/mcfs.c:156
msgid " The server does not support this version "
msgstr ""
#: edit/editcmd.c:413 edit/editcmd.c:722 edit/editcmd.c:734 edit/editcmd.c:835 edit/editcmd.c:918 gnome/gdesktop.c:1330 src/ext.c:295 src/help.c:320 src/main.c:671 src/subshell.c:700 src/subshell.c:726 src/utilunix.c:380 src/utilunix.c:384 src/utilunix.c:450 vfs/mcfs.c:172
msgid " Warning "
msgstr ""
#: vfs/mcfs.c:173
msgid ""
" The remote server is not running on a system port \n"
" you need a password to log in, but the information may \n"
" not be safe on the remote side. Continue? \n"
msgstr ""
#: vfs/mcfs.c:176
msgid " Yes "
msgstr ""
#: vfs/mcfs.c:176
msgid " No "
msgstr ""
#: vfs/mcfs.c:178
msgid " The remote server is running on stange port. Giving up.\n"
msgstr ""
#: vfs/mcfs.c:190
msgid " MCFS Password required "
msgstr ""
#: vfs/mcfs.c:204
msgid " Invalid password "
msgstr ""
#: vfs/mcfs.c:270
msgid " Too many open connections "
msgstr ""
#. The file-name is printed after the ':'
@ -66,10 +115,6 @@ msgstr ""
msgid " Save As "
msgstr ""
#: edit/editcmd.c:413 edit/editcmd.c:722 edit/editcmd.c:734 edit/editcmd.c:835 edit/editcmd.c:918 gnome/gdesktop.c:1347 src/ext.c:295 src/help.c:320 src/main.c:685 src/subshell.c:700 src/subshell.c:726 src/utilunix.c:377 src/utilunix.c:381 src/utilunix.c:447
msgid " Warning "
msgstr ""
#: edit/editcmd.c:414
msgid " A file already exists with this name. "
msgstr ""
@ -312,11 +357,11 @@ msgstr ""
msgid "Cancel quit"
msgstr ""
#: edit/editcmd.c:1969 gnome/gcmd.c:94 gnome/gdesktop.c:625 gnome/gdesktop.c:1204 src/cmd.c:248 src/file.c:2365 src/file.c:2691 src/file.c:2881 src/hotlist.c:1027 src/main.c:840 src/screen.c:2040 src/subshell.c:701 src/subshell.c:727 src/tree.c:1195 src/view.c:410
#: edit/editcmd.c:1969 gnome/gcmd.c:94 gnome/gdesktop.c:625 gnome/gdesktop.c:1187 src/cmd.c:248 src/file.c:2365 src/file.c:2691 src/file.c:2881 src/hotlist.c:1027 src/main.c:826 src/screen.c:2040 src/subshell.c:701 src/subshell.c:727 src/tree.c:1195 src/view.c:410
msgid "&Yes"
msgstr ""
#: edit/editcmd.c:1969 gnome/gcmd.c:94 gnome/gdesktop.c:625 gnome/gdesktop.c:1204 src/cmd.c:248 src/file.c:2365 src/file.c:2690 src/file.c:2881 src/hotlist.c:1027 src/main.c:840 src/screen.c:2040 src/subshell.c:701 src/subshell.c:727 src/tree.c:1195 src/view.c:410
#: edit/editcmd.c:1969 gnome/gcmd.c:94 gnome/gdesktop.c:625 gnome/gdesktop.c:1187 src/cmd.c:248 src/file.c:2365 src/file.c:2690 src/file.c:2881 src/hotlist.c:1027 src/main.c:826 src/screen.c:2040 src/subshell.c:701 src/subshell.c:727 src/tree.c:1195 src/view.c:410
msgid "&No"
msgstr ""
@ -581,11 +626,11 @@ msgstr ""
msgid "&Save mode..."
msgstr ""
#: edit/editmenu.c:243 edit/editmenu.c:252 src/main.c:1310
#: edit/editmenu.c:243 edit/editmenu.c:252 src/main.c:1296
msgid "&Layout..."
msgstr ""
#: edit/editmenu.c:262 edit/editmenu.c:271 edit/editmenu.c:388 src/chmod.c:174 src/chown.c:131 src/main.c:1341
#: edit/editmenu.c:262 edit/editmenu.c:271 edit/editmenu.c:388 src/chmod.c:174 src/chown.c:131 src/main.c:1327
msgid " File "
msgstr ""
@ -597,11 +642,11 @@ msgstr ""
msgid " Sear/Repl "
msgstr ""
#: edit/editmenu.c:265 edit/editmenu.c:274 edit/editmenu.c:438 src/main.c:1342
#: edit/editmenu.c:265 edit/editmenu.c:274 edit/editmenu.c:438 src/main.c:1328
msgid " Command "
msgstr ""
#: edit/editmenu.c:266 edit/editmenu.c:275 src/main.c:1343
#: edit/editmenu.c:266 edit/editmenu.c:275 src/main.c:1329
msgid " Options "
msgstr ""
@ -762,7 +807,7 @@ msgstr ""
msgid "Error initialising editor.\n"
msgstr ""
#: edit/editwidget.c:992 gnome/glayout.c:350 src/help.c:812 src/main.c:1672 src/screen.c:2256 src/screen.c:2290 src/tree.c:1451 src/view.c:1987
#: edit/editwidget.c:992 gnome/glayout.c:350 src/help.c:812 src/main.c:1658 src/screen.c:2256 src/screen.c:2290 src/tree.c:1451 src/view.c:1987
msgid "Help"
msgstr ""
@ -786,15 +831,15 @@ msgstr ""
msgid "Search"
msgstr ""
#: edit/editwidget.c:999 gnome/gdesktop.c:624 gnome/gdesktop.c:1100 gnome/gscreen.c:545 src/screen.c:2263 src/screen.c:2297
#: edit/editwidget.c:999 gnome/gdesktop.c:624 gnome/gscreen.c:545 src/screen.c:2263 src/screen.c:2297
msgid "Delete"
msgstr ""
#: edit/editwidget.c:1001 src/main.c:1674
#: edit/editwidget.c:1001 src/main.c:1660
msgid "PullDn"
msgstr ""
#: edit/editwidget.c:1002 gnome/gview.c:286 src/help.c:824 src/main.c:1675 src/view.c:1989 src/view.c:2009
#: edit/editwidget.c:1002 gnome/gview.c:286 src/help.c:824 src/main.c:1661 src/view.c:1989 src/view.c:2009
msgid "Quit"
msgstr ""
@ -2102,7 +2147,7 @@ msgstr ""
msgid "Content: "
msgstr ""
#: src/find.c:158 src/main.c:1206 src/main.c:1227
#: src/find.c:158 src/main.c:1192 src/main.c:1213
msgid "&Tree"
msgstr ""
@ -2594,7 +2639,7 @@ msgstr ""
msgid "key, or click with the mouse to define it. Move around with Tab."
msgstr ""
#: src/main.c:686
#: src/main.c:672
msgid ""
" The Commander can't change to the directory that \n"
" the subshell claims you are in. Perhaps you have \n"
@ -2602,131 +2647,131 @@ msgid ""
" extra access permissions with the \"su\" command? "
msgstr ""
#: src/main.c:761
#: src/main.c:747
msgid "Press any key to continue..."
msgstr ""
#: src/main.c:811
#: src/main.c:797
msgid " The shell is already running a command "
msgstr ""
#: gnome/gcmd.c:92 gnome/gdesktop.c:1202 src/main.c:838 src/screen.c:2038
#: gnome/gcmd.c:92 gnome/gdesktop.c:1185 src/main.c:824 src/screen.c:2038
msgid " The Midnight Commander "
msgstr ""
#: gnome/gcmd.c:93 src/main.c:839
#: gnome/gcmd.c:93 src/main.c:825
msgid " Do you really want to quit the Midnight Commander? "
msgstr ""
#: src/main.c:1203 src/main.c:1224
#: src/main.c:1189 src/main.c:1210
msgid "&Listing mode..."
msgstr ""
#: src/main.c:1204 src/main.c:1225
#: src/main.c:1190 src/main.c:1211
msgid "&Quick view C-x q"
msgstr ""
#: src/main.c:1205 src/main.c:1226
#: src/main.c:1191 src/main.c:1212
msgid "&Info C-x i"
msgstr ""
#: src/main.c:1208 src/main.c:1229
#: src/main.c:1194 src/main.c:1215
msgid "&Sort order..."
msgstr ""
#: src/main.c:1210 src/main.c:1231
#: src/main.c:1196 src/main.c:1217
msgid "&Filter..."
msgstr ""
#: src/main.c:1213 src/main.c:1234
#: src/main.c:1199 src/main.c:1220
msgid "&Network link..."
msgstr ""
#: src/main.c:1214 src/main.c:1235
#: src/main.c:1200 src/main.c:1221
msgid "FT&P link..."
msgstr ""
#: src/main.c:1218 src/main.c:1239
#: src/main.c:1204 src/main.c:1225
msgid "&Drive... M-d"
msgstr ""
#: src/main.c:1220 src/main.c:1241
#: src/main.c:1206 src/main.c:1227
msgid "&Rescan C-r"
msgstr ""
#: src/main.c:1245
#: src/main.c:1231
msgid "&User menu F2"
msgstr ""
#: src/main.c:1246
#: src/main.c:1232
msgid "&View F3"
msgstr ""
#: src/main.c:1247
#: src/main.c:1233
msgid "&Filtered view M-!"
msgstr ""
#: src/main.c:1248
#: src/main.c:1234
msgid "&Edit F4"
msgstr ""
#: src/main.c:1249
#: src/main.c:1235
msgid "&Copy F5"
msgstr ""
#: src/main.c:1250
#: src/main.c:1236
msgid "c&Hmod C-x c"
msgstr ""
#: src/main.c:1252
#: src/main.c:1238
msgid "&Link C-x l"
msgstr ""
#: src/main.c:1253
#: src/main.c:1239
msgid "&SymLink C-x s"
msgstr ""
#: src/main.c:1254
#: src/main.c:1240
msgid "edit s&Ymlink C-x C-s"
msgstr ""
#: src/main.c:1255
#: src/main.c:1241
msgid "ch&Own C-x o"
msgstr ""
#: src/main.c:1256
#: src/main.c:1242
msgid "&Advanced chown "
msgstr ""
#: src/main.c:1258
#: src/main.c:1244
msgid "&Rename/Move F6"
msgstr ""
#: src/main.c:1259
#: src/main.c:1245
msgid "&Mkdir F7"
msgstr ""
#: src/main.c:1260
#: src/main.c:1246
msgid "&Delete F8"
msgstr ""
#: src/main.c:1261
#: src/main.c:1247
msgid "&Quick cd M-c"
msgstr ""
#: src/main.c:1263
#: src/main.c:1249
msgid "select &Group M-+"
msgstr ""
#: src/main.c:1264
#: src/main.c:1250
msgid "u&Nselect group M-\\"
msgstr ""
#: src/main.c:1265
#: src/main.c:1251
msgid "reverse selec&Tion M-*"
msgstr ""
#: src/main.c:1267
#: src/main.c:1253
msgid "e&Xit F10"
msgstr ""
@ -2734,111 +2779,111 @@ msgstr ""
#. * as a panel still has some problems, I have not yet finished
#. * the WTree widget port, sorry.
#.
#: src/main.c:1276
#: src/main.c:1262
msgid "&Directory tree"
msgstr ""
#: src/main.c:1277
#: src/main.c:1263
msgid "&Find file M-?"
msgstr ""
#: src/main.c:1279
#: src/main.c:1265
msgid "s&Wap panels C-u"
msgstr ""
#: src/main.c:1280
#: src/main.c:1266
msgid "switch &Panels on/off C-o"
msgstr ""
#: src/main.c:1282
#: src/main.c:1268
msgid "&Compare directories C-x d"
msgstr ""
#: src/main.c:1283
#: src/main.c:1269
msgid "e&Xternal panelize C-x !"
msgstr ""
#: src/main.c:1285
#: src/main.c:1271
msgid "show directory s&Izes"
msgstr ""
#: src/main.c:1288
#: src/main.c:1274
msgid "command &History"
msgstr ""
#: src/main.c:1289
#: src/main.c:1275
msgid "di&Rectory hotlist C-\\"
msgstr ""
#: src/main.c:1291
#: src/main.c:1277
msgid "&Active VFS list C-x a"
msgstr ""
#: src/main.c:1294
#: src/main.c:1280
msgid "&Background jobs C-x j"
msgstr ""
#: src/main.c:1298
#: src/main.c:1284
msgid "&Undelete files (ext2fs only)"
msgstr ""
#: src/main.c:1301
#: src/main.c:1287
msgid "&Listing format edit"
msgstr ""
#: src/main.c:1303
#: src/main.c:1289
msgid "&Extension file edit"
msgstr ""
#: src/main.c:1304
#: src/main.c:1290
msgid "&Menu file edit"
msgstr ""
#: src/main.c:1309
#: src/main.c:1295
msgid "&Configuration..."
msgstr ""
#: src/main.c:1311
#: src/main.c:1297
msgid "c&Onfirmation..."
msgstr ""
#: src/main.c:1312
#: src/main.c:1298
msgid "&Display bits..."
msgstr ""
#: src/main.c:1314
#: src/main.c:1300
msgid "learn &Keys..."
msgstr ""
#: src/main.c:1317
#: src/main.c:1303
msgid "&Virtual FS..."
msgstr ""
#: src/main.c:1320
#: src/main.c:1306
msgid "&Save setup"
msgstr ""
#: src/main.c:1336 src/main.c:1338
#: src/main.c:1322 src/main.c:1324
msgid " Left "
msgstr ""
#: src/main.c:1338
#: src/main.c:1324
msgid " Above "
msgstr ""
#: src/main.c:1346 src/main.c:1348
#: src/main.c:1332 src/main.c:1334
msgid " Right "
msgstr ""
#: src/main.c:1348
#: src/main.c:1334
msgid " Below "
msgstr ""
#: src/main.c:1409
#: src/main.c:1395
msgid " Information "
msgstr ""
#: src/main.c:1410
#: src/main.c:1396
msgid ""
" Using the fast reload option may not reflect the exact \n"
" directory contents. In this cases you'll need to do a \n"
@ -2846,149 +2891,149 @@ msgid ""
" the details. "
msgstr ""
#: src/main.c:1673 src/screen.c:2257 src/screen.c:2291
#: src/main.c:1659 src/screen.c:2257 src/screen.c:2291
msgid "Menu"
msgstr ""
#: src/main.c:1884
#: src/main.c:1870
msgid "Thank you for using GNU Midnight Commander"
msgstr ""
#: src/main.c:2246
#: src/main.c:2232
msgid "with mouse support on xterm%s.\n"
msgstr ""
#: src/main.c:2247
#: src/main.c:2233
msgid " and the Linux console"
msgstr ""
#: src/main.c:2340
#: src/main.c:2326
msgid "The TERM environment variable is unset!\n"
msgstr ""
#: src/main.c:2592
#: src/main.c:2578
msgid "Library directory for the Midnight Commander: %s\n"
msgstr ""
#: src/main.c:2597
#: src/main.c:2583
msgid "Option -m is obsolete. Please look at Display Bits... in the Option's menu\n"
msgstr ""
#: src/main.c:2658
#: src/main.c:2644
msgid "[DEVEL-ONLY: Debug the background code]"
msgstr ""
#: src/main.c:2661
#: src/main.c:2647
msgid "Create command file to set default directory upon exit."
msgstr ""
#: src/main.c:2663
#: src/main.c:2649
msgid "Force color mode."
msgstr ""
#: src/main.c:2664
#: src/main.c:2650
msgid "Specify colors (use --help-colors to get a list)."
msgstr ""
#: src/main.c:2666
#: src/main.c:2652
msgid "[DEVEL-ONLY: Debug the subshell."
msgstr ""
#: src/main.c:2668
#: src/main.c:2654
msgid "Startup the internal editor."
msgstr ""
#: src/main.c:2669
#: src/main.c:2655
msgid "Shows this help message."
msgstr ""
#: src/main.c:2670
#: src/main.c:2656
msgid "Help on how to specify colors."
msgstr ""
#: src/main.c:2672
#: src/main.c:2658
msgid "Log ftpfs commands to the file."
msgstr ""
#: src/main.c:2674
#: src/main.c:2660
msgid "Prints out the configured paths."
msgstr ""
#: src/main.c:2676
#: src/main.c:2662
msgid "Force black and white display."
msgstr ""
#: src/main.c:2677
#: src/main.c:2663
msgid "Disable mouse support."
msgstr ""
#: src/main.c:2679
#: src/main.c:2665
msgid "Force the concurrent subshell mode"
msgstr ""
#: src/main.c:2680
#: src/main.c:2666
msgid "Disable the concurrent subshell mode."
msgstr ""
#: src/main.c:2681
#: src/main.c:2667
msgid "Force subshell execution."
msgstr ""
#: src/main.c:2683
#: src/main.c:2669
msgid "At exit, print the last working directory."
msgstr ""
#: src/main.c:2684
#: src/main.c:2670
msgid "Reset softkeys (HP terminals only) to their terminfo/termcap default."
msgstr ""
#: src/main.c:2685
#: src/main.c:2671
msgid "Disables verbose operation (for slow terminals)."
msgstr ""
#: src/main.c:2687
#: src/main.c:2673
msgid "Use simple symbols for line drawing."
msgstr ""
#: src/main.c:2692
#: src/main.c:2678
msgid "Activate support for the TERMCAP variable."
msgstr ""
#: src/main.c:2694
#: src/main.c:2680
msgid "Report versionand configuration options."
msgstr ""
#: src/main.c:2695
#: src/main.c:2681
msgid "Start up into the viewer mode."
msgstr ""
#: src/main.c:2696
#: src/main.c:2682
msgid "Force xterm mouse support and screen save/restore"
msgstr ""
#: src/main.c:2697
#: src/main.c:2683
msgid "Geometry for the window"
msgstr ""
#: src/main.c:2698
#: src/main.c:2684
msgid "No windows opened at startup"
msgstr ""
#: src/main.c:2775
#: src/main.c:2761
msgid "[this dir] [other dir]"
msgstr ""
#: src/main.c:3017
#: src/main.c:3003
msgid ""
"Couldn't open tty line. You have to run mc without the -P flag.\n"
"On some systems you may want to run # `which mc`\n"
msgstr ""
#: src/main.c:3105
#: src/main.c:3091
msgid " Notice "
msgstr ""
#: src/main.c:3106
#: src/main.c:3092
msgid ""
" The Midnight Commander configuration files \n"
" are now stored in the ~/.mc directory, the \n"
@ -3221,7 +3266,7 @@ msgstr ""
msgid "Unknow tag on display format: "
msgstr ""
#: gnome/gdesktop.c:1203 src/screen.c:2039
#: gnome/gdesktop.c:1186 src/screen.c:2039
msgid " Do you really want to execute? "
msgstr ""
@ -3360,15 +3405,15 @@ msgstr ""
msgid " User menu "
msgstr ""
#: src/util.c:232
#: src/util.c:235
msgid "name_trunc: too big"
msgstr ""
#: src/utilunix.c:377
#: src/utilunix.c:380
msgid " Pipe failed "
msgstr ""
#: src/utilunix.c:381
#: src/utilunix.c:384
msgid " Dup failed "
msgstr ""
@ -3709,6 +3754,10 @@ msgstr ""
msgid "NumLock on keypad"
msgstr ""
#: src/wtools.c:609
msgid "Password:"
msgstr ""
#: src/wtools.c:609
msgid "Password"
msgstr ""
@ -3738,19 +3787,15 @@ msgstr ""
msgid "Do you want to delete "
msgstr ""
#: gnome/gdesktop.c:1093 gnome/gscreen.c:514 gnome/gscreen.c:515
msgid "Properties"
msgstr ""
#: gnome/gdesktop.c:1213
#: gnome/gdesktop.c:1196
msgid "Open with..."
msgstr ""
#: gnome/gdesktop.c:1214 gnome/gscreen.c:466
#: gnome/gdesktop.c:1197 gnome/gscreen.c:466
msgid "Enter extra arguments:"
msgstr ""
#: gnome/gdesktop.c:1347
#: gnome/gdesktop.c:1330
msgid " Could not open %s directory"
msgstr ""
@ -4094,6 +4139,10 @@ msgstr ""
msgid " Open with..."
msgstr ""
#: gnome/gscreen.c:514 gnome/gscreen.c:515
msgid "Properties"
msgstr ""
#: gnome/gscreen.c:517 gnome/gscreen.c:518
msgid "Open"
msgstr ""

Просмотреть файл

@ -66,7 +66,7 @@ cons.saver: cons.saver.o
check:
@echo no tests are supplied.
mc: $(OBJS) @LIBVFS@ @LIBSLANG@ @LIBEDIT_A@
mc: $(OBJS) libvfs-mc.a @LIBSLANG@ @LIBEDIT_A@
$(CC) $(LDFLAGS) -o $@ $(OBJS) -L../vfs -L../slang -L../edit $(OURLIBS) $(LIBS)
mfmt: mfmt.o
@ -75,10 +75,10 @@ mfmt: mfmt.o
mcmfmt: mfmt
cp mfmt mcmfmt
libvfs.a:
cd ../vfs; $(MAKE) libvfs.a
@PCENTRULE@ -$(RMF) libvfs.a
@PCENTRULE@ $(LN_S) ../vfs/libvfs.a .
libvfs-mc.a:
cd ../vfs; $(MAKE) libvfs-mc.a
@PCENTRULE@ -$(RMF) libvfs-mc.a
@PCENTRULE@ $(LN_S) ../vfs/libvfs-mc.a .
libmcslang.a:
cd ../slang; $(MAKE) libmcslang.a
@ -109,7 +109,7 @@ TAGS: $(SRCS)
clean:
$(RMF) mc cons.saver man2hlp fixhlp *.o core a.out mc.html mcmfmt
$(RMF) libvfs.a libedit.a libmcslang.a mfmt
$(RMF) libvfs-mc.a libedit.a libmcslang.a mfmt
realclean: clean
$(RMF) .depend
@ -121,7 +121,7 @@ distclean:
-$(RMF) $(srcdir)/mfmt
-$(RMF) $(srcdir)/man2hlp $(srcdir)/fixhlp $(srcdir)/*.o $(srcdir)/core
-$(RMF) $(srcdir)/a.out $(srcdir)/mc.html
-$(RMF) $(srcdir)/libvfs.a $(srcdir)/libmcslang.a $(srcdir)/libedit.a
-$(RMF) $(srcdir)/libvfs-mc.a $(srcdir)/libmcslang.a $(srcdir)/libedit.a
-if test $(srcdir) = .; then $(MAKE) realclean; fi
-$(RMF) $(srcdir)/Makefile

Просмотреть файл

@ -37,6 +37,7 @@
#include <string.h>
#include <fcntl.h>
#include <stdio.h>
#include "tty.h"
#include "dlg.h"
#include "widget.h"
#include "wtools.h"
@ -48,7 +49,6 @@
#ifdef USE_NETCODE
# include <sys/socket.h>
#endif
#include "tty.h"
#include "util.h"
#include "dialog.h"
#include "file.h"

Просмотреть файл

@ -1259,13 +1259,13 @@ static void nice_cd (char *text, char *xtext, char *help, char *prefix, int to_h
void netlink_cmd (void)
{
nice_cd (_(" Link to a remote machine "), _(machine_str),
"[Network File System]", "mc:", 1);
"[Network File System]", "/#mc:", 1);
}
void ftplink_cmd (void)
{
nice_cd (_(" FTP to machine "), _(machine_str),
"[FTP File System]", "ftp://", 1);
"[FTP File System]", "/#ftp:", 1);
}
#ifdef HAVE_SETSOCKOPT
@ -1296,7 +1296,7 @@ void undelete_cmd (void)
nice_cd (_(" Undelete files on an ext2 file system "),
_(" Enter the file system name where you want to run the\n "
" undelete file system on: (F1 for details)"),
"[Undelete File System]", "undel:", 0);
"[Undelete File System]", "/#undel/", 0);
}
#endif

Просмотреть файл

@ -306,7 +306,7 @@ static int
add_dotdot_to_list (dir_list *list, int index)
{
char buffer [MC_MAXPATHLEN + MC_MAXPATHLEN];
char *p, *s;
char *p;
int i = 0;
/* Need to grow the *list? */
@ -337,7 +337,7 @@ add_dotdot_to_list (dir_list *list, int index)
break;
}
i = 1;
if ((s = vfs_path (p)) && !strcmp (s, PATH_SEP_STR)){
if (!strcmp (p, PATH_SEP_STR)){
free (p);
return 1;
}

Просмотреть файл

@ -387,20 +387,6 @@ cd_try_to_select (WPanel *panel)
&& strchr (panel->lwd + strlen (panel->cwd) + 1, PATH_SEP) == 0)
try_to_select (panel, panel->lwd);
else
#ifdef USE_VFS
if ((!strncmp (panel->lwd, "tar:", 4) &&
!strncmp (panel->lwd + 4, panel->cwd, strlen (panel->cwd))) ||
((i = extfs_prefix_to_type (panel->lwd)) != -1 &&
!strncmp (panel->lwd + (j = strlen (extfs_get_prefix (i)) + 1),
panel->cwd, strlen (panel->cwd)))) {
p = strdup (panel->lwd + j + strlen (panel->cwd));
q = strchr (p, PATH_SEP);
if (q != NULL && (q != p || (q = strchr (q + 1, PATH_SEP)) != NULL))
*q = 0;
try_to_select (panel, p);
free (p);
} else
#endif
try_to_select (panel, NULL);
}

Просмотреть файл

@ -1528,7 +1528,7 @@ static int my_mkdir_rec (char *s, mode_t mode)
/* FIXME: should check instead if s is at the root of that filesystem */
if (!vfs_file_is_local (s))
return -1;
if (!strcmp (vfs_path(s), PATH_SEP_STR))
if (!strcmp (s, PATH_SEP_STR))
return ENOTDIR;
p = concat_dir_and_file (s, "..");
q = vfs_canon (p);

Просмотреть файл

@ -103,6 +103,7 @@ char *strdup (const char *s)
}
#endif
#ifndef VFS_STANDALONE
int is_printable (int c)
{
static const unsigned char xterm_printable[] = {
@ -165,6 +166,7 @@ char *trim (char *s, char *d, int len)
strcpy (d, s);
return d;
}
#endif
char *
name_quote (const char *s, int quote_percent)
@ -210,6 +212,7 @@ name_quote (const char *s, int quote_percent)
return ret;
}
#ifndef VFS_STANDALONE
char *
fake_name_quote (const char *s, int quote_percent)
{
@ -358,51 +361,24 @@ strip_password (char *path)
char *strip_home_and_password(char *dir)
{
static char newdir [MC_MAXPATHLEN], *p, *q;
static char newdir [MC_MAXPATHLEN];
if (home_dir && !strncmp (dir, home_dir, strlen (home_dir))){
newdir [0] = '~';
strcpy (&newdir [1], &dir [strlen (home_dir)]);
return newdir;
}
#ifdef USE_NETCODE
else if (!strncmp (dir, "ftp://", 6)) {
strip_password (strcpy (newdir, dir) + 6);
if ((p = strchr (newdir + 6, PATH_SEP)) != NULL) {
*p = 0;
q = ftpfs_gethome (newdir);
*p = PATH_SEP;
if (q != 0 && strcmp (q, PATH_SEP_STR) && !strncmp (p, q, strlen (q) - 1)) {
strcpy (p, "/~");
strcat (newdir, p + strlen (q) - 1);
}
}
return newdir;
} else if (!strncmp (dir, "mc:", 3)) {
char *pth;
strcpy (newdir, dir);
if (newdir[3] == '/' && newdir[4] == '/') {
pth = newdir + 5;
strip_password ( newdir + 5);
} else {
pth = newdir + 3;
strip_password (newdir + 3);
}
if ((p = strchr (pth, PATH_SEP)) != NULL) {
*p = 0;
q = mcfs_gethome (newdir);
*p = PATH_SEP;
if (q != NULL ) {
if (strcmp (q, PATH_SEP_STR) && !strncmp (p, q, strlen (q) - 1)) {
strcpy (p, "/~");
strcat (newdir, p + strlen (q) - 1);
}
free (q);
}
}
return (newdir);
/* We do not strip homes in /#ftp tree, I do not like ~'s there (see ftpfs.c why) */
#define STRIP( name ) \
if (strstr( dir, name )) { \
strcpy (newdir, dir); \
strip_password ( strstr( newdir, name ) + strlen(name) ); \
return newdir; \
}
#endif
STRIP( "/#ftp:" );
STRIP( "/#mc:" );
return dir;
}
@ -732,6 +708,7 @@ static void prepare_environment (void)
/* MC_CONTROL_FILE has been added to environment on startup */
}
#endif
#endif /* VFS_STANDALONE */
char *unix_error_string (int error_num)
{
@ -779,7 +756,8 @@ char *copy_strings (const char *first,...)
return result;
}
#ifndef VFS_STANDALONE
long blocks2kilos (int blocks, int bsize)
{
if (bsize > 1024){
@ -866,6 +844,7 @@ int strcasecmp (const char *s, const char *d)
return result;
}
#endif /* HAVE_STRCASECMP */
#endif /* VFS_STANDALONE */
/* getwd is better than getcwd, the later uses a popen ("pwd"); */
char *get_current_wd (char *buffer, int size)
@ -1001,6 +980,7 @@ decompress_command_and_arg (int type, char **cmd, char **flags)
fprintf (stderr, "Fatal: decompress_command called with an unknown argument\n");
}
#ifndef VFS_STANDALONE
/* Hooks */
void add_hook (Hook **hook_list, void (*hook_fn)(void *), void *data)
{
@ -1284,6 +1264,7 @@ int truncate (const char *path, long size)
}
#endif
#endif /* VFS_STANDALONE */
char *
concat_dir_and_file (const char *dir, const char *file)

Просмотреть файл

@ -98,6 +98,7 @@ max_open_files (void)
#endif
}
#ifndef VFS_STANDALONE
void init_groups (void)
{
int i;
@ -246,6 +247,7 @@ void save_stop_handler (void)
{
sigaction (SIGTSTP, NULL, &startup_handler);
}
#endif /* VFS_STANDALONE */
#ifdef HAVE_GNOME
#define PORT_HAS_MY_SYSTEM 1
@ -351,6 +353,7 @@ char *tilde_expand (char *directory)
return directory;
}
#ifndef VFS_STANDALONE
int
set_nonblocking (int fd)
{
@ -446,6 +449,7 @@ void check_error_pipe (void)
if (len > 0)
message (0, _(" Warning "), error);
}
#endif
static struct sigaction ignore, save_intr, save_quit, save_stop;
@ -675,6 +679,7 @@ char *canonicalize_pathname (char *path)
return path;
}
#ifndef VFS_STANDALONE
#ifdef SCO_FLAVOR
int gettimeofday( struct timeval * tv, struct timezone * tz)
{
@ -931,3 +936,4 @@ int socketpair(int dummy1, int dummy2, int dummy3, int fd[2])
#endif /* ifndef HAVE_SOCKETPAIR */
#endif /* ifdef USE_NETCODE */
#endif /* SCO_FLAVOR */
#endif /* VFS_STANDALONE */

Просмотреть файл

@ -25,6 +25,7 @@
/* }}} */
/* {{{ Declarations */
#include <config.h>
#include "tty.h"
#include "x.h"
#include <stdio.h>
#ifdef OS2_NT
@ -35,7 +36,6 @@
# include <unistd.h>
#endif
#include <string.h>
#include "tty.h"
#include <sys/stat.h>
#ifdef HAVE_MMAP
# include <sys/mman.h>

Просмотреть файл

@ -31,13 +31,29 @@ VFSOBJS = $(NONETFILES) @NETFILES@
EXTFSSTUFF = README extfs.ini a cpio.in deb.in ftplist.in lha.in lslR.in \
rar.in rpm zip.in zoo.in arfs patchfs mailfs hp48
#
# Commands to build standalone version (.so)
#
VFSSOOBJS = tcputil.so ftpfs.so mcfs.so utilvfs.so local.so vfs.so tar.so names.so container.so extfs.so util-alone.so util.sor utilunix.sor
%.sor: ../src/%.c
$(CC) -c $(CPPFLAGS) $(DEFS) $(CFLAGS) -DVFS_STANDALONE $< -o $@
%.so: %.c
$(CC) -c $(CPPFLAGS) $(DEFS) $(CFLAGS) -DVFS_STANDALONE $< -o $@
libvfs.so: $(VFSSOOBJS) libvfs.o
gcc $(VFSSOOBJS) libvfs.o -shared -o libvfs.so
#
# Distribution variables
#
DISTVFS = Makefile.in ChangeLog $(VFSSRCS) $(VFSHDRS)
all: @LIBVFS@ @mcserv@
all: libvfs-mc.a @mcserv@
.c.o:
$(CC) -c $(CPPFLAGS) $(DEFS) $(CFLAGS) $<
@ -59,7 +75,7 @@ mcservx: mcserv.o tcputil.o mad.o
$(CC) $(LDFLAGS) -o mcserv mcserv.o tcputil.o mad.o $(LIBS)
touch mcservx
libvfs.a: $(VFSOBJS)
libvfs-mc.a: $(VFSOBJS)
$(RMF) $@
$(AR) cr $@ $(VFSOBJS)
-$(RANLIB) $@
@ -75,7 +91,7 @@ TAGS: $(VFSSRCS)
etags $(VFSSRCS)
clean:
$(RMF) mcserv *.o core a.out libvfs.a mcservx
$(RMF) mcserv *.o core a.out libvfs-mc.a mcservx libvfs.so
realclean: clean
$(RMF) .depend
@ -84,7 +100,7 @@ realclean: clean
distclean:
-$(RMF) $(srcdir)/*~ $(srcdir)/mcserv $(srcdir)/*.o $(srcdir)/a.out
-$(RMF) $(srcdir)/core $(srcdir)/libvfs.a
-$(RMF) $(srcdir)/core $(srcdir)/libvfs-mc.a $(srcdir)/libvfs.so
-$(RMF) $(srcdir)/mad.c $(srcdir)/mad.h
-if test $(srcdir) = .; then $(MAKE) realclean; fi
-$(RMF) $(srcdir)/Makefile

Просмотреть файл

@ -2,6 +2,7 @@
Copyright (C) 1995 The Free Software Foundation
Written by: 1995 Jakub Jelinek
Rewritten by: 1998 Pavel Machek
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -37,6 +38,7 @@
#include <time.h>
#include "../src/fs.h"
#include "../src/util.h"
#include "../src/dialog.h"
#include "../src/mem.h"
#include "../src/mad.h"
#include "../src/main.h" /* For shell_execute */
@ -53,31 +55,18 @@ static struct stat hstat; /* Stat struct corresponding */
static char *current_file_name, *current_link_name;
static char *extfs_current_dir;
enum {
EFS_ARG_EMPTY,
EFS_NEED_FILE,
EFS_NEED_ARG
};
#define MAXEXTFS 32
static char *extfs_prefixes [MAXEXTFS];
static char extfs_need_archive [MAXEXTFS];
static int extfs_no = 0;
struct extfs_ext {
char *ext;
struct extfs_ext *next;
};
static struct extfs_ext *extfs_extensions [MAXEXTFS];
void extfs_fill_names (void (*func)(char *))
{
struct extfs_archive *a = first_archive;
char *name;
while (a){
name = copy_strings (extfs_prefixes [a->fstype], ":",
name = copy_strings (extfs_prefixes [a->fstype], "#",
(a->name ? a->name : ""), "/",
a->current_dir->name, 0);
(*func)(name);
@ -196,9 +185,10 @@ static FILE *open_extfs_archive (int fstype, char *name, struct extfs_archive **
struct extfs_archive *current_archive;
struct extfs_entry *root_entry;
char *local_name = NULL, *tmp = 0;
const int uses_archive = extfs_need_archive [fstype];
int uses_archive = extfs_need_archive [fstype];
char *tmpfile;
if (uses_archive == EFS_NEED_FILE){
if (uses_archive){
if (mc_stat (name, &mystat) == -1)
return NULL;
if (!vfs_file_is_local (name)) {
@ -209,9 +199,12 @@ static FILE *open_extfs_archive (int fstype, char *name, struct extfs_archive **
tmp = name_quote (name, 0);
}
#if 0
/* Sorry, what is this good for? */
if (uses_archive == EFS_NEED_ARG){
tmp = name_quote (name, 0);
}
#endif
cmd = copy_strings (LIBDIR "extfs/", extfs_prefixes [fstype],
" list ", local_name ? local_name : tmp, 0);
@ -226,7 +219,7 @@ static FILE *open_extfs_archive (int fstype, char *name, struct extfs_archive **
}
current_archive = (struct extfs_archive *)
xmalloc (sizeof (struct extfs_archive), "Tar archive");
xmalloc (sizeof (struct extfs_archive), "Extfs archive");
current_archive->fstype = fstype;
current_archive->name = name ? strdup (name): name;
current_archive->local_name = local_name;
@ -272,7 +265,7 @@ int read_extfs_archive (int fstype, char *name, struct extfs_archive **pparc)
struct extfs_archive *current_archive;
if ((extfsd = open_extfs_archive (fstype, name, &current_archive)) == NULL) {
message_3s (1, " Error ", "Couldn't open %s archive\n%s",
message_3s (1, MSG_ERROR, _("Couldn't open %s archive\n%s"),
extfs_prefixes [fstype], name);
return -1;
}
@ -304,7 +297,7 @@ int read_extfs_archive (int fstype, char *name, struct extfs_archive **pparc)
goto read_extfs_continue;
pent = extfs_find_entry (current_archive->root_entry, q, 1, 0) ;
if (pent == NULL) {
message_1s (1, " Error ", "Inconsistent extfs archive");
message_1s (1, MSG_ERROR, _("Inconsistent extfs archive"));
/* FIXME: Should clean everything one day */
free (buffer);
pclose (extfsd);
@ -324,7 +317,7 @@ int read_extfs_archive (int fstype, char *name, struct extfs_archive **pparc)
if (!S_ISLNK (hstat.st_mode) && current_link_name != NULL) {
pent = extfs_find_entry (current_archive->root_entry, current_link_name, 0, 0);
if (pent == NULL) {
message_1s (1, " Error ", "Inconsistent extfs archive");
message_1s (1, MSG_ERROR, _("Inconsistent extfs archive"));
/* FIXME: Should clean everything one day */
free (buffer);
pclose (extfsd);
@ -358,7 +351,8 @@ int read_extfs_archive (int fstype, char *name, struct extfs_archive **pparc)
inode->linkname = current_link_name;
current_link_name = NULL;
} else {
inode->mode &= ~S_IFLNK;
if (S_ISLNK( hstat.st_mode))
inode->mode &= ~S_IFLNK; /* You *DON'T* want to do this always */
inode->linkname = NULL;
}
if (S_ISDIR (hstat.st_mode))
@ -380,112 +374,46 @@ int read_extfs_archive (int fstype, char *name, struct extfs_archive **pparc)
return 0;
}
char *extfs_analysis (char *name, char **archive, int *fstype, int is_dir)
{
char *p, *local;
int j;
char *archive_name = NULL;
struct extfs_ext *ext;
/* | this is len of prefix plus some minimum
* v space needed for the extension */
*fstype = extfs_prefix_to_type (name);
if (*fstype == -1) {
extfserrno = ENOENT;
return NULL;
}
if (extfs_need_archive [*fstype] == EFS_ARG_EMPTY){
*archive = 0;
return strdup (name + strlen(extfs_prefixes [*fstype]) + 1);
}
if (extfs_need_archive [*fstype] == EFS_NEED_ARG){
char c;
p = strchr (name + strlen (extfs_prefixes [*fstype]) + 1, '/');
if (p){
c = *p;
*p = 0;
}
archive_name = strdup (name + strlen (extfs_prefixes [*fstype]) + 1);
if (p)
*p = c;
*archive = archive_name;
return p ? strdup (p+1) : NULL;
}
for (p = name + strlen (name); p > name; p--)
if (*p == '/' || (is_dir && !*p))
for (ext = extfs_extensions [*fstype]; ext; ext = ext->next) {
j = strlen (ext->ext);
if (p - j < name + 1)
continue;
if (!strncmp (p - j, ext->ext, j)) {
char c = *p;
*p = 0;
archive_name =
vfs_canon (name + strlen (extfs_prefixes [*fstype]) + 1);
*archive = archive_name;
*p = c;
local = strdup (p);
return local;
}
}
extfserrno = ENOENT;
return NULL;
}
/* Returns allocated path inside the archive or NULL */
static char *extfs_get_path (char *inname, struct extfs_archive **archive, int is_dir,
int do_not_open)
{
char *local, *archive_name;
char *local, *archive_name, *op;
int result = -1;
struct extfs_archive *parc;
struct vfs_stamping *parent;
vfs *v;
int fstype;
local = extfs_analysis (inname, &archive_name, &fstype, is_dir);
if (local == NULL) {
extfserrno = ENOENT;
return NULL;
}
archive_name = inname;
vfs_split( inname, &local, &op );
fstype = extfs_which( op );
if (!local)
local = "";
if (fstype == -1)
return NULL;
/* In the case of the file systems that do not require a local
* archive, we compare the fstype instead of the archive name,
* of course, this has the drawback that we can't have more than
* one external file system for each prefix.
/* All filesystems should have some local archive, at least
* it can be '/'.
*
* Actually, we should implement an alias mechanism that would
* translate: "a:" to "dos:a.
*
*/
for (parc = first_archive; parc != NULL; parc = parc->next)
if (archive_name){
if (parc->name) {
if (!strcmp (parc->name, archive_name)) {
vfs_stamp (&extfs_vfs_ops, (vfsid) parc);
goto return_success;
}
}
} else {
if (parc->fstype == fstype){
vfs_stamp (&extfs_vfs_ops, (vfsid) parc);
if (parc->name) {
if (!strcmp (parc->name, archive_name)) {
vfs_stamp (&extfs_vfs_ops, (vfsid) parc);
goto return_success;
}
}
if (do_not_open)
result = -1;
else
result = read_extfs_archive (fstype, archive_name, &parc);
result = do_not_open ? -1 : read_extfs_archive (fstype, archive_name, &parc);
if (result == -1) {
extfserrno = EIO;
free(local);
if (archive_name)
free(archive_name);
return NULL;
}
if (archive_name){
v = vfs_type (archive_name);
if (v == &local_vfs_ops) {
@ -501,8 +429,6 @@ static char *extfs_get_path (char *inname, struct extfs_archive **archive, int i
}
return_success:
*archive = parc;
if (archive_name)
free (archive_name);
return local;
}
@ -591,96 +517,6 @@ static struct extfs_entry *extfs_resolve_symlinks (struct extfs_entry *entry)
return res;
}
static struct extfs_entry*
__extfs_find_entry (struct extfs_entry *dir, char *name,
struct extfs_loop_protect *list, int make_dirs, int make_file)
{
struct extfs_entry *pent, *pdir;
char *p, *q, *name_end;
char c;
if (*name == '/') { /* Handle absolute paths */
name++;
dir = dir->inode->archive->root_entry;
}
pent = dir;
p = name;
name_end = name + strlen (name);
q = strchr (p, '/');
c = '/';
if (!q)
q = strchr (p, 0);
for (; pent != NULL && c && *p; ){
c = *q;
*q = 0;
if (strcmp (p, ".")){
if (!strcmp (p, ".."))
pent = pent->dir;
else {
if ((pent = __extfs_resolve_symlinks (pent, list))==NULL){
*q = c;
return NULL;
}
if (c == '/' && !S_ISDIR (pent->inode->mode)){
*q = c;
notadir = 1;
return NULL;
}
pdir = pent;
for (pent = pent->inode->first_in_subdir; pent; pent = pent->next_in_dir)
/* Hack: I keep the original semanthic unless
q+1 would break in the strchr */
if (!strcmp (pent->name, p)){
if (q + 1 > name_end){
*q = c;
notadir = !S_ISDIR (pent->inode->mode);
return pent;
}
break;
}
/* When we load archive, we create automagically
* non-existant directories
*/
if (pent == NULL && make_dirs) {
pent = generate_entry (dir->inode->archive, p, pdir, S_IFDIR | 0777);
}
if (pent == NULL && make_file) {
pent = generate_entry (dir->inode->archive, p, pdir, 0777);
}
}
}
/* Next iteration */
*q = c;
p = q + 1;
q = strchr (p, '/');
if (!q)
q = strchr (p, 0);
}
if (pent == NULL)
extfserrno = ENOENT;
return pent;
}
static struct extfs_entry *extfs_find_entry (struct extfs_entry *dir, char *name, int make_dirs, int make_file)
{
struct extfs_entry *res;
errloop = 0;
notadir = 0;
res = __extfs_find_entry (dir, name, NULL, make_dirs, make_file);
if (res == NULL) {
if (errloop)
extfserrno = ELOOP;
else if (notadir)
extfserrno = ENOTDIR;
}
return res;
}
struct extfs_pseudofile {
struct extfs_archive *archive;
unsigned int has_changed:1;
@ -710,14 +546,18 @@ void extfs_run (char *file)
if ((p = extfs_get_path (file, &archive, 0, 0)) == NULL)
return;
q = name_quote (((*p == '/') ? p + 1 : p), 0);
q = name_quote (p, 0);
archive_name = name_quote (get_archive_name(archive), 0);
cmd = copy_strings (LIBDIR "extfs/", extfs_prefixes [archive->fstype],
" run ", archive_name, " ", q, 0);
free (archive_name);
free (q);
#ifndef VFS_STANDALONE
shell_execute(cmd, 0);
#else
vfs_die( "shell_execute: implement me!" );
#endif
free(cmd);
free(p);
}
@ -726,28 +566,24 @@ static void *extfs_open (char *file, int flags, int mode)
{
struct extfs_pseudofile *extfs_info;
struct extfs_archive *archive;
char *p, *q;
char *q;
struct extfs_entry *entry;
int local_handle;
const int do_create = (flags & O_ACCMODE) != O_RDONLY;
if ((p = extfs_get_path (file, &archive, 0, 0)) == NULL)
if ((q = extfs_get_path (file, &archive, 0, 0)) == NULL)
return NULL;
q = (*p == '/') ? p + 1 : p;
entry = extfs_find_entry (archive->root_entry, q, 0, do_create);
free (p);
if (entry == NULL) {
if (entry == NULL)
return NULL;
}
if ((entry = extfs_resolve_symlinks (entry)) == NULL) {
if ((entry = extfs_resolve_symlinks (entry)) == NULL)
return NULL;
}
if (S_ISDIR (entry->inode->mode)) {
extfserrno = EISDIR;
return NULL;
}
if (entry->inode->local_filename == NULL) {
char *cmd, *archive_name;
char *cmd, *archive_name, *p;
entry->inode->local_filename = strdup (tmpnam (NULL));
p = extfs_get_path_from_entry (entry);
@ -861,144 +697,21 @@ static int extfs_close (void *data)
return 0;
}
static int extfs_errno (void)
{
return extfserrno;
}
#define RECORDSIZE 512
#define X_pseudofile extfs_pseudofile
#define Xerrno extfserrno
static void *extfs_opendir (char *dirname)
{
struct extfs_archive *archive;
char *p, *q;
struct extfs_entry *entry;
struct extfs_entry **extfs_info;
if ((p = extfs_get_path (dirname, &archive, 1, 0)) == NULL)
return NULL;
q = (*p == '/') ? p + 1 : p;
entry = extfs_find_entry (archive->root_entry, q, 0, 0);
free (p);
if (entry == NULL)
return NULL;
if ((entry = extfs_resolve_symlinks (entry)) == NULL)
return NULL;
if (!S_ISDIR (entry->inode->mode)) {
extfserrno = ENOTDIR;
return NULL;
}
extfs_info = (struct extfs_entry **) xmalloc (sizeof (struct extfs_entry *), "Extfs: extfs_opendir");
*extfs_info = entry->inode->first_in_subdir;
return extfs_info;
}
static void *extfs_readdir (void *data)
{
static struct {
struct dirent dir;
#ifdef NEED_EXTRA_DIRENT_BUFFER
char extra_buffer [MC_MAXPATHLEN];
#endif
} dir;
struct extfs_entry **extfs_info = (struct extfs_entry **) data;
if (*extfs_info == NULL)
return NULL;
strcpy (&(dir.dir.d_name [0]), (*extfs_info)->name);
#ifndef DIRENT_LENGTH_COMPUTED
dir.d_namlen = strlen (dir.dir.d_name);
#endif
*extfs_info = (*extfs_info)->next_in_dir;
return (void *)&dir;
}
static int extfs_closedir (void *data)
{
free (data);
return 0;
}
static int _extfs_stat (char *path, struct stat *buf, int resolve)
{
struct extfs_archive *archive;
char *p, *q;
struct extfs_entry *entry;
struct extfs_inode *inode;
if ((p = extfs_get_path (path, &archive, 0, 0)) == NULL)
return -1;
q = (*p == '/') ? p + 1 : p;
entry = extfs_find_entry (archive->root_entry, q, 0, 0);
free (p);
if (entry == NULL)
return -1;
if (resolve && (entry = extfs_resolve_symlinks (entry)) == NULL)
return -1;
inode = entry->inode;
buf->st_dev = inode->dev;
buf->st_ino = inode->inode;
buf->st_mode = inode->mode;
buf->st_nlink = inode->nlink;
buf->st_uid = inode->uid;
buf->st_gid = inode->gid;
#ifdef HAVE_ST_RDEV
buf->st_rdev = inode->rdev;
#endif
buf->st_size = inode->size;
#ifdef HAVE_ST_BLKSIZE
buf->st_blksize = 512;
#endif
#ifdef HAVE_ST_BLOCKS
buf->st_blocks = (inode->size + 512 - 1) / 512;
#endif
buf->st_atime = inode->atime;
buf->st_mtime = inode->mtime;
buf->st_ctime = inode->ctime;
return 0;
}
static int extfs_stat (char *path, struct stat *buf)
{
return _extfs_stat (path, buf, 1);
}
static int extfs_lstat (char *path, struct stat *buf)
{
return _extfs_stat (path, buf, 0);
}
static int extfs_fstat (void *data, struct stat *buf)
{
struct extfs_pseudofile *file = (struct extfs_pseudofile *)data;
struct extfs_inode *inode;
inode = file->entry->inode;
buf->st_dev = inode->dev;
buf->st_ino = inode->inode;
buf->st_mode = inode->mode;
buf->st_nlink = inode->nlink;
buf->st_uid = inode->uid;
buf->st_gid = inode->gid;
#ifdef HAVE_ST_RDEV
buf->st_rdev = inode->rdev;
#endif
buf->st_size = inode->size;
#ifdef HAVE_ST_BLKSIZE
buf->st_blksize = 512;
#endif
#ifdef HAVE_ST_BLOCKS
buf->st_blocks = (inode->size + 512 - 1) / 512;
#endif
buf->st_atime = inode->atime;
buf->st_mtime = inode->mtime;
buf->st_ctime = inode->ctime;
return 0;
}
#define X_entry extfs_entry
#define X_archive extfs_archive
#define X_get_path extfs_get_path
#define X_find_entry extfs_find_entry
#define X_resolve_symlinks extfs_resolve_symlinks
#define X_inode extfs_inode
#define __X_find_entry __extfs_find_entry
#define __X_resolve_symlinks __extfs_resolve_symlinks
#define X_loop_protect extfs_loop_protect
#include "shared.c"
static int extfs_chmod (char *path, int mode)
{
@ -1010,31 +723,6 @@ static int extfs_chown (char *path, int owner, int group)
return -1;
}
static int extfs_readlink (char *path, char *buf, int size)
{
struct extfs_archive *archive;
char *p, *q;
int i;
struct extfs_entry *entry;
if ((p = extfs_get_path (path, &archive, 0, 0)) == NULL)
return -1;
q = (*p == '/') ? p + 1 : p;
entry = extfs_find_entry (archive->root_entry, q, 0, 0);
free (p);
if (entry == NULL)
return -1;
if (!S_ISLNK (entry->inode->mode)) {
extfserrno = EINVAL;
return -1;
}
if (size > (i = strlen (entry->inode->linkname))) {
size = i;
}
strncpy (buf, entry->inode->linkname, i);
return i;
}
static int extfs_unlink (char *path)
{
return -1;
@ -1061,31 +749,22 @@ static int extfs_rename (char *a, char *b)
static int extfs_chdir (char *path)
{
struct extfs_archive *archive;
char *p, *q, *res;
char *q, *res;
struct extfs_entry *entry;
extfserrno = ENOTDIR;
if ((p = extfs_get_path (path, &archive, 1, 0)) == NULL)
if ((q = extfs_get_path (path, &archive, 1, 0)) == NULL)
return -1;
q = (*p == '/') ? p + 1 : p;
entry = extfs_find_entry (archive->root_entry, q, 0, 0);
if (entry == NULL) {
free (p);
if (!entry)
return -1;
}
entry = extfs_resolve_symlinks (entry);
if (entry == NULL) {
free (p);
if ((!entry) || (!S_ISDIR (entry->inode->mode)))
return -1;
}
if (!S_ISDIR (entry->inode->mode)) {
free (p);
return -1;
}
entry->inode->archive->current_dir = entry;
res = copy_strings (extfs_prefixes [entry->inode->archive->fstype], ":",
entry->inode->archive->name, p, NULL);
free (p);
res = copy_strings (
entry->inode->archive->name, "#", extfs_prefixes [entry->inode->archive->fstype],
"/", q, NULL);
extfserrno = 0;
if (extfs_current_dir)
free (extfs_current_dir);
@ -1125,14 +804,11 @@ static vfsid extfs_getid (char *path, struct vfs_stamping **parent)
struct extfs_archive *archive;
vfs *v;
vfsid id;
char *p;
struct vfs_stamping *par;
*parent = NULL;
if ((p = extfs_get_path (path, &archive, 1, 1)) == NULL) {
if (!extfs_get_path (path, &archive, 1, 1))
return (vfsid) -1;
}
free (p);
if (archive->name){
v = vfs_type (archive->name);
id = (*v->getid) (archive->name, &par);
@ -1253,19 +929,21 @@ vfs extfs_vfs_ops =
extfs_read,
extfs_write,
extfs_opendir,
extfs_readdir,
extfs_closedir,
s_opendir,
s_readdir,
s_closedir,
s_telldir,
s_seekdir,
extfs_stat,
extfs_lstat,
extfs_fstat,
s_stat,
s_lstat,
s_fstat,
extfs_chmod, /* unimplemented */
extfs_chown, /* unimplemented */
NULL,
extfs_readlink,
s_readlink,
extfs_symlink, /* unimplemented */
extfs_link, /* unimplemented */
@ -1273,7 +951,7 @@ vfs extfs_vfs_ops =
extfs_rename, /* unimplemented */
extfs_chdir,
extfs_errno,
s_errno,
extfs_lseek,
extfs_mknod, /* unimplemented */
@ -1289,6 +967,7 @@ vfs extfs_vfs_ops =
NULL,
NULL,
NULL
#ifdef HAVE_MMAP
, extfs_mmap,
extfs_munmap
@ -1298,54 +977,56 @@ vfs extfs_vfs_ops =
#include "../src/profile.h"
void extfs_init (void)
{
void *keys = profile_init_iterator ("extfs", LIBDIR "extfs/extfs.ini");
char *key, *value;
char *p, *q, c;
FILE *cfg = fopen( LIBDIR "extfs/extfs.ini", "r" );
if (!cfg) {
fprintf( stderr, "Warning: " LIBDIR "extfs/extfs.ini not found\n" );
return;
}
extfs_no = 0;
for (extfs_no = 0; keys != NULL && extfs_no < MAXEXTFS; extfs_no++) {
keys = profile_iterator_next (keys, &key, &value);
while ( extfs_no < MAXEXTFS ) {
char key[256];
char *c;
if (!fgets( key, 250, cfg ))
break;
/* Handle those with a trailing ':', those flag that the
* file system does not require an archive to work
*/
c = key [strlen (key)-1];
if (c == ':'){
key [strlen (key)-1] = 0;
extfs_need_archive [extfs_no] = EFS_ARG_EMPTY;
} else if (c == '*'){
key [strlen (key)-1] = 0;
extfs_need_archive [extfs_no] = EFS_NEED_ARG;
} else
extfs_need_archive [extfs_no] = EFS_NEED_FILE;
extfs_prefixes [extfs_no] = strdup (key);
value = strdup (value);
for (q = value; (p = strtok (q, " \t")) != NULL; ){
struct extfs_ext *newn;
q = NULL;
newn = xmalloc (sizeof (struct extfs_ext), "prefixes");
newn->next = extfs_extensions [extfs_no];
newn->ext = strdup (p);
extfs_extensions [extfs_no] = newn;
if (*key == '[') {
/* We may not use vfs_die() message or message_1s or similar,
* UI is not initialized at this time and message would not
* appear on screen. */
fprintf( stderr, "Warning: You need to update your " LIBDIR "extfs/extfs.ini file.\n" );
fclose(cfg);
return;
}
free (value);
if (*key == '#')
continue;
if ((c = strchr( key, '\n')))
*c = 0;
c = &key [strlen (key)-1];
extfs_need_archive [extfs_no] = !(*c==':');
if (*c==':') *c = 0;
if (!(*key))
continue;
extfs_prefixes [extfs_no] = strdup (key);
extfs_no++;
}
free_profile_name (LIBDIR "extfs/extfs.ini");
fclose(cfg);
}
int extfs_prefix_to_type (char *path)
int extfs_which (char *path)
{
int i, j;
int i;
for (i = 0; i < extfs_no; i++) {
j = strlen (extfs_prefixes [i]);
if (!strncmp (path, extfs_prefixes [i], j) && path [j] == ':')
for (i = 0; i < extfs_no; i++)
if (!strcmp (path, extfs_prefixes [i]))
return i;
}
return -1;
}
@ -1356,19 +1037,10 @@ char *extfs_get_prefix (int idx)
void extfs_done (void)
{
struct extfs_ext *current, *old;
int i;
for (i = 0; i < extfs_no; i++ ){
for (i = 0; i < extfs_no; i++ )
free (extfs_prefixes [i]);
current = extfs_extensions [i];
while (current){
old = current;
current = current->next;
free (old->ext);
free (old);
}
}
extfs_no = 0;
if (extfs_current_dir)
free (extfs_current_dir);

Просмотреть файл

@ -1,8 +1,6 @@
Writing scripts for Midnight Commander's external vfs
IMPORTANT NOTE: extfs is not officialy released and fully bug free
in 3.0! You have been warned. If you would really like to try it,
you can (by typing make install.extfs in the vfs directory).
IMPORTANT NOTE: There may be some bugs left in extfs. Enjoy.
Starting with version 3.1, the Midnight Commander comes with so called
extfs, which is one of the virtual filesystems. This system makes it
@ -16,18 +14,23 @@ Creating a shell script/program to handle requests.
configured or compiled, like /usr/local/lib/mc or /usr/lib/mc).
The first one is very easy:
You assign a vfs prefix and vfs extensions to your vfs. Both will be used in
vfs pseudoURL names, like if you assign prefix zip and extensions .zip,
.ZIP, then URLs will look like
zip:anypath/my.zip/some_path/in_the/archive
Then you add a line to the end of the [extfs] section:
prefix=space_separated_extensions
e.g.
zip=.zip .ZIP
You assign a vfs suffix. For example, if you have .zip file, and would
like to see what's inside it, path will be
/anypath/my.zip#uzip/some_path/...
Then you add a line extfs.ini file containing just that extension. If
your vfs does not require file to work on, add ':' to the of name.
In this example, .zip is suffix, but I call vfs 'uzip'. Why? Well,
what this vfs essentially does is UNzip. UN is too long, so I choosed
U. Note that sometime in future filesystem like zip may exist: It will
take whole tree and create .zip file from it. So /usr:zip will be
zipfile containing whole /usr tree.
The second one may require some your knowledge of shell/c programming:
You have to create a program (with executable permissions) prefix in
$(libdir)/extfs (in our example $(libdir)/extfs/zip).
$(libdir)/extfs (in our example $(libdir)/extfs/uzip).
* Commands that should be implemented by your shell script
----------------------------------------------------------
@ -51,10 +54,7 @@ SSSSSSSS is the file size
FILENAME is the filename
PATH is the path from the archive's root without the leading slash (/)
DATETIME has one of the following formats:
Mon DD hh:mm
Mon DD YYYY
Mon DD YYYY hh:mm
MM-DD-YY hh:mm
Mon DD hh:mm, Mon DD YYYY, Mon DD YYYY hh:mm, MM-DD-YY hh:mm
where Mon is a three digit english month name, DD day
1-31, MM month 01-12, YY two digit year, YYYY four digit
@ -74,7 +74,8 @@ then it says that this file should be a hardlinked with the other file.
* Command: copyout archivename storedfilename extractto
This should extract from archive archivename the file called
storedfilename (possibly with path if not located in archive's root)
storedfilename (possibly with path if not located in archive's root
[this is wrong. current extfs strips paths! -- pavel@ucw.cz])
to file extractto.
* Command: copyin archivename storedfilename sourcefile
@ -88,55 +89,16 @@ archivename will be something like /tmp/f43513254 or just
anything. Some archivers do not like it, so you'll have to find some
workaround.
* Command: run
Undocumented :-)
---------------------------------------------------------
Don't forget to mark this file executable (chmod 755 ThisFile, for example)
This is a skeleton structure of the executable:
#!/bin/sh
# Command functions
mcvfs_list ()
# $1 is the archive name
{
# Apply a system command to obtain a list of filenames
# For example 'zip -l $1'
# Scan each line of the 'list' output, discarding unused information, and
# constructing a printable line in a form, described above, that mc can use.
# Exit
}
mcvfs_copyout ()
# $1 is the archive name
# $2 is a name of a file within the archive
# $3 is a name of a file within the system (to add from or extract to)
{
# Apply the system command used to extract one file from the archive
# Exit
}
mcvfs_copyin ()
# $1 is the archive name
# $2 is a name of a file within the archive
# $3 is a name of a file within the system (to add from or extract to)
{
# Apply the system command used to add one file to the archive
# Exit
}
# Command line parser
# $1 is the command
# $2 is the archive name
# $3 is a name of a file within the archive
# $4 is a name of a file within the system (to add from or extract to)
case "$1" in
list) mcvfs_list $2; exit $?;;
copyout) mcvfs_copyout $2 $3 $4; exit $?;;
copyin) mcvfs_copyin $2 $3 $4; exit $?;;
esac
# Show an error if this was called with some other command
exit 1
For skeleton structure of executable, look at some of filesystems
similar to yours.
---------------------------------------------------------

Просмотреть файл

@ -1,17 +1,22 @@
[extfs]
zip=.zip .ZIP
zoo=.zoo
arc=.arc .ARC .pak .PAK
lha=.lha .LHA .lzh .LZH
cpio=.cpio .cpio.Z .cpio.gz
rpm=.rpm
rar=.rar
deb=.deb
a:=a
b:=a
lslR=lslR ls-lR lslR.gz ls-lR.gz lslR.Z ls-lR.Z
ftplist=ftplist
patch=
arfs=.a
hp48:=hp48
# Popular pc archivers, for arj usage you need special patch to unarj
uzip
uzoo
ulha
urar
uarj
# Unknown to me, it was named arfs before
uar
# cpio archiver (unix)
ucpio
# Packages from popular distributions
rpm
deb
# a: - mtools filesystem. I probably broke this one
a:
# For browsing lslR listings (found on many ftp sites)
lslR
# Simple fs for list of popular ftp sites
ftplist
# Hewlet packard calculator
hp48:

Просмотреть файл

@ -5,6 +5,7 @@
1995 Jakub Jelinek
1995, 1996, 1997 Miguel de Icaza
1997 Norbert Warmuth
1998 Pavel Machek
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -28,7 +29,6 @@
etc., (tarfs as well), we should give there a user selectable timeout
and assign a key sequence.
- use hash table instead of linklist to cache ftpfs directory.
- complete rename operation.
*/
#include <config.h>
@ -89,8 +89,6 @@
#define UPLOAD_ZERO_LENGTH_FILE
void print_vfs_message(char *, ...);
static int ftpfserrno;
static int code;
@ -106,7 +104,7 @@ int use_netrc = 1;
extern char *home_dir;
/* Anonymous setup */
char *ftpfs_anonymous_passwd;
char *ftpfs_anonymous_passwd = 0;
int ftpfs_directory_timeout;
/* Proxy host */
@ -132,8 +130,6 @@ static int force_expiration = 0;
struct linklist *ftpfs_connections_list;
extern char *last_current_dir;
/* command wait_flag: */
#define NONE 0x00
#define WAIT_REPLY 0x01
@ -441,7 +437,7 @@ login_server (struct ftpfs_connection *bucket, char *netrcpass)
if (!bucket->password){
p = copy_strings (" FTP: Password required for ", quser(bucket),
" ", NULL);
op = input_dialog (p, _("Password:"), "");
op = vfs_get_password (p);
free (p);
if (op == NULL) {
ftpfserrno = EPERM;
@ -475,7 +471,7 @@ login_server (struct ftpfs_connection *bucket, char *netrcpass)
wipe_password (proxypass);
p = copy_strings(" Proxy: Password required for ", proxyname, " ",
NULL);
proxypass = input_dialog (p, _("Password:"), "");
proxypass = vfs_get_password (p);
free(p);
if (proxypass == NULL) {
ftpfserrno = EPERM;
@ -603,7 +599,7 @@ setup_source_route (int socket, int dest)
ptr++;
if (setsockopt (socket, IPPROTO_IP, IP_OPTIONS,
buffer, ptr - buffer) < 0)
message_2s (1, " Error ", " Could not set source routing (%s)", unix_error_string (errno));
message_2s (1, MSG_ERROR, _(" Could not set source routing (%s)"), unix_error_string (errno));
}
#else
#define setup_source_route(x,y)
@ -619,7 +615,7 @@ load_no_proxy_list ()
{
/* FixMe: shouldn't be hardcoded!!! */
char s[258]; /* provide for 256 characters and nl */
struct no_proxy_entry *np, *current;
struct no_proxy_entry *np, *current = 0;
FILE *npf;
int c;
char *p;
@ -890,13 +886,7 @@ open_command_connection (char *host, char *user, int port, char *netrcpass)
qhome(bucket) = ftpfs_get_current_directory (bucket);
if (!qhome(bucket))
qhome(bucket) = strdup ("/");
if (last_current_dir) {
if (last_current_dir [strlen (last_current_dir) - 1] == '/')
qupdir(bucket) = strdup (last_current_dir);
else
qupdir(bucket) = copy_strings (last_current_dir, "/", NULL);
} else
qupdir(bucket) = strdup ("/");
qupdir(bucket) = strdup ("/"); /* FIXME: I changed behavior to ignore last_current_dir */
return bucket;
}
@ -1018,7 +1008,7 @@ void ftpfs_fill_names (void (*func)(char *))
do {
if ((bucket = lptr->data) != 0){
path_name = copy_strings ("ftp://", quser (bucket),
path_name = copy_strings ("/#ftp.", quser (bucket),
"@", qhost (bucket),
qcdir(bucket), 0);
(*func)(path_name);
@ -1177,36 +1167,47 @@ ftpfs_get_path (struct ftpfs_connection **bucket, char *path)
char *user, *host, *remote_path, *pass;
int port;
/* An absolute path name, try to determine connection socket */
if (strncmp (path, "ftp://", 6) == 0){
path += 6;
#ifndef BROKEN_PATHS
if (strncmp (path, "/#ftp:", 6))
return NULL; /* Normal: consider cd /bla/#ftp */
#else
if (!(path = strstr (path, "/#ftp:")))
return NULL;
#endif
path += 6;
if (!(remote_path = ftpfs_get_host_and_username (path, &host, &user,
&port, &pass))) {
ftpfserrno = ENOENT;
free (host);
free (user);
if (pass)
wipe_password (pass);
return NULL;
if (!(remote_path = ftpfs_get_host_and_username (path, &host, &user, &port, &pass)))
ftpfserrno = ENOENT;
else {
if ((*bucket = ftpfs_open_link (host, user, port, pass)) == NULL) {
free (remote_path);
remote_path = NULL;
}
if ((*bucket = ftpfs_open_link (host, user, port, pass)) == NULL) {
free (remote_path);
free (host);
free (user);
if (pass)
wipe_password (pass);
return NULL;
}
free (host);
free (user);
if (pass)
wipe_password (pass);
return remote_path;
}
/* never get here !!! */
message_1s(1, " Error ", " Oops, you just hit a bug in the code ");
return NULL;
free (host);
free (user);
if (pass)
wipe_password (pass);
if (!remote_path)
return NULL;
/* NOTE: Usage of tildes is deprecated, consider:
* cd /#ftp:pavel@hobit
* cd ~
* And now: what do I want to do? Do I want to go to /home/pavel or to
* /#ftp:hobit/home/pavel? I think first has better sense...
*/
{
int f = !strcmp( remote_path, "/~" );
if (f || !strncmp( remote_path, "/~/", 3 )) {
char *s;
s = concat_dir_and_file( qhome (*bucket), remote_path +3-f );
free (remote_path);
remote_path = s;
}
}
return remote_path;
}
static void
@ -1635,7 +1636,7 @@ int retrieve_file_start(struct ftpentry *fe)
int retrieve_file_start2(struct ftpentry *fe)
{
remotelocal_handle = open(fe->local_filename, O_RDWR | O_CREAT | O_TRUNC, 0600);
remotelocal_handle = open(fe->local_filename, O_RDWR | O_CREAT | O_TRUNC | O_EXCL, 0600);
if (remotelocal_handle == -1) {
ftpfserrno = EIO;
free(fe->local_filename);
@ -1649,11 +1650,13 @@ int retrieve_file_start2(struct ftpentry *fe)
return 1;
}
void ftpfs_flushdir ()
void ftpfs_flushdir (void)
{
force_expiration = 1;
}
static int remove_temp_file (char *file_name);
int ftpfs_ctl (void *data, int ctlop, int arg)
{
int n = 0;
@ -1731,6 +1734,9 @@ int ftpfs_ctl (void *data, int ctlop, int arg)
int ftpfs_setctl (char *path, int ctlop, char *arg)
{
switch (ctlop) {
case MCCTL_REMOVELOCALCOPY:
return remove_temp_file (path);
case MCCTL_SETREMOTECOPY: if (localname) free (localname);
localname = strdup (vfs_canon (arg));
return 1;
@ -1748,7 +1754,7 @@ int retrieve_file(struct ftpentry *fe)
if (fe->local_filename)
return 1;
fe->local_stat.st_mtime = 0;
fe->local_filename = strdup(tmpnam(NULL));
fe->local_filename = tempnam (0, "ftpfs");
fe->local_is_temp = 1;
if (fe->local_filename == NULL) {
ftpfserrno = ENOMEM;
@ -1911,7 +1917,7 @@ _get_file_entry(struct ftpfs_connection *bucket, char *file_name,
ent->local_filename = 0;
}
if (flags & O_TRUNC) {
ent->local_filename = strdup(tmpnam(NULL));
ent->local_filename = tempnam (0, "ftpfs");
if (ent->local_filename == NULL) {
ftpfserrno = ENOMEM;
return NULL;
@ -1964,7 +1970,7 @@ _get_file_entry(struct ftpfs_connection *bucket, char *file_name,
ent->bucket = bucket;
ent->name = strdup(p);
ent->remote_filename = strdup(file_name);
ent->local_filename = strdup(tmpnam(NULL));
ent->local_filename = tempnam(0, "ftpfs");
if (!ent->name && !ent->remote_filename && !ent->local_filename) {
ftpentry_destructor(ent);
ftpfserrno = ENOMEM;
@ -2002,6 +2008,43 @@ _get_file_entry(struct ftpfs_connection *bucket, char *file_name,
}
}
/* this just free's the local temp file. I don't know if the
remote file can be used after this without crashing - paul
psheer@obsidian.co.za psheer@icon.co.za */
static int remove_temp_file (char *file_name)
{
char *p, q;
struct ftpfs_connection *bucket;
struct ftpentry *ent;
struct linklist *file_list, *lptr;
struct ftpfs_dir *dcache;
if (!(file_name = ftpfs_get_path (&bucket, file_name)))
return -1;
p = strrchr (file_name, '/');
q = *p;
*p = '\0';
dcache = retrieve_dir (bucket, *file_name ? file_name : "/");
if (dcache == NULL)
return -1;
file_list = dcache->file_list;
*p++ = q;
if (!*p)
p = ".";
for (lptr = file_list->next; lptr != file_list; lptr = lptr->next) {
ent = lptr->data;
if (strcmp (p, ent->name) == 0) {
if (ent->local_filename) {
unlink (ent->local_filename);
free (ent->local_filename);
ent->local_filename = 0;
return 0;
}
}
}
return -1;
}
static struct ftpentry *
get_file_entry(char *path, int op, int flags)
{
@ -2194,7 +2237,7 @@ static int ftpfs_errno (void)
/* Explanation:
* On some operating systems (Slowaris 2 for example)
* the d_name member is just a char long (Nice trick that break everything,
* the d_name member is just a char long (nice trick that break everything),
* so we need to set up some space for the filename.
*/
struct ftpfs_dirent {
@ -2206,27 +2249,7 @@ struct ftpfs_dirent {
struct ftpfs_dir *dcache;
};
char *ftpfs_gethome (char *servername)
{
struct ftpfs_connection *bucket;
char *remote_path;
if (!(remote_path = ftpfs_get_path (&bucket, servername)))
return NULL;
free (remote_path);
return qhome(bucket);
}
char *ftpfs_getupdir (char *servername)
{
struct ftpfs_connection *bucket;
char *remote_path;
if (!(remote_path = ftpfs_get_path (&bucket, servername)))
return NULL;
free (remote_path);
return qupdir(bucket);
}
/* Possible FIXME: what happens if one directory is opened twice ? */
static void *ftpfs_opendir (char *dirname)
{
@ -2271,6 +2294,32 @@ static void *ftpfs_readdir (void *data)
return (void *) &dirp->dent;
}
static int ftpfs_telldir (void *data)
{
struct ftpfs_dirent *dirp = data;
struct linklist *pos;
int i = 0;
pos = dirp->dcache->file_list->next;
while( pos!=dirp->dcache->file_list) {
if (pos == dirp->pos)
return i;
pos = pos->next;
i++;
}
return -1;
}
static void ftpfs_seekdir (void *data, int pos)
{
struct ftpfs_dirent *dirp = data;
int i;
dirp->pos = dirp->dcache->file_list->next;
for (i=0; i<pos; i++)
ftpfs_readdir(data);
}
static int ftpfs_closedir (void *info)
{
struct ftpfs_dirent *dirp = info;
@ -2580,6 +2629,8 @@ vfs ftpfs_vfs_ops = {
ftpfs_opendir,
ftpfs_readdir,
ftpfs_closedir,
ftpfs_telldir,
ftpfs_seekdir,
ftpfs_stat,
ftpfs_lstat,
@ -2724,8 +2775,8 @@ int lookup_netrc (char *host, char **login, char **pass)
stat (netrcname, &mystat) >= 0 &&
(mystat.st_mode & 077)) {
if (be_angry) {
message_1s (1, "Error", "~/.netrc file has not correct mode.\n"
"Remove password or correct mode.");
message_1s (1, MSG_ERROR, _("~/.netrc file has not correct mode.\n"
"Remove password or correct mode."));
be_angry = 0;
}
free (netrc);
@ -2739,8 +2790,8 @@ int lookup_netrc (char *host, char **login, char **pass)
if (stat (netrcname, &mystat) >= 0 &&
(mystat.st_mode & 077)) {
if (be_angry) {
message_1s (1, "Error", "~/.netrc file has not correct mode.\n"
"Remove password or correct mode.");
message_1s (1, MSG_ERROR, _("~/.netrc file has not correct mode.\n"
"Remove password or correct mode."));
be_angry = 0;
}
free (netrc);

Просмотреть файл

@ -80,6 +80,16 @@ static void *local_opendir (char *dirname)
return local_info;
}
static int local_telldir (void *data)
{
return telldir( *(DIR **) data );
}
static void local_seekdir (void *data, int offset)
{
seekdir( *(DIR **) data, offset );
}
static void *local_readdir (void *data)
{
return readdir (*(DIR **) data);
@ -249,6 +259,8 @@ vfs local_vfs_ops = {
local_opendir,
local_readdir,
local_closedir,
local_telldir,
local_seekdir,
local_stat,
local_lstat,

Просмотреть файл

@ -73,6 +73,8 @@ static mcfs_connection *current_dir_connection;
char *mcfs_current_dir = 0;
static char *mcfs_gethome (mcfs_connection *mc);
/* Extract the hostname and username from the path */
/* path is in the form: hostname:user/remote-dir */
char *mcfs_get_host_and_username (char *path, char **host, char **user,
@ -89,7 +91,7 @@ void mcfs_fill_names (void (*func)(char *))
for (i = 0; i < MCFS_MAX_CONNECTIONS; i++){
if (mcfs_connections [i].host == 0)
continue;
name = copy_strings ("mc:", mcfs_connections [i].user,
name = copy_strings ("/#mc:", mcfs_connections [i].user,
"@", mcfs_connections [i].host, 0);
(*func) (name);
free (name);
@ -137,8 +139,6 @@ int mcfs_invalidate_socket (int sock)
return 0;
}
extern char *last_current_dir;
/* This routine checks the server RPC version and logs the user in */
static int mcfs_login_server (int my_socket, char *user, int port,
int port_autodetected, char *netrcpass,
@ -153,26 +153,32 @@ static int mcfs_login_server (int my_socket, char *user, int port,
return 0;
if (result != MC_VERSION_OK){
message_1s (1, " MCFS ", " The server does not support this version ");
message_1s (1, _(" MCFS "), _(" The server does not support this version "));
close (my_socket);
return 0;
}
rpc_send (my_socket, RPC_INT, MC_LOGIN, RPC_STRING, last_current_dir,
/* FIXME: figure out why last_current_dir used to be passed here */
rpc_send (my_socket, RPC_INT, MC_LOGIN, RPC_STRING, "/",
RPC_STRING, user, RPC_END);
if (0 == rpc_get (my_socket, RPC_INT, &result, RPC_END))
if (0 == rpc_get (my_socket, RPC_INT, &result, RPC_END))
return 0;
if (result == MC_NEED_PASSWORD){
if (port > 1024 && port_autodetected){
int v;
v = query_dialog (" Warning ",
" The remote server is not running on a system port \n"
" you need a password to log in, but the information may \n"
" not be safe on the remote side. Continue? \n", 3, 2,
" Yes ", " No ");
#ifndef VFS_STANDALONE
v = query_dialog (_(" Warning "),
_(" The remote server is not running on a system port \n"
" you need a password to log in, but the information may \n"
" not be safe on the remote side. Continue? \n"), 3, 2,
_(" Yes "), _(" No "));
#else
message_1s( 1, " MCFS ", _(" The remote server is running on stange port. Giving up.\n"));
v = 1;
#endif
if (v == 1){
close (my_socket);
return 0;
@ -181,7 +187,7 @@ static int mcfs_login_server (int my_socket, char *user, int port,
if (netrcpass != NULL)
pass = strdup (netrcpass);
else
pass = input_dialog (" MCFS Password required ", _("Password:"), "");
pass = vfs_get_password (_(" MCFS Password required "));
if (!pass){
rpc_send (my_socket, RPC_INT, MC_QUIT, RPC_END);
close (my_socket);
@ -195,7 +201,7 @@ static int mcfs_login_server (int my_socket, char *user, int port,
return 0;
if (result != MC_LOGINOK){
message_1s (1, " MCFS ", " Invalid password ");
message_1s (1, " MCFS ", _(" Invalid password "));
rpc_send (my_socket, RPC_INT, MC_QUIT, RPC_END);
close (my_socket);
return 0;
@ -237,8 +243,8 @@ static mcfs_connection *mcfs_get_free_bucket ()
return &mcfs_connections [i];
}
/* This can't happend, since we have checked for max connections before */
fprintf (stderr, "Internal error: mcfs_get_free_bucket");
return 0;
vfs_die("Internal error: mcfs_get_free_bucket");
return 0; /* shut up, stupid gcc */
}
/* This routine keeps track of open connections */
@ -261,7 +267,7 @@ static mcfs_connection *mcfs_open_link (char *host, char *user, int *port, char
return &mcfs_connections [i];
}
if (mcfs_open_connections == MCFS_MAX_CONNECTIONS){
message_1s (1, " Error ", " Too many open connections ");
message_1s (1, MSG_ERROR, _(" Too many open connections "));
return 0;
}
@ -305,43 +311,40 @@ static char *mcfs_get_path (mcfs_connection **mc, char *path)
int port;
/* An absolute path name, try to determine connection socket */
if (strncmp (path, "mc:", 3) == 0){
path += 3;
/* 1.11.96 bor: add mc:// URL syntax */
if (path[0] == '/' && path[1] == '/')
path += 2;
/* Port = 0 means that open_tcp_link will try to contact the
* remote portmapper to get the port number
*/
port = 0;
if (!(remote_path = mcfs_get_host_and_username
(path, &host, &user, &port, &pass))){
free (host);
free (user);
if (pass)
wipe_password (pass);
return 0;
}
if (strncmp (path, "/#mc:", 5)) {
vfs_die( "Mcfs: this should not happen.\n" );
/* We used to *mc = current_dir_connection; return strdup (path); */
}
path += 5;
/* Port = 0 means that open_tcp_link will try to contact the
* remote portmapper to get the port number
*/
port = 0;
if ((remote_path = mcfs_get_host_and_username(path, &host, &user, &port, &pass)))
if (!(*mc = mcfs_open_link (host, user, &port, pass))){
free (remote_path);
free (host);
free (user);
if (pass)
wipe_password (pass);
return 0;
remote_path = NULL;
}
free (host);
free (user);
if (pass)
wipe_password (pass);
if (!remote_path)
return NULL;
/* NOTE: tildes are deprecated. See ftpfs.c */
{
int f = !strcmp( remote_path, "/~" );
if (f || !strncmp( remote_path, "/~/", 3 )) {
char *s;
s = concat_dir_and_file( mcfs_gethome (*mc), remote_path +3-f );
free (remote_path);
remote_path = s;
}
free (host);
free (user);
if (pass)
wipe_password (pass);
return remote_path;
}
*mc = current_dir_connection;
return strdup (path);
return remote_path;
}
/* Simple function for routines returning only an integer from the server */
@ -436,15 +439,10 @@ static int mcfs_rpc_path_int_int (int command, char *path, int n1, int n2)
return mcfs_handle_simple_error (mc->sock, 0);
}
char *mcfs_gethome (char *servername)
static char *mcfs_gethome (mcfs_connection *mc)
{
char *remote_file;
char *buffer;
mcfs_connection *mc;
if (!(remote_file = mcfs_get_path (&mc, servername)))
return 0;
free (remote_file);
if (mc->home)
return strdup (mc->home);
else {
@ -456,22 +454,6 @@ char *mcfs_gethome (char *servername)
}
}
char *mcfs_getupdir (char *servername)
{
char *remote_file;
mcfs_connection *mc;
char *buffer;
if (!(remote_file = mcfs_get_path (&mc, servername)))
return 0;
free (remote_file);
rpc_send (mc->sock, RPC_INT, MC_GETUPDIR, RPC_END);
if (0 == rpc_get (mc->sock, RPC_STRING, &buffer, RPC_END)) {
return strdup ("/");
}
return buffer;
}
/* The callbacks */
static void *mcfs_open (char *file, int flags, int mode)
{
@ -1114,6 +1096,8 @@ vfs mcfs_vfs_ops = {
mcfs_opendir,
mcfs_readdir,
mcfs_closedir,
NULL,
NULL,
mcfs_stat,
mcfs_lstat,

Просмотреть файл

@ -1305,3 +1305,9 @@ char *strdup (char *s)
return t;
}
#endif
void vfs_die( char *m )
{
fprintf (stderr,m);
exit (1);
}

Просмотреть файл

@ -36,6 +36,13 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <pwd.h>
#include <grp.h>
#ifndef TUNMLEN
#define TUNMLEN 256
#endif
#ifndef TGNMLEN
#define TGNMLEN 256
#endif
static int saveuid = -993;
static char saveuname[TUNMLEN];
static int my_uid = -993;

414
vfs/tar.c
Просмотреть файл

@ -2,6 +2,7 @@
Copyright (C) 1995 The Free Software Foundation
Written by: 1995 Jakub Jelinek
Rewritten by: 1998 Pavel Machek
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -37,6 +38,7 @@
#include <time.h>
#include "../src/fs.h"
#include "../src/util.h"
#include "../src/dialog.h" /* For MSG_ERROR */
#include "../src/mem.h"
#include "../src/mad.h"
#include "vfs.h"
@ -80,7 +82,7 @@ static struct tarfs_archive *first_archive = NULL;
static int tarerrno = 0;
static struct stat hstat; /* Stat struct corresponding */
static char *current_file_name, *current_link_name;
static struct tarfs_entry *tarfs_find_entry (struct tarfs_entry *dir, char *name, int make_dirs);
static struct tarfs_entry *tarfs_find_entry (struct tarfs_entry *dir, char *name, int make_dirs, int make_file);
void tarfs_fill_names (void (*func)(char *))
{
@ -88,7 +90,7 @@ void tarfs_fill_names (void (*func)(char *))
char *name;
while (a){
name = copy_strings ("tar:", a->name, "/",
name = copy_strings ( a->name, "#tar/",
a->current_dir->name, 0);
(*func)(name);
free (name);
@ -573,7 +575,7 @@ static int read_header (struct tarfs_archive *archive, int tard)
size -= written) {
data = get_next_record (archive, tard)->charptr;
if (data == NULL) {
message_1s (1, " Error ", "Unexpected EOF on archive file");
message_1s (1, MSG_ERROR, _("Unexpected EOF on archive file"));
return 0;
}
written = RECORDSIZE;
@ -625,9 +627,9 @@ static int read_header (struct tarfs_archive *archive, int tard)
q = current_file_name;
}
pent = tarfs_find_entry (archive->root_entry, q, 1);
pent = tarfs_find_entry (archive->root_entry, q, 1, 0);
if (pent == NULL) {
message_1s (1, " Error ", "Inconsistent tar archive");
message_1s (1, MSG_ERROR, _("Inconsistent tar archive"));
}
entry = (struct tarfs_entry *) xmalloc (sizeof (struct tarfs_entry), "Tar: tarfs_entry");
@ -646,9 +648,9 @@ static int read_header (struct tarfs_archive *archive, int tard)
free (current_file_name);
if (header->header.linkflag == LF_LINK) {
pent = tarfs_find_entry (archive->root_entry, current_link_name, 0);
pent = tarfs_find_entry (archive->root_entry, current_link_name, 0, 0);
if (pent == NULL) {
message_1s (1, " Error ", "Inconsistent tar archive");
message_1s (1, MSG_ERROR, _("Inconsistent tar archive"));
} else {
entry->inode = pent->inode;
pent->inode->nlink++;
@ -748,7 +750,7 @@ int read_tar_archive (char *name, struct tarfs_archive **pparc)
struct tarfs_archive *archive;
if ((tard = open_tar_archive (name, &archive)) == -1) { /* Open for reading */
message_2s (1, " Error ", "Couldn't open tar archive\n%s", name);
message_2s (1, MSG_ERROR, _("Couldn't open tar archive\n%s"), name);
return -1;
}
@ -767,7 +769,7 @@ int read_tar_archive (char *name, struct tarfs_archive **pparc)
case 0: /* Invalid header */
switch (prev_status) {
case 3: /* Error on first record */
message_2s (1, " Error ", "Hmm,...\n%s\ndoesn't look like a tar archive.", name);
message_2s (1, MSG_ERROR, _("Hmm,...\n%s\ndoesn't look like a tar archive."), name);
/* FALL THRU */
case 2: /* Error after record of zeroes */
case 1: /* Error after header rec */
@ -791,43 +793,6 @@ int read_tar_archive (char *name, struct tarfs_archive **pparc)
return 0;
}
char *tarfs_analysis (char *name, char **archive, int is_dir)
{
static struct {
int len; /* strlen (ext) */
char *ext;
} tarext[] = {{4, ".tar"},
{4, ".tgz"},
{7, ".tar.gz"},
{4, ".taz"},
{4, ".tpz"},
{6, ".tar.z"},
{7, ".tar.bz"},
{8, ".tar.bz2"},
{6, ".tar.Z"} };
char *p, *local;
unsigned int i;
char *archive_name = NULL;
/* | this is len of "tar:" plus some minimum
* v space needed for the extension */
for (p = name + strlen (name); p >= name + 8; p--)
if (*p == '/' || (is_dir && !*p))
for (i = 0; i < sizeof (tarext) / sizeof (tarext [0]); i++)
if (!strncmp (p - tarext [i].len, tarext [i].ext, tarext [i].len)) {
char c = *p;
*p = 0;
archive_name = vfs_canon (name + 4);
*archive = archive_name;
*p = c;
local = strdup (p);
return local;
}
tarerrno = ENOENT;
return NULL;
}
/* Returns allocated path inside the archive or NULL */
static char *tarfs_get_path (char *inname, struct tarfs_archive **archive, int is_dir,
int do_not_open)
@ -839,11 +804,10 @@ static char *tarfs_get_path (char *inname, struct tarfs_archive **archive, int i
vfs *v;
struct stat stat_buf;
local = tarfs_analysis (inname, &archive_name, is_dir);
if (local == NULL) {
tarerrno = ENOENT;
return NULL;
}
archive_name = inname;
vfs_split( inname, &local, NULL );
if (!local)
local = "";
mc_stat (archive_name, &stat_buf);
@ -865,8 +829,6 @@ static char *tarfs_get_path (char *inname, struct tarfs_archive **archive, int i
result = read_tar_archive (archive_name, &parc);
if (result == -1) {
tarerrno = EIO;
free(local);
free(archive_name);
return NULL;
}
v = vfs_type (archive_name);
@ -882,7 +844,6 @@ static char *tarfs_get_path (char *inname, struct tarfs_archive **archive, int i
vfs_rm_parents (parent);
return_success:
*archive = parc;
free (archive_name);
return local;
}
@ -895,7 +856,7 @@ static int notadir;
static struct tarfs_entry *
__tarfs_find_entry (struct tarfs_entry *dir, char *name,
struct tarfs_loop_protect *list, int make_dirs);
struct tarfs_loop_protect *list, int make_dirs, int make_file);
static struct tarfs_entry *
__tarfs_resolve_symlinks (struct tarfs_entry *entry,
@ -916,7 +877,7 @@ __tarfs_resolve_symlinks (struct tarfs_entry *entry,
"Tar: symlink looping protection");
looping->entry = entry;
looping->next = list;
pent = __tarfs_find_entry (entry->dir, entry->inode->linkname, looping, 0);
pent = __tarfs_find_entry (entry->dir, entry->inode->linkname, looping, 0, 0);
free (looping);
if (pent == NULL)
tarerrno = ENOENT;
@ -939,93 +900,6 @@ static struct tarfs_entry *tarfs_resolve_symlinks (struct tarfs_entry *entry)
return res;
}
static struct tarfs_entry*
__tarfs_find_entry (struct tarfs_entry *dir, char *name,
struct tarfs_loop_protect *list, int make_dirs)
{
struct tarfs_entry *pent, *pdir;
char *p, *q, *name_end;
char c;
if (*name == '/') { /* Handle absolute paths */
name++;
dir = dir->inode->archive->root_entry;
}
pent = dir;
p = name;
name_end = name + strlen (name);
q = strchr (p, '/');
c = '/';
if (!q)
q = strchr (p, 0);
for (; pent != NULL && c && *p; ){
c = *q;
*q = 0;
if (strcmp (p, ".")){
if (!strcmp (p, ".."))
pent = pent->dir;
else {
if ((pent = __tarfs_resolve_symlinks (pent, list))==NULL){
*q = c;
return NULL;
}
if (c == '/' && !S_ISDIR (pent->inode->mode)){
*q = c;
notadir = 1;
return NULL;
}
pdir = pent;
for (pent = pent->inode->first_in_subdir; pent; pent = pent->next_in_dir)
/* Hack: I keep the original semanthic unless
q+1 would break in the strchr */
if (!strcmp (pent->name, p)){
if (q + 1 > name_end){
*q = c;
notadir = !S_ISDIR (pent->inode->mode);
return pent;
}
break;
}
/* When we load archive, we create automagically
* non-existant directories
*/
if (pent == NULL && make_dirs) {
pent = generate_entry (dir->inode->archive, p, pdir, S_IFDIR | 0777);
}
}
}
/* Next iteration */
*q = c;
p = q + 1;
q = strchr (p, '/');
if (!q)
q = strchr (p, 0);
}
if (pent == NULL)
tarerrno = ENOENT;
return pent;
}
static struct tarfs_entry *tarfs_find_entry (struct tarfs_entry *dir, char *name, int make_dirs)
{
struct tarfs_entry *res;
errloop = 0;
notadir = 0;
res = __tarfs_find_entry (dir, name, NULL, make_dirs);
if (res == NULL) {
if (errloop)
tarerrno = ELOOP;
else if (notadir)
tarerrno = ENOTDIR;
}
return res;
}
struct tar_pseudofile {
struct tarfs_archive *archive;
long pos;
@ -1034,18 +908,18 @@ struct tar_pseudofile {
struct tarfs_entry *entry;
};
static struct tarfs_entry *tarfs_find_entry (struct tarfs_entry *dir, char *name, int make_dirs, int make_file);
static void *tar_open (char *file, int flags, int mode)
{
struct tar_pseudofile *tar_info;
struct tarfs_archive *archive;
char *p, *q;
char *q;
struct tarfs_entry *entry;
if ((p = tarfs_get_path (file, &archive, 0, 0)) == NULL)
if ((q = tarfs_get_path (file, &archive, 0, 0)) == NULL)
return NULL;
q = (*p == '/') ? p + 1 : p;
entry = tarfs_find_entry (archive->root_entry, q, 0);
free (p);
entry = tarfs_find_entry (archive->root_entry, q, 0, 0);
if (entry == NULL)
return NULL;
if ((entry = tarfs_resolve_symlinks (entry)) == NULL)
@ -1150,178 +1024,31 @@ static int tar_close (void *data)
return 0;
}
static int tar_errno (void)
{
return tarerrno;
}
#define X_pseudofile tar_pseudofile
#define Xerrno tarerrno
static void *tar_opendir (char *dirname)
{
struct tarfs_archive *archive;
char *p, *q;
struct tarfs_entry *entry;
struct tarfs_entry **tar_info;
#define X_entry tarfs_entry
#define X_archive tarfs_archive
#define X_get_path tarfs_get_path
#define X_find_entry tarfs_find_entry
#define X_resolve_symlinks tarfs_resolve_symlinks
#define X_inode tarfs_inode
#define __X_find_entry __tarfs_find_entry
#define __X_resolve_symlinks __tarfs_resolve_symlinks
#define X_loop_protect tarfs_loop_protect
if ((p = tarfs_get_path (dirname, &archive, 1, 0)) == NULL)
return NULL;
q = (*p == '/') ? p + 1 : p;
entry = tarfs_find_entry (archive->root_entry, q, 0);
free (p);
if (entry == NULL)
return NULL;
if ((entry = tarfs_resolve_symlinks (entry)) == NULL)
return NULL;
if (!S_ISDIR (entry->inode->mode)) {
tarerrno = ENOTDIR;
return NULL;
}
tar_info = (struct tarfs_entry **) xmalloc (sizeof (struct tarfs_entry *), "Tar: tar_opendir");
*tar_info = entry->inode->first_in_subdir;
return tar_info;
}
static void *tar_readdir (void *data)
{
static struct {
struct dirent dir;
#ifdef NEED_EXTRA_DIRENT_BUFFER
char extra_buffer [MC_MAXPATHLEN];
#endif
} dir;
struct tarfs_entry **tar_info = (struct tarfs_entry **) data;
if (*tar_info == NULL)
return NULL;
strcpy (&(dir.dir.d_name [0]), (*tar_info)->name);
#ifndef DIRENT_LENGTH_COMPUTED
dir.d_namlen = strlen (dir.dir.d_name);
#endif
*tar_info = (*tar_info)->next_in_dir;
return (void *)&dir;
}
static int tar_closedir (void *data)
{
free (data);
return 0;
}
static int _tar_stat (char *path, struct stat *buf, int resolve)
{
struct tarfs_archive *archive;
char *p, *q;
struct tarfs_entry *entry;
struct tarfs_inode *inode;
if ((p = tarfs_get_path (path, &archive, 0, 0)) == NULL)
return -1;
q = (*p == '/') ? p + 1 : p;
entry = tarfs_find_entry (archive->root_entry, q, 0);
free (p);
if (entry == NULL)
return -1;
if (resolve && (entry = tarfs_resolve_symlinks (entry)) == NULL)
return -1;
inode = entry->inode;
buf->st_dev = inode->dev;
buf->st_ino = inode->inode;
buf->st_mode = inode->mode;
buf->st_nlink = inode->nlink;
buf->st_uid = inode->uid;
buf->st_gid = inode->gid;
#ifdef HAVE_ST_RDEV
buf->st_rdev = inode->rdev;
#endif
buf->st_size = inode->size;
#ifdef HAVE_ST_BLKSIZE
buf->st_blksize = RECORDSIZE;
#endif
#ifdef HAVE_ST_BLOCKS
buf->st_blocks = (inode->size + RECORDSIZE - 1) / RECORDSIZE;
#endif
buf->st_atime = inode->atime;
buf->st_mtime = inode->mtime;
buf->st_ctime = inode->ctime;
return 0;
}
static int tar_stat (char *path, struct stat *buf)
{
return _tar_stat (path, buf, 1);
}
static int tar_lstat (char *path, struct stat *buf)
{
return _tar_stat (path, buf, 0);
}
static int tar_fstat (void *data, struct stat *buf)
{
struct tar_pseudofile *file = (struct tar_pseudofile *)data;
struct tarfs_inode *inode;
inode = file->entry->inode;
buf->st_dev = inode->dev;
buf->st_ino = inode->inode;
buf->st_mode = inode->mode;
buf->st_nlink = inode->nlink;
buf->st_uid = inode->uid;
buf->st_gid = inode->gid;
buf->st_rdev = inode->rdev;
buf->st_size = inode->size;
#ifdef HAVE_ST_BLKSIZE
buf->st_blksize = RECORDSIZE;
#endif
#ifdef HAVE_ST_BLOCKS
buf->st_blocks = (inode->size + RECORDSIZE - 1) / RECORDSIZE;
#endif
buf->st_atime = inode->atime;
buf->st_mtime = inode->mtime;
buf->st_ctime = inode->ctime;
return 0;
}
#include "shared.c"
static int tar_chmod (char *path, int mode)
{
{ /* Fixme: are you sure? IMO this is guaranteed to fail */
return chmod (path, mode);
}
static int tar_chown (char *path, int owner, int group)
{
{ /* Fixme: are you sure? IMO this is guaranteed to fail */
return chown (path, owner, group);
}
static int tar_readlink (char *path, char *buf, int size)
{
struct tarfs_archive *archive;
char *p, *q;
int i;
struct tarfs_entry *entry;
if ((p = tarfs_get_path (path, &archive, 0, 0)) == NULL)
return -1;
q = (*p == '/') ? p + 1 : p;
entry = tarfs_find_entry (archive->root_entry, q, 0);
free (p);
if (entry == NULL)
return -1;
if (!S_ISLNK (entry->inode->mode)) {
tarerrno = EINVAL;
return -1;
}
if (size > (i = strlen (entry->inode->linkname))) {
size = i;
}
strncpy (buf, entry->inode->linkname, i);
return i;
}
static int tar_unlink (char *path)
{
return -1;
@ -1345,29 +1072,19 @@ static int tar_rename (char *a, char *b)
static int tar_chdir (char *path)
{
struct tarfs_archive *archive;
char *p, *q;
char *q;
struct tarfs_entry *entry;
tarerrno = ENOTDIR;
if ((p = tarfs_get_path (path, &archive, 1, 0)) == NULL)
if ((q = tarfs_get_path (path, &archive, 1, 0)) == NULL)
return -1;
q = (*p == '/') ? p + 1 : p;
entry = tarfs_find_entry (archive->root_entry, q, 0);
if (entry == NULL) {
free (p);
entry = tarfs_find_entry (archive->root_entry, q, 0, 0);
if (!entry)
return -1;
}
entry = tarfs_resolve_symlinks (entry);
if (entry == NULL) {
free (p);
if ((!entry) || (!S_ISDIR (entry->inode->mode)))
return -1;
}
if (!S_ISDIR (entry->inode->mode)) {
free (p);
return -1;
}
entry->inode->archive->current_dir = entry;
free (p);
tarerrno = 0;
return 0;
}
@ -1423,7 +1140,6 @@ static vfsid tar_getid (char *path, struct vfs_stamping **parent)
if ((p = tarfs_get_path (path, &archive, 0, 1)) == NULL) {
return (vfsid) -1;
}
free (p);
v = vfs_type (archive->name);
id = (*v->getid) (archive->name, &par);
if (id != (vfsid)-1) {
@ -1491,12 +1207,12 @@ static char *tar_getlocalcopy (char *path)
struct tarfs_archive *archive;
char *p, *q;
struct tarfs_entry *entry;
char buf[MC_MAXPATHLEN];
if ((p = tarfs_get_path (path, &archive, 1, 0)) == NULL)
strcpy( buf, path );
if ((q = tarfs_get_path (path, &archive, 1, 0)) == NULL)
return NULL;
q = (*p == '/') ? p + 1 : p;
entry = tarfs_find_entry (archive->root_entry, q, 0);
free (p);
entry = tarfs_find_entry (archive->root_entry, q, 0, 0);
if (entry == NULL)
return NULL;
if ((entry = tarfs_resolve_symlinks (entry)) == NULL)
@ -1504,7 +1220,7 @@ static char *tar_getlocalcopy (char *path)
if (entry->inode->local_filename != NULL)
return entry->inode->local_filename;
p = mc_def_getlocalcopy (path);
p = mc_def_getlocalcopy (buf);
if (p != NULL) {
entry->inode->local_filename = p;
}
@ -1534,30 +1250,32 @@ vfs tarfs_vfs_ops =
tar_open,
tar_close,
tar_read,
tar_write,
tar_write, /* unimplemented */
tar_opendir,
tar_readdir,
tar_closedir,
s_opendir,
s_readdir,
s_closedir,
s_telldir,
s_seekdir,
tar_stat,
tar_lstat,
tar_fstat,
s_stat,
s_lstat,
s_fstat,
tar_chmod,
tar_chown,
NULL,
tar_readlink,
tar_symlink,
tar_link,
tar_unlink,
s_readlink,
tar_symlink, /* unimplemented */
tar_link, /* unimplemented */
tar_unlink, /* unimplemented */
tar_rename,
tar_rename, /* unimplemented */
tar_chdir,
tar_errno,
s_errno,
tar_lseek,
tar_mknod,
tar_mknod, /* unipmelemented */
tar_getid,
tar_nothingisopen,
@ -1566,13 +1284,13 @@ vfs tarfs_vfs_ops =
tar_getlocalcopy,
tar_ungetlocalcopy,
tar_mkdir,
tar_rmdir,
tar_mkdir, /* unimplemented */
tar_rmdir, /* unimplemented */
NULL,
NULL,
NULL
#ifdef HAVE_MMAP
, tar_mmap,
tar_munmap
, tar_mmap, /* unimplemented */
tar_munmap /* unimplemented */
#endif
};

Просмотреть файл

@ -54,6 +54,7 @@
{ tcp_invalidate_socket (sock); return got_sigpipe = 0; }
extern void tcp_invalidate_socket (int);
extern void vfs_die (char *);
int got_sigpipe;
@ -134,8 +135,7 @@ int rpc_send (int sock, ...)
break;
default:
fprintf (stderr, "Unknown rpc message\n");
abort ();
vfs_die ("Unknown rpc message\n");
}
}
}
@ -223,8 +223,7 @@ int rpc_get (int sock, ...)
break;
default:
fprintf (stderr, "Unknown rpc message\n");
abort ();
vfs_die ("Unknown rpc message\n");
}
}
}
@ -262,8 +261,8 @@ void tcp_init (void)
int get_remote_port (struct sockaddr_in *sin, int *version)
{
int port;
#ifdef HAVE_PMAP_GETMAPS
int port;
struct pmaplist *pl;
*version = 1;
@ -278,6 +277,7 @@ int get_remote_port (struct sockaddr_in *sin, int *version)
return port;
#else
#ifdef HAVE_PMAP_GETPORT
int port;
for (*version = RPC_PROGVER; *version >= 1; (*version)--)
if (port = pmap_getport (sin, RPC_PROGNUM, *version, IPPROTO_TCP))
return port;

Просмотреть файл

@ -769,6 +769,8 @@ vfs undelfs_vfs_ops = {
undelfs_opendir,
undelfs_readdir,
undelfs_closedir,
NULL,
NULL,
undelfs_stat,
undelfs_lstat,

981
vfs/vfs.c

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -1,6 +1,18 @@
#ifndef __VFS_H
#define __VFS_H
#ifdef VFS_STANDALONE
#include "util-alone.h"
#undef USE_EXT2FSLIB
#else
#define BROKEN_PATHS
/*
* We should really only allow /:ftp/ tree to export ftp, but midnight's users may
* like to be able to cd .. to get back where there were before ftp. How to solve?
* Ok, we'll allow /any/path/:ftp/ to access ftp tree. Broken, yes.
*/
#endif
#if !defined(SCO_FLAVOR) || !defined(_SYS_SELECT_H)
# include <sys/time.h> /* alex: this redefines struct timeval */
#endif /* SCO_FLAVOR */
@ -35,6 +47,8 @@ struct utimbuf {
void *(*opendir)(char *dirname);
void *(*readdir)(void *vfs_info);
int (*closedir)(void *vfs_info);
int (*telldir)(void *dir);
void (*seekdir)(void *dir, int offset);
int (*stat)(char *path, struct stat *buf);
int (*lstat)(char *path, struct stat *buf);
@ -139,12 +153,6 @@ struct utimbuf {
void ftpfs_fill_names (void (*)(char *));
void tarfs_fill_names (void (*)(char *));
char *ftpfs_gethome (char *);
char *mcfs_gethome (char *);
char *ftpfs_getupdir (char *);
char *mcfs_getupdir (char *);
/* Only the routines outside of the VFS module need the emulation macros */
int mc_open (char *file, int flags, ...);
@ -157,6 +165,8 @@ struct utimbuf {
DIR *mc_opendir (char *dirname);
struct dirent *mc_readdir(DIR *dirp);
int mc_closedir (DIR *dir);
int mc_telldir (DIR *dir);
void mc_seekdir (DIR *dir, int offset);
int mc_stat (char *path, struct stat *buf);
int mc_lstat (char *path, struct stat *buf);
@ -192,6 +202,8 @@ struct utimbuf {
# undef USE_NETCODE
#endif
# undef USE_NETCODE
# define vfs_fill_names(x)
# define vfs_add_current_stamps()
# define vfs_current_is_local() 1
@ -207,6 +219,8 @@ struct utimbuf {
# define mc_opendir opendir
# define mc_readdir readdir
# define mc_closedir closedir
# define mc_telldir telldir
# define mc_seekdir seekdir
# define mc_get_current_wd(x,size) get_current_wd (x, size)
# define mc_fstat fstat
@ -276,12 +290,15 @@ struct utimbuf {
#ifdef WANT_PARSE_LS_LGA
int parse_ls_lga (char *p, struct stat *s, char **filename, char **linkname);
#endif
extern void vfs_die (char *msg);
extern char *vfs_get_password (char *msg);
#define MCCTL_SETREMOTECOPY 0
#define MCCTL_ISREMOTECOPY 1
#define MCCTL_REMOTECOPYCHUNK 2
#define MCCTL_FINISHREMOTE 3
#define MCCTL_FLUSHDIR 4
#define MCCTL_REMOVELOCALCOPY 5
/* Return codes from the ${fs}_ctl routine */