Ignore:
Timestamp:
Jan 1, 2014, 12:47:38 AM (7 years ago)
Author:
Bruno Cornec
Message:
  • Update mindi-busybox to 1.21.1
File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/3.2/mindi-busybox/util-linux/mount.c

    r2725 r3232  
    1717// mount_it_now() does the actual mount.
    1818//
     19
     20//usage:#define mount_trivial_usage
     21//usage:       "[OPTIONS] [-o OPTS] DEVICE NODE"
     22//usage:#define mount_full_usage "\n\n"
     23//usage:       "Mount a filesystem. Filesystem autodetection requires /proc.\n"
     24//usage:     "\n    -a      Mount all filesystems in fstab"
     25//usage:    IF_FEATURE_MOUNT_FAKE(
     26//usage:    IF_FEATURE_MTAB_SUPPORT(
     27//usage:     "\n    -f      Update /etc/mtab, but don't mount"
     28//usage:    )
     29//usage:    IF_NOT_FEATURE_MTAB_SUPPORT(
     30//usage:     "\n    -f      Dry run"
     31//usage:    )
     32//usage:    )
     33//usage:    IF_FEATURE_MOUNT_HELPERS(
     34//usage:     "\n    -i      Don't run mount helper"
     35//usage:    )
     36//usage:    IF_FEATURE_MTAB_SUPPORT(
     37//usage:     "\n    -n      Don't update /etc/mtab"
     38//usage:    )
     39//usage:    IF_FEATURE_MOUNT_VERBOSE(
     40//usage:     "\n    -v      Verbose"
     41//usage:    )
     42////usage:   "\n    -s      Sloppy (ignored)"
     43//usage:     "\n    -r      Read-only mount"
     44//usage:     "\n    -w      Read-write mount (default)"
     45//usage:     "\n    -t FSTYPE[,...] Filesystem type(s)"
     46//usage:     "\n    -O OPT      Mount only filesystems with option OPT (-a only)"
     47//usage:     "\n-o OPT:"
     48//usage:    IF_FEATURE_MOUNT_LOOP(
     49//usage:     "\n    loop        Ignored (loop devices are autodetected)"
     50//usage:    )
     51//usage:    IF_FEATURE_MOUNT_FLAGS(
     52//usage:     "\n    [a]sync     Writes are [a]synchronous"
     53//usage:     "\n    [no]atime   Disable/enable updates to inode access times"
     54//usage:     "\n    [no]diratime    Disable/enable atime updates to directories"
     55//usage:     "\n    [no]relatime    Disable/enable atime updates relative to modification time"
     56//usage:     "\n    [no]dev     (Dis)allow use of special device files"
     57//usage:     "\n    [no]exec    (Dis)allow use of executable files"
     58//usage:     "\n    [no]suid    (Dis)allow set-user-id-root programs"
     59//usage:     "\n    [r]shared   Convert [recursively] to a shared subtree"
     60//usage:     "\n    [r]slave    Convert [recursively] to a slave subtree"
     61//usage:     "\n    [r]private  Convert [recursively] to a private subtree"
     62//usage:     "\n    [un]bindable    Make mount point [un]able to be bind mounted"
     63//usage:     "\n    [r]bind     Bind a file or directory [recursively] to another location"
     64//usage:     "\n    move        Relocate an existing mount point"
     65//usage:    )
     66//usage:     "\n    remount     Remount a mounted filesystem, changing flags"
     67//usage:     "\n    ro/rw       Same as -r/-w"
     68//usage:     "\n"
     69//usage:     "\nThere are filesystem-specific -o flags."
     70//usage:
     71//usage:#define mount_example_usage
     72//usage:       "$ mount\n"
     73//usage:       "/dev/hda3 on / type minix (rw)\n"
     74//usage:       "proc on /proc type proc (rw)\n"
     75//usage:       "devpts on /dev/pts type devpts (rw)\n"
     76//usage:       "$ mount /dev/fd0 /mnt -t msdos -o ro\n"
     77//usage:       "$ mount /tmp/diskimage /opt -t ext2 -o loop\n"
     78//usage:       "$ mount cd_image.iso mydir\n"
     79//usage:#define mount_notes_usage
     80//usage:       "Returns 0 for success, number of failed mounts for -a, or errno for one mount."
     81
    1982#include <mntent.h>
    2083#include <syslog.h>
     
    55118# define MS_RELATIME    (1 << 21)
    56119#endif
     120#ifndef MS_STRICTATIME
     121# define MS_STRICTATIME (1 << 24)
     122#endif
     123
     124/* Any ~MS_FOO value has this bit set: */
     125#define BB_MS_INVERTED_VALUE (1u << 31)
    57126
    58127#include "libbb.h"
     
    160229        IF_DESKTOP(/* "users" */ MOUNT_USERS,)
    161230        /* "_netdev" */ 0,
     231        IF_DESKTOP(/* "comment=" */ 0,) /* systemd uses this in fstab */
    162232    )
    163233
     
    181251        /* "relatime"    */ MS_RELATIME,
    182252        /* "norelatime"  */ ~MS_RELATIME,
     253        /* "strictatime" */ MS_STRICTATIME,
    183254        /* "loud"        */ ~MS_SILENT,
     255        /* "rbind"       */ MS_BIND|MS_RECURSIVE,
    184256
    185257        // action flags
     
    193265        /* "rshared"     */ MS_SHARED|MS_RECURSIVE,
    194266        /* "rslave"      */ MS_SLAVE|MS_RECURSIVE,
    195         /* "rprivate"    */ MS_SLAVE|MS_RECURSIVE,
     267        /* "rprivate"    */ MS_PRIVATE|MS_RECURSIVE,
    196268        /* "runbindable" */ MS_UNBINDABLE|MS_RECURSIVE,
    197269    )
     
    216288        IF_DESKTOP("users\0")
    217289        "_netdev\0"
     290        IF_DESKTOP("comment=\0") /* systemd uses this in fstab */
    218291    )
    219292    IF_FEATURE_MOUNT_FLAGS(
     
    236309        "relatime\0"
    237310        "norelatime\0"
     311        "strictatime\0"
    238312        "loud\0"
     313        "rbind\0"
    239314
    240315        // action flags
     
    242317        "bind\0"
    243318        "move\0"
    244         "shared\0"
    245         "slave\0"
    246         "private\0"
    247         "unbindable\0"
    248         "rshared\0"
    249         "rslave\0"
    250         "rprivate\0"
    251         "runbindable\0"
     319        "make-shared\0"
     320        "make-slave\0"
     321        "make-private\0"
     322        "make-unbindable\0"
     323        "make-rshared\0"
     324        "make-rslave\0"
     325        "make-rprivate\0"
     326        "make-runbindable\0"
    252327    )
    253328
     
    279354#define fslist            (G.fslist           )
    280355#define getmntent_buf     (G.getmntent_buf    )
    281 
     356#define INIT_G() do { } while (0)
     357
     358#if ENABLE_FEATURE_MTAB_SUPPORT
     359/*
     360 * update_mtab_entry_on_move() is used to update entry in case of mount --move.
     361 * we are looking for existing entries mnt_dir which is equal to mnt_fsname of
     362 * input mntent and replace it by new one.
     363 */
     364static void FAST_FUNC update_mtab_entry_on_move(const struct mntent *mp)
     365{
     366    struct mntent *entries, *m;
     367    int i, count;
     368    FILE *mountTable;
     369
     370    mountTable = setmntent(bb_path_mtab_file, "r");
     371    if (!mountTable) {
     372        bb_perror_msg(bb_path_mtab_file);
     373        return;
     374    }
     375
     376    entries = NULL;
     377    count = 0;
     378    while ((m = getmntent(mountTable)) != NULL) {
     379        entries = xrealloc_vector(entries, 3, count);
     380        entries[count].mnt_fsname = xstrdup(m->mnt_fsname);
     381        entries[count].mnt_dir = xstrdup(m->mnt_dir);
     382        entries[count].mnt_type = xstrdup(m->mnt_type);
     383        entries[count].mnt_opts = xstrdup(m->mnt_opts);
     384        entries[count].mnt_freq = m->mnt_freq;
     385        entries[count].mnt_passno = m->mnt_passno;
     386        count++;
     387    }
     388    endmntent(mountTable);
     389
     390    mountTable = setmntent(bb_path_mtab_file, "w");
     391    if (mountTable) {
     392        for (i = 0; i < count; i++) {
     393            if (strcmp(entries[i].mnt_dir, mp->mnt_fsname) != 0)
     394                addmntent(mountTable, &entries[i]);
     395            else
     396                addmntent(mountTable, mp);
     397        }
     398        endmntent(mountTable);
     399    } else if (errno != EROFS)
     400        bb_perror_msg(bb_path_mtab_file);
     401
     402    if (ENABLE_FEATURE_CLEAN_UP) {
     403        for (i = 0; i < count; i++) {
     404            free(entries[i].mnt_fsname);
     405            free(entries[i].mnt_dir);
     406            free(entries[i].mnt_type);
     407            free(entries[i].mnt_opts);
     408        }
     409        free(entries);
     410    }
     411}
     412#endif
    282413
    283414#if ENABLE_FEATURE_MOUNT_VERBOSE
     
    334465// Use the mount_options list to parse options into flags.
    335466// Also update list of unrecognized options if unrecognized != NULL
    336 static long parse_mount_options(char *options, char **unrecognized)
    337 {
    338     long flags = MS_SILENT;
     467static unsigned long parse_mount_options(char *options, char **unrecognized)
     468{
     469    unsigned long flags = MS_SILENT;
    339470
    340471    // Loop through options
     
    349480        // Find this option in mount_options
    350481        for (i = 0; i < ARRAY_SIZE(mount_options); i++) {
    351             if (strcasecmp(option_str, options) == 0) {
    352                 long fl = mount_options[i];
    353                 if (fl < 0)
     482            unsigned opt_len = strlen(option_str);
     483
     484            if (strncasecmp(option_str, options, opt_len) == 0
     485             && (options[opt_len] == '\0'
     486                /* or is it "comment=" thingy in fstab? */
     487                IF_FEATURE_MOUNT_FSTAB(IF_DESKTOP( || option_str[opt_len-1] == '=' ))
     488                )
     489            ) {
     490                unsigned long fl = mount_options[i];
     491                if (fl & BB_MS_INVERTED_VALUE)
    354492                    flags &= fl;
    355493                else
     
    357495                goto found;
    358496            }
    359             option_str += strlen(option_str) + 1;
     497            option_str += opt_len + 1;
    360498        }
    361499        // We did not recognize this option.
     
    406544        while ((buf = xmalloc_fgetline(f)) != NULL) {
    407545            if (strncmp(buf, "nodev", 5) == 0 && isspace(buf[5]))
    408                 continue;
     546                goto next;
    409547            fs = skip_whitespace(buf);
    410548            if (*fs == '#' || *fs == '*' || !*fs)
    411                 continue;
     549                goto next;
    412550
    413551            llist_add_to_end(&list, xstrdup(fs));
     552 next:
    414553            free(buf);
    415554        }
     
    431570// Perform actual mount of specific filesystem at specific location.
    432571// NB: mp->xxx fields may be trashed on exit
    433 static int mount_it_now(struct mntent *mp, long vfsflags, char *filteropts)
     572static int mount_it_now(struct mntent *mp, unsigned long vfsflags, char *filteropts)
    434573{
    435574    int rc = 0;
     
    497636
    498637        if (!mountTable) {
    499             bb_error_msg("no %s", bb_path_mtab_file);
     638            bb_perror_msg(bb_path_mtab_file);
    500639            goto ret;
    501640        }
    502641
    503642        // Add vfs string flags
    504 
    505643        for (i = 0; mount_options[i] != MS_REMOUNT; i++) {
    506644            if (mount_options[i] > 0 && (mount_options[i] & vfsflags))
     
    510648
    511649        // Remove trailing / (if any) from directory we mounted on
    512 
    513650        i = strlen(mp->mnt_dir) - 1;
    514         if (i > 0 && mp->mnt_dir[i] == '/') mp->mnt_dir[i] = '\0';
     651        while (i > 0 && mp->mnt_dir[i] == '/')
     652            mp->mnt_dir[i--] = '\0';
    515653
    516654        // Convert to canonical pathnames as needed
    517 
    518655        mp->mnt_dir = bb_simplify_path(mp->mnt_dir);
    519         fsname = 0;
     656        fsname = NULL;
    520657        if (!mp->mnt_type || !*mp->mnt_type) { // bind mount
    521658            mp->mnt_fsname = fsname = bb_simplify_path(mp->mnt_fsname);
     
    524661        mp->mnt_freq = mp->mnt_passno = 0;
    525662
    526         // Write and close.
    527 
    528         addmntent(mountTable, mp);
     663        // Write and close
     664#if ENABLE_FEATURE_MTAB_SUPPORT
     665        if (vfsflags & MS_MOVE)
     666            update_mtab_entry_on_move(mp);
     667        else
     668#endif
     669            addmntent(mountTable, mp);
    529670        endmntent(mountTable);
     671
    530672        if (ENABLE_FEATURE_CLEAN_UP) {
    531673            free(mp->mnt_dir);
     
    700842
    701843struct nfs2_fh {
    702     char                    data[32];
     844    char            data[32];
    703845};
    704846struct nfs3_fh {
    705     unsigned short          size;
    706     unsigned char           data[64];
     847    unsigned short  size;
     848    unsigned char   data[64];
    707849};
    708850
    709851struct nfs_mount_data {
    710     int     version;        /* 1 */
    711     int     fd;         /* 1 */
    712     struct nfs2_fh  old_root;       /* 1 */
    713     int     flags;          /* 1 */
    714     int     rsize;          /* 1 */
    715     int     wsize;          /* 1 */
    716     int     timeo;          /* 1 */
    717     int     retrans;        /* 1 */
    718     int     acregmin;       /* 1 */
    719     int     acregmax;       /* 1 */
    720     int     acdirmin;       /* 1 */
    721     int     acdirmax;       /* 1 */
    722     struct sockaddr_in addr;        /* 1 */
    723     char        hostname[256];      /* 1 */
    724     int     namlen;         /* 2 */
    725     unsigned int    bsize;          /* 3 */
    726     struct nfs3_fh  root;           /* 4 */
     852    int     version;    /* 1 */
     853    int     fd;     /* 1 */
     854    struct nfs2_fh  old_root;   /* 1 */
     855    int     flags;      /* 1 */
     856    int     rsize;      /* 1 */
     857    int     wsize;      /* 1 */
     858    int     timeo;      /* 1 */
     859    int     retrans;    /* 1 */
     860    int     acregmin;   /* 1 */
     861    int     acregmax;   /* 1 */
     862    int     acdirmin;   /* 1 */
     863    int     acdirmax;   /* 1 */
     864    struct sockaddr_in addr;    /* 1 */
     865    char        hostname[256];  /* 1 */
     866    int     namlen;     /* 2 */
     867    unsigned int    bsize;      /* 3 */
     868    struct nfs3_fh  root;       /* 4 */
    727869};
    728870
     
    739881    NFS_MOUNT_KERBEROS = 0x0100,    /* 3 */
    740882    NFS_MOUNT_NONLM = 0x0200,   /* 3 */
     883    NFS_MOUNT_NOACL = 0x0800,   /* 4 */
    741884    NFS_MOUNT_NORDIRPLUS = 0x4000
    742885};
     
    792935{
    793936    if (!xdr_u_int(xdrs, &objp->fhs_status))
    794          return FALSE;
     937        return FALSE;
    795938    if (objp->fhs_status == 0)
    796939        return xdr_fhandle(xdrs, objp->fhstatus_u.fhs_fhandle);
     
    806949{
    807950    return xdr_bytes(xdrs, (char **)&objp->fhandle3_val,
    808                (unsigned int *) &objp->fhandle3_len,
    809                FHSIZE3);
     951            (unsigned int *) &objp->fhandle3_len,
     952            FHSIZE3);
    810953}
    811954
     
    815958        return FALSE;
    816959    return xdr_array(xdrs, &(objp->auth_flavours.auth_flavours_val),
    817                &(objp->auth_flavours.auth_flavours_len),
    818                ~0,
    819                sizeof(int),
    820                (xdrproc_t) xdr_int);
     960            &(objp->auth_flavours.auth_flavours_len),
     961            ~0,
     962            sizeof(int),
     963            (xdrproc_t) xdr_int);
    821964}
    822965
     
    9591102
    9601103/* NB: mp->xxx fields may be trashed on exit */
    961 static NOINLINE int nfsmount(struct mntent *mp, long vfsflags, char *filteropts)
     1104static NOINLINE int nfsmount(struct mntent *mp, unsigned long vfsflags, char *filteropts)
    9621105{
    9631106    CLIENT *mclient;
     
    10031146    int nordirplus;
    10041147    int nolock;
     1148    int noacl;
    10051149
    10061150    find_kernel_nfs_mount_version();
     
    10221166    *s = '\0';
    10231167    /* Ignore all but first hostname in replicated mounts
    1024        until they can be fully supported. (mack@sgi.com) */
     1168     * until they can be fully supported. (mack@sgi.com) */
    10251169    s = strchr(hostname, ',');
    10261170    if (s) {
     
    10751219    noac = 0;
    10761220    nordirplus = 0;
     1221    noacl = 0;
    10771222    retry = 10000;      /* 10000 minutes ~ 1 week */
    1078     tcp = 0;
     1223    tcp = 1;            /* nfs-utils uses tcp per default */
    10791224
    10801225    mountprog = MOUNTPROG;
     
    11301275            case 20: // "addr" - ignore
    11311276                continue;
     1277            case -1: // unknown
     1278                if (vfsflags & MS_REMOUNT)
     1279                    continue;
    11321280            }
    11331281
     
    12101358                "udp\0"
    12111359                "lock\0"
    1212                 "rdirplus\0";
     1360                "rdirplus\0"
     1361                "acl\0";
    12131362            int val = 1;
    12141363            if (!strncmp(opt, "no", 2)) {
     
    12601409                nordirplus = !val;
    12611410                break;
     1411            case 12: // acl
     1412                noacl = !val;
     1413                break;
    12621414            default:
    12631415                bb_error_msg("unknown nfs mount option: %s%s", val ? "" : "no", opt);
     
    12731425        | (nocto ? NFS_MOUNT_NOCTO : 0)
    12741426        | (noac ? NFS_MOUNT_NOAC : 0)
    1275         | (nordirplus ? NFS_MOUNT_NORDIRPLUS : 0);
     1427        | (nordirplus ? NFS_MOUNT_NORDIRPLUS : 0)
     1428        | (noacl ? NFS_MOUNT_NOACL : 0);
    12761429    if (nfs_mount_version >= 2)
    12771430        data.flags |= (tcp ? NFS_MOUNT_TCP : 0);
     
    13771530        case IPPROTO_UDP:
    13781531            mclient = clntudp_create(&mount_server_addr,
    1379                          pm_mnt.pm_prog,
    1380                          pm_mnt.pm_vers,
    1381                          retry_timeout,
    1382                          &msock);
     1532                        pm_mnt.pm_prog,
     1533                        pm_mnt.pm_vers,
     1534                        retry_timeout,
     1535                        &msock);
    13831536            if (mclient)
    13841537                break;
     
    13871540        case IPPROTO_TCP:
    13881541            mclient = clnttcp_create(&mount_server_addr,
    1389                          pm_mnt.pm_prog,
    1390                          pm_mnt.pm_vers,
    1391                          &msock, 0, 0);
     1542                        pm_mnt.pm_prog,
     1543                        pm_mnt.pm_vers,
     1544                        &msock, 0, 0);
    13921545            break;
    13931546        default:
     
    14101563            if (pm_mnt.pm_vers == 3)
    14111564                clnt_stat = clnt_call(mclient, MOUNTPROC3_MNT,
    1412                           (xdrproc_t) xdr_dirpath,
    1413                           (caddr_t) &pathname,
    1414                           (xdrproc_t) xdr_mountres3,
    1415                           (caddr_t) &status,
    1416                           total_timeout);
     1565                        (xdrproc_t) xdr_dirpath,
     1566                        (caddr_t) &pathname,
     1567                        (xdrproc_t) xdr_mountres3,
     1568                        (caddr_t) &status,
     1569                        total_timeout);
    14171570            else
    14181571                clnt_stat = clnt_call(mclient, MOUNTPROC_MNT,
    1419                           (xdrproc_t) xdr_dirpath,
    1420                           (caddr_t) &pathname,
    1421                           (xdrproc_t) xdr_fhstatus,
    1422                           (caddr_t) &status,
    1423                           total_timeout);
     1572                        (xdrproc_t) xdr_dirpath,
     1573                        (caddr_t) &pathname,
     1574                        (xdrproc_t) xdr_fhstatus,
     1575                        (caddr_t) &status,
     1576                        total_timeout);
    14241577
    14251578            if (clnt_stat == RPC_SUCCESS)
     
    15521705    /* Perform actual mount */
    15531706 do_mount:
    1554     mp->mnt_type = (char*)"nfs";
    15551707    retval = mount_it_now(mp, vfsflags, (char*)&data);
    15561708    goto ret;
     
    15771729#else // !ENABLE_FEATURE_MOUNT_NFS
    15781730
    1579 // Never called. Call should be optimized out.
    1580 int nfsmount(struct mntent *mp, long vfsflags, char *filteropts);
     1731/* Linux 2.6.23+ supports nfs mounts with options passed as a string.
     1732 * For older kernels, you must build busybox with ENABLE_FEATURE_MOUNT_NFS.
     1733 * (However, note that then you lose any chances that NFS over IPv6 would work).
     1734 */
     1735static int nfsmount(struct mntent *mp, unsigned long vfsflags, char *filteropts)
     1736{
     1737    len_and_sockaddr *lsa;
     1738    char *opts;
     1739    char *end;
     1740    char *dotted;
     1741    int ret;
     1742
     1743# if ENABLE_FEATURE_IPV6
     1744    end = strchr(mp->mnt_fsname, ']');
     1745    if (end && end[1] == ':')
     1746        end++;
     1747    else
     1748# endif
     1749        /* mount_main() guarantees that ':' is there */
     1750        end = strchr(mp->mnt_fsname, ':');
     1751
     1752    *end = '\0';
     1753    lsa = xhost2sockaddr(mp->mnt_fsname, /*port:*/ 0);
     1754    *end = ':';
     1755    dotted = xmalloc_sockaddr2dotted_noport(&lsa->u.sa);
     1756    if (ENABLE_FEATURE_CLEAN_UP) free(lsa);
     1757    opts = xasprintf("%s%saddr=%s",
     1758        filteropts ? filteropts : "",
     1759        filteropts ? "," : "",
     1760        dotted
     1761    );
     1762    if (ENABLE_FEATURE_CLEAN_UP) free(dotted);
     1763    ret = mount_it_now(mp, vfsflags, opts);
     1764    if (ENABLE_FEATURE_CLEAN_UP) free(opts);
     1765
     1766    return ret;
     1767}
    15811768
    15821769#endif // !ENABLE_FEATURE_MOUNT_NFS
     
    15881775{
    15891776    int rc = -1;
    1590     long vfsflags;
     1777    unsigned long vfsflags;
    15911778    char *loopFile = NULL, *filteropts = NULL;
    15921779    llist_t *fl = NULL;
     
    16381825        int len;
    16391826        char c;
     1827        char *hostname, *share;
     1828        char *dotted, *ip;
    16401829        len_and_sockaddr *lsa;
    1641         char *hostname, *dotted, *ip;
     1830
     1831        // Parse mp->mnt_fsname of the form "//hostname/share[/dir1/dir2]"
    16421832
    16431833        hostname = mp->mnt_fsname + 2;
    16441834        len = strcspn(hostname, "/\\");
    1645         if (len == 0 || hostname[len] == '\0')
     1835        share = hostname + len + 1;
     1836        if (len == 0          // 3rd char is a [back]slash (IOW: empty hostname)
     1837         || share[-1] == '\0' // no [back]slash after hostname
     1838         || share[0] == '\0'  // empty share name
     1839        ) {
    16461840            goto report_error;
    1647         c = hostname[len];
    1648         hostname[len] = '\0';
     1841        }
     1842        c = share[-1];
     1843        share[-1] = '\0';
     1844        len = strcspn(share, "/\\");
     1845
     1846        // "unc=\\hostname\share" option is mandatory
     1847        // after CIFS option parsing was rewritten in Linux 3.4.
     1848        // Must use backslashes.
     1849        // If /dir1/dir2 is present, also add "prefixpath=dir1/dir2"
     1850        {
     1851            char *unc = xasprintf(
     1852                share[len] != '\0'  /* "/dir1/dir2" exists? */
     1853                    ? "unc=\\\\%s\\%.*s,prefixpath=%s"
     1854                    : "unc=\\\\%s\\%.*s",
     1855                hostname,
     1856                len, share,
     1857                share + len + 1  /* "dir1/dir2" */
     1858            );
     1859            parse_mount_options(unc, &filteropts);
     1860            if (ENABLE_FEATURE_CLEAN_UP) free(unc);
     1861        }
     1862
    16491863        lsa = host2sockaddr(hostname, 0);
    1650         hostname[len] = c;
     1864        share[-1] = c;
    16511865        if (!lsa)
    16521866            goto report_error;
     
    16601874        if (ENABLE_FEATURE_CLEAN_UP) free(ip);
    16611875
    1662         // "-o mand" is required [why?]
    1663         vfsflags |= MS_MANDLOCK;
    16641876        mp->mnt_type = (char*)"cifs";
    16651877        rc = mount_it_now(mp, vfsflags, filteropts);
     
    16691881
    16701882    // Might this be an NFS filesystem?
    1671     if (ENABLE_FEATURE_MOUNT_NFS
    1672      && (!mp->mnt_type || strcmp(mp->mnt_type, "nfs") == 0)
     1883    if ((!mp->mnt_type || strncmp(mp->mnt_type, "nfs", 3) == 0)
    16731884     && strchr(mp->mnt_fsname, ':') != NULL
    16741885    ) {
     1886        if (!mp->mnt_type)
     1887            mp->mnt_type = (char*)"nfs";
    16751888        rc = nfsmount(mp, vfsflags, filteropts);
    16761889        goto report_error;
     
    16881901            loopFile = bb_simplify_path(mp->mnt_fsname);
    16891902            mp->mnt_fsname = NULL; // will receive malloced loop dev name
    1690             if (set_loop(&mp->mnt_fsname, loopFile, 0) < 0) {
     1903            if (set_loop(&mp->mnt_fsname, loopFile, 0, /*ro:*/ (vfsflags & MS_RDONLY)) < 0) {
    16911904                if (errno == EPERM || errno == EACCES)
    16921905                    bb_error_msg(bb_msg_perm_denied_are_you_root);
     
    17041917    // to the actual mount.
    17051918    if (mp->mnt_type || (vfsflags & (MS_REMOUNT | MS_BIND | MS_MOVE))) {
    1706         rc = mount_it_now(mp, vfsflags, filteropts);
     1919        char *next;
     1920        for (;;) {
     1921            next = mp->mnt_type ? strchr(mp->mnt_type, ',') : NULL;
     1922            if (next)
     1923                *next = '\0';
     1924            rc = mount_it_now(mp, vfsflags, filteropts);
     1925            if (rc == 0 || !next)
     1926                break;
     1927            mp->mnt_type = next + 1;
     1928        }
    17071929    } else {
    17081930        // Loop through filesystem types until mount succeeds
     
    17211943            mp->mnt_type = fl->data;
    17221944            rc = mount_it_now(mp, vfsflags, filteropts);
    1723             if (!rc)
     1945            if (rc == 0)
    17241946                break;
    17251947        }
     
    18172039    int i, j;
    18182040    int rc = EXIT_SUCCESS;
     2041    unsigned long cmdopt_flags;
    18192042    unsigned opt;
    18202043    struct mntent mtpair[2], *mtcur = mtpair;
     
    18222045
    18232046    IF_DESKTOP(int nonroot = ) sanitize_env_if_suid();
     2047
     2048    INIT_G();
    18242049
    18252050    // Parse long options, like --bind and --move.  Note that -o option
     
    18892114    // or "mount [opts] single_param"
    18902115
    1891     i = parse_mount_options(cmdopts, NULL); // FIXME: should be "long", not "int"
    1892     if (nonroot && (i & ~MS_SILENT)) // Non-root users cannot specify flags
     2116    cmdopt_flags = parse_mount_options(cmdopts, NULL);
     2117    if (nonroot && (cmdopt_flags & ~MS_SILENT)) // Non-root users cannot specify flags
    18932118        bb_error_msg_and_die(bb_msg_you_must_be_root);
    18942119
    18952120    // If we have a shared subtree flag, don't worry about fstab or mtab.
    18962121    if (ENABLE_FEATURE_MOUNT_FLAGS
    1897      && (i & (MS_SHARED | MS_PRIVATE | MS_SLAVE | MS_UNBINDABLE))
     2122     && (cmdopt_flags & (MS_SHARED | MS_PRIVATE | MS_SLAVE | MS_UNBINDABLE))
    18982123    ) {
    18992124        // verbose_mount(source, target, type, flags, data)
    1900         rc = verbose_mount("", argv[0], "", i, "");
     2125        rc = verbose_mount("", argv[0], "", cmdopt_flags, "");
    19012126        if (rc)
    19022127            bb_simple_perror_msg_and_die(argv[0]);
     
    19062131    // Open either fstab or mtab
    19072132    fstabname = "/etc/fstab";
    1908     if (i & MS_REMOUNT) {
     2133    if (cmdopt_flags & MS_REMOUNT) {
    19092134        // WARNING. I am not sure this matches util-linux's
    19102135        // behavior. It's possible util-linux does not
     
    20052230    // Were we looking for something specific?
    20062231    if (argv[0]) { // yes
    2007         long l;
     2232        unsigned long l;
    20082233
    20092234        // If we didn't find anything, complain
Note: See TracChangeset for help on using the changeset viewer.