~ubuntu-branches/ubuntu/quantal/mc/quantal

« back to all changes in this revision

Viewing changes to vfs/ftpfs.c

  • Committer: Bazaar Package Importer
  • Author(s): Ludovic Drolez
  • Date: 2006-08-24 22:19:03 UTC
  • mfrom: (2.1.4 edgy)
  • Revision ID: james.westby@ubuntu.com-20060824221903-v7g8c4t1het21fy8
Tags: 1:4.6.1-6
* debian/rules modified to fix a FTBFS during the 2nd build. Closes: #384302
* added 05_symcrash.patch to fix a segfault (should be in mc's CVS). Closes: #383341
* mpg123 title view fixed. Closes: #391644

Show diffs side-by-side

added added

removed removed

Lines of Context:
19
19
 
20
20
   You should have received a copy of the GNU Library General Public
21
21
   License along with this program; if not, write to the Free Software
22
 
   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
22
   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
23
23
   
24
24
/* FTPfs TODO:
25
25
 
72
72
 
73
73
#include "xdirentry.h"
74
74
#include "vfs.h"
 
75
#include "vfs-impl.h"
75
76
#include "gc.h"         /* vfs_stamp_create */
76
77
#include "tcputil.h"
77
78
#include "../src/setup.h"       /* for load_anon_passwd */
92
93
#define RFC_DARING 1
93
94
#define RFC_STRICT 2
94
95
 
 
96
#ifndef HAVE_C_TYPE_SOCKLEN_T
 
97
typedef int socklen_t;
 
98
#endif
95
99
 
96
100
static int ftpfs_errno;
97
101
static int code;
151
155
 */
152
156
 
153
157
static char *ftpfs_get_current_directory (struct vfs_class *me, struct vfs_s_super *super);
154
 
static int ftpfs_chdir_internal (struct vfs_class *me, struct vfs_s_super *super, char *remote_path);
 
158
static int ftpfs_chdir_internal (struct vfs_class *me, struct vfs_s_super *super, const char *remote_path);
155
159
static int ftpfs_command (struct vfs_class *me, struct vfs_s_super *super, int wait_reply, const char *fmt, ...)
156
160
    __attribute__ ((format (printf, 4, 5)));
157
161
static int ftpfs_open_socket (struct vfs_class *me, struct vfs_s_super *super);
241
245
        g_free (new_user);
242
246
    }
243
247
 
244
 
    if (p)
245
 
        g_free (p);
 
248
    g_free (p);
246
249
}
247
250
 
248
251
/* Returns a reply code, check /usr/include/arpa/ftp.h for possible values */
261
264
        }
262
265
        switch (sscanf(answer, "%d", &code)){
263
266
            case 0:
264
 
                if (string_buf) {
265
 
                    strncpy (string_buf, answer, string_len - 1);
266
 
                    *(string_buf + string_len - 1) = 0;
267
 
                }
 
267
                if (string_buf) 
 
268
                    g_strlcpy (string_buf, answer, string_len);
268
269
                code = 500;
269
270
                return 5;
270
271
            case 1:
281
282
                            break;
282
283
                    }
283
284
                }
284
 
                if (string_buf){
285
 
                    strncpy (string_buf, answer, string_len - 1);
286
 
                    *(string_buf + string_len - 1) = 0;
287
 
                }
 
285
                if (string_buf)
 
286
                    g_strlcpy (string_buf, answer, string_len);
288
287
                return code / 100;
289
288
        }
290
289
    }
442
441
    if (!anon || MEDATA->logfile)
443
442
        pass = op;
444
443
    else {
445
 
        pass = g_strconcat ("-", op, NULL);
 
444
        pass = g_strconcat ("-", op, (char *) NULL);
446
445
        wipe_password (op);
447
446
    }
448
447
 
883
882
{
884
883
    struct sockaddr_in data_addr;
885
884
    int data;
886
 
    int len = sizeof(data_addr);
 
885
    socklen_t len = sizeof(data_addr);
887
886
    struct protoent *pe;
888
887
 
889
888
    pe = getprotobyname ("tcp");
933
932
                      const char *remote, int isbinary, int reget)
934
933
{
935
934
    struct sockaddr_in from;
936
 
    int s, j, data, fromlen = sizeof(from);
 
935
    int s, j, data;
 
936
    socklen_t fromlen = sizeof(from);
937
937
    
938
938
    if ((s = ftpfs_initconn (me, super)) == -1)
939
939
        return -1;
1292
1292
}
1293
1293
 
1294
1294
static int
1295
 
ftpfs_file_store(struct vfs_class *me, struct vfs_s_fh *fh, char *name, char *localname)
 
1295
ftpfs_file_store (struct vfs_class *me, struct vfs_s_fh *fh, char *name,
 
1296
                  char *localname)
1296
1297
{
1297
 
    int h, sock, n;
1298
 
    off_t total;
 
1298
    int h, sock, n_read, n_written;
 
1299
    off_t n_stored;
1299
1300
#ifdef HAVE_STRUCT_LINGER_L_LINGER
1300
1301
    struct linger li;
1301
1302
#else
1303
1304
#endif
1304
1305
    char buffer[8192];
1305
1306
    struct stat s;
 
1307
    char  *w_buf;
1306
1308
    struct vfs_s_super *super = FH_SUPER;
1307
1309
 
1308
 
    h = open(localname, O_RDONLY);
 
1310
    h = open (localname, O_RDONLY);
1309
1311
    if (h == -1)
1310
 
            ERRNOR (EIO, -1);
1311
 
    fstat(h, &s);
1312
 
    sock = ftpfs_open_data_connection(me, super, fh->u.ftp.append ? "APPE" : "STOR", name, TYPE_BINARY, 0);
1313
 
    if (sock < 0) {
1314
 
        close(h);
 
1312
        ERRNOR (EIO, -1);
 
1313
    sock =
 
1314
        ftpfs_open_data_connection (me, super,
 
1315
                                    fh->u.ftp.append ? "APPE" : "STOR", name,
 
1316
                                    TYPE_BINARY, 0);
 
1317
    if (sock < 0 || fstat (h, &s) == -1) {
 
1318
        close (h);
1315
1319
        return -1;
1316
1320
    }
1317
1321
#ifdef HAVE_STRUCT_LINGER_L_LINGER
1318
1322
    li.l_onoff = 1;
1319
1323
    li.l_linger = 120;
1320
 
    setsockopt(sock, SOL_SOCKET, SO_LINGER, (char *) &li, sizeof(li));
 
1324
    setsockopt (sock, SOL_SOCKET, SO_LINGER, (char *) &li, sizeof (li));
1321
1325
#else
1322
 
    setsockopt(sock, SOL_SOCKET, SO_LINGER, &flag_one, sizeof (flag_one));
 
1326
    setsockopt (sock, SOL_SOCKET, SO_LINGER, &flag_one, sizeof (flag_one));
1323
1327
#endif
1324
 
    total = 0;
1325
 
    
1326
 
    enable_interrupt_key();
 
1328
    n_stored = 0;
 
1329
 
 
1330
    enable_interrupt_key ();
1327
1331
    while (1) {
1328
 
        while ((n = read(h, buffer, sizeof(buffer))) < 0) {
 
1332
        while ((n_read = read (h, buffer, sizeof (buffer))) == -1) {
1329
1333
            if (errno == EINTR) {
1330
 
                if (got_interrupt()) {
 
1334
                if (got_interrupt ()) {
1331
1335
                    ftpfs_errno = EINTR;
1332
1336
                    goto error_return;
1333
 
                }
1334
 
                else
 
1337
                } else
1335
1338
                    continue;
1336
1339
            }
1337
1340
            ftpfs_errno = errno;
1338
1341
            goto error_return;
1339
1342
        }
1340
 
        if (n == 0)
 
1343
        if (n_read == 0)
1341
1344
            break;
1342
 
        while (write(sock, buffer, n) < 0) {
1343
 
            if (errno == EINTR) {
1344
 
                if (got_interrupt()) {
1345
 
                    ftpfs_errno = EINTR;
1346
 
                    goto error_return;
 
1345
        n_stored += n_read;
 
1346
        w_buf = buffer;
 
1347
        while ((n_written = write (sock, w_buf, n_read)) != n_read) {
 
1348
            if (n_written == -1) {
 
1349
                if (errno == EINTR && !got_interrupt ()) {
 
1350
                    continue;
1347
1351
                }
1348
 
                else 
1349
 
                    continue;
 
1352
                ftpfs_errno = errno;
 
1353
                goto error_return;
1350
1354
            }
1351
 
            ftpfs_errno = errno;
1352
 
            goto error_return;
 
1355
            w_buf += n_written;
 
1356
            n_read -= n_written;
1353
1357
        }
1354
 
        total += n;
1355
 
        print_vfs_message(_("ftpfs: storing file %lu (%lu)"),
1356
 
                          (unsigned long) total, (unsigned long) s.st_size);
 
1358
        print_vfs_message (_("ftpfs: storing file %lu (%lu)"),
 
1359
                           (unsigned long) n_stored, (unsigned long) s.st_size);
1357
1360
    }
1358
 
    disable_interrupt_key();
1359
 
    close(sock);
1360
 
    close(h);
 
1361
    disable_interrupt_key ();
 
1362
    close (sock);
 
1363
    close (h);
1361
1364
    if (ftpfs_get_reply (me, SUP.sock, NULL, 0) != COMPLETE)
1362
 
            ERRNOR (EIO, -1);
 
1365
        ERRNOR (EIO, -1);
1363
1366
    return 0;
1364
 
error_return:
1365
 
    disable_interrupt_key();
1366
 
    close(sock);
1367
 
    close(h);
1368
 
    ftpfs_get_reply(me, SUP.sock, NULL, 0);
 
1367
  error_return:
 
1368
    disable_interrupt_key ();
 
1369
    close (sock);
 
1370
    close (h);
 
1371
    ftpfs_get_reply (me, SUP.sock, NULL, 0);
1369
1372
    return -1;
1370
1373
}
1371
1374
 
1372
1375
static int 
1373
 
ftpfs_linear_start(struct vfs_class *me, struct vfs_s_fh *fh, int offset)
 
1376
ftpfs_linear_start (struct vfs_class *me, struct vfs_s_fh *fh, off_t offset)
1374
1377
{
1375
1378
    char *name = vfs_s_fullpath (me, fh->ino);
1376
1379
 
1441
1444
    }
1442
1445
}
1443
1446
 
1444
 
/* Warning: filename passed to this command is damaged */
1445
1447
static int
1446
 
ftpfs_send_command(struct vfs_class *me, char *filename, char *cmd, int flags)
 
1448
ftpfs_send_command(struct vfs_class *me, const char *filename, const char *cmd, int flags)
1447
1449
{
1448
 
    char *rpath, *p;
 
1450
    char *rpath, *p, *mpath = g_strdup(filename);
1449
1451
    struct vfs_s_super *super;
1450
1452
    int r;
1451
1453
    int flush_directory_cache = (flags & OPT_FLUSH);
1452
1454
 
1453
 
    if (!(rpath = vfs_s_get_path_mangle(me, filename, &super, 0)))
 
1455
    if (!(rpath = vfs_s_get_path_mangle(me, mpath, &super, 0))) {
 
1456
        g_free(mpath);
1454
1457
        return -1;
 
1458
    }
1455
1459
    p = ftpfs_translate_path (me, super, rpath);
1456
1460
    r = ftpfs_command (me, super, WAIT_REPLY, cmd, p);
1457
1461
    g_free (p);
1458
1462
    vfs_stamp_create (&vfs_ftpfs_ops, super);
1459
1463
    if (flags & OPT_IGNORE_ERROR)
1460
1464
        r = COMPLETE;
1461
 
    if (r != COMPLETE)
1462
 
            ERRNOR (EPERM, -1);
 
1465
    if (r != COMPLETE) {
 
1466
        me->verrno = EPERM;
 
1467
        g_free (mpath);
 
1468
        return -1;
 
1469
    }
1463
1470
    if (flush_directory_cache)
1464
1471
        vfs_s_invalidate(me, super);
 
1472
    g_free(mpath);
1465
1473
    return 0;
1466
1474
}
1467
1475
 
1484
1492
    ftpfs_anonymous_passwd = g_strdup ("anonymous@");
1485
1493
}
1486
1494
 
1487
 
static int ftpfs_chmod (struct vfs_class *me, char *path, int mode)
 
1495
static int ftpfs_chmod (struct vfs_class *me, const char *path, int mode)
1488
1496
{
1489
1497
    char buf[BUF_SMALL];
1490
1498
 
1492
1500
    return ftpfs_send_command(me, path, buf, OPT_FLUSH);
1493
1501
}
1494
1502
 
1495
 
static int ftpfs_chown (struct vfs_class *me, char *path, int owner, int group)
 
1503
static int ftpfs_chown (struct vfs_class *me, const char *path, int owner, int group)
1496
1504
{
1497
1505
#if 0
1498
1506
    ftpfs_errno = EPERM;
1504
1512
#endif    
1505
1513
}
1506
1514
 
1507
 
static int ftpfs_unlink (struct vfs_class *me, char *path)
 
1515
static int ftpfs_unlink (struct vfs_class *me, const char *path)
1508
1516
{
1509
1517
    return ftpfs_send_command(me, path, "DELE /%s", OPT_FLUSH);
1510
1518
}
1521
1529
}
1522
1530
 
1523
1531
static int
1524
 
ftpfs_chdir_internal (struct vfs_class *me, struct vfs_s_super *super, char *remote_path)
 
1532
ftpfs_chdir_internal (struct vfs_class *me, struct vfs_s_super *super, const char *remote_path)
1525
1533
{
1526
1534
    int r;
1527
1535
    char *p;
1543
1551
    return r;
1544
1552
}
1545
1553
 
1546
 
static int ftpfs_rename (struct vfs_class *me, char *path1, char *path2)
 
1554
static int ftpfs_rename (struct vfs_class *me, const char *path1, const char *path2)
1547
1555
{
1548
1556
    ftpfs_send_command(me, path1, "RNFR /%s", OPT_FLUSH);
1549
1557
    return ftpfs_send_command(me, path2, "RNTO /%s", OPT_FLUSH);
1550
1558
}
1551
1559
 
1552
 
static int ftpfs_mkdir (struct vfs_class *me, char *path, mode_t mode)
 
1560
static int ftpfs_mkdir (struct vfs_class *me, const char *path, mode_t mode)
1553
1561
{
1554
1562
    return ftpfs_send_command(me, path, "MKD /%s", OPT_FLUSH);
1555
1563
}
1556
1564
 
1557
 
static int ftpfs_rmdir (struct vfs_class *me, char *path)
 
1565
static int ftpfs_rmdir (struct vfs_class *me, const char *path)
1558
1566
{
1559
1567
    return ftpfs_send_command(me, path, "RMD /%s", OPT_FLUSH);
1560
1568
}
1653
1661
}
1654
1662
 
1655
1663
static void
1656
 
ftpfs_fill_names (struct vfs_class *me, void (*func)(char *))
 
1664
ftpfs_fill_names (struct vfs_class *me, fill_names_f func)
1657
1665
{
1658
1666
    struct vfs_s_super *super = MEDATA->supers;
1659
1667
    char *name;
1660
1668
    
1661
1669
    while (super){
1662
 
        name = g_strconcat ("/#ftp:", SUP.user, "@", SUP.host, "/", SUP.cwdir, NULL);
 
1670
        name = g_strconcat ("/#ftp:", SUP.user, "@", SUP.host, "/", SUP.cwdir, (char *) NULL);
1663
1671
        (*func)(name);
1664
1672
        g_free (name);
1665
1673
        super = super->next;
1667
1675
}
1668
1676
 
1669
1677
static char buffer[BUF_MEDIUM];
1670
 
static char *netrc, *netrcp;
 
1678
static char *netrc;
 
1679
static const char *netrcp;
1671
1680
 
1672
1681
/* This should match the keywords[] array below */
1673
1682
typedef enum {
1729
1738
    return NETRC_UNKNOWN;
1730
1739
}
1731
1740
 
1732
 
static int ftpfs_netrc_bad_mode (char *netrcname, char *netrc)
 
1741
static int ftpfs_netrc_bad_mode (const char *netrcname, const char *arg_netrc)
1733
1742
{
1734
1743
    static int be_angry = 1;
1735
1744
    struct stat mystat;
1779
1788
 
1780
1789
        if (g_strcasecmp (host, buffer)) {
1781
1790
            /* Try adding our domain to short names in .netrc */
1782
 
            char *host_domain = strchr (host, '.');
 
1791
            const char *host_domain = strchr (host, '.');
1783
1792
            if (!host_domain)
1784
1793
                continue;
1785
1794
 
1806
1815
{
1807
1816
    char *netrcname;
1808
1817
    char *tmp_pass = NULL;
1809
 
    char hostname[MAXHOSTNAMELEN], *domain;
 
1818
    char hostname[MAXHOSTNAMELEN];
 
1819
    const char *domain;
1810
1820
    keyword_t keyword;
1811
1821
    static struct rupcache {
1812
1822
        struct rupcache *next;