struct mount_entry * read_filesystem_list (int need_fs_type) { struct mount_entry *mount_list; struct mount_entry *me; struct mount_entry **mtail = &mount_list; #ifdef MOUNTED_LISTMNTENT { struct tabmntent *mntlist, *p; struct mntent *mnt; struct mount_entry *me; /* the third and fourth arguments could be used to filter mounts, but Crays doesn't seem to have any mounts that we want to remove. Specifically, automount create normal NFS mounts. */ if(listmntent(&mntlist, KMTAB, NULL, NULL) < 0) return NULL; for (p = mntlist; p; p = p->next) { mnt = p->ment; me = (struct mount_entry*) xmalloc(sizeof (struct mount_entry)); me->me_devname = xstrdup(mnt->mnt_fsname); me->me_mountdir = xstrdup(mnt->mnt_dir); me->me_type = xstrdup(mnt->mnt_type); me->me_dummy = ME_DUMMY (me->me_devname, me->me_type); me->me_remote = ME_REMOTE (me->me_devname, me->me_type); me->me_dev = -1; *mtail = me; mtail = &me->me_next; } freemntlist(mntlist); } #endif #ifdef MOUNTED_GETMNTENT1 /* 4.3BSD, SunOS, HP-UX, Dynix, Irix. */ { struct mntent *mnt; char *table = MOUNTED; FILE *fp; char *devopt; fp = setmntent (table, "r"); if (fp == NULL) return NULL; while ((mnt = getmntent (fp))) { me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry)); me->me_devname = xstrdup (mnt->mnt_fsname); me->me_mountdir = xstrdup (mnt->mnt_dir); me->me_type = xstrdup (mnt->mnt_type); me->me_dummy = ME_DUMMY (me->me_devname, me->me_type); me->me_remote = ME_REMOTE (me->me_devname, me->me_type); devopt = strstr (mnt->mnt_opts, "dev="); if (devopt) { if (devopt[4] == '0' && (devopt[5] == 'x' || devopt[5] == 'X')) me->me_dev = xatoi (devopt + 6); else me->me_dev = xatoi (devopt + 4); } else me->me_dev = (dev_t) -1; /* Magic; means not known yet. */ /* Add to the linked list. */ *mtail = me; mtail = &me->me_next; } if (endmntent (fp) == 0) goto free_then_fail; } #endif /* MOUNTED_GETMNTENT1. */ #ifdef MOUNTED_GETMNTINFO /* 4.4BSD. */ { struct statfs *fsp; int entries; entries = getmntinfo (&fsp, MNT_NOWAIT); if (entries < 0) return NULL; for (; entries-- > 0; fsp++) { char *fs_type = fsp_to_string (fsp); me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry)); me->me_devname = xstrdup (fsp->f_mntfromname); me->me_mountdir = xstrdup (fsp->f_mntonname); me->me_type = fs_type; me->me_dummy = ME_DUMMY (me->me_devname, me->me_type); me->me_remote = ME_REMOTE (me->me_devname, me->me_type); me->me_dev = (dev_t) -1; /* Magic; means not known yet. */ /* Add to the linked list. */ *mtail = me; mtail = &me->me_next; } } #endif /* MOUNTED_GETMNTINFO */ #ifdef MOUNTED_GETMNT /* Ultrix. */ { int offset = 0; int val; struct fs_data fsd; while (errno = 0, 0 < (val = getmnt (&offset, &fsd, sizeof (fsd), NOSTAT_MANY, (char *) 0))) { me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry)); me->me_devname = xstrdup (fsd.fd_req.devname); me->me_mountdir = xstrdup (fsd.fd_req.path); me->me_type = gt_names[fsd.fd_req.fstype]; me->me_dummy = ME_DUMMY (me->me_devname, me->me_type); me->me_remote = ME_REMOTE (me->me_devname, me->me_type); me->me_dev = fsd.fd_req.dev; /* Add to the linked list. */ *mtail = me; mtail = &me->me_next; } if (val < 0) goto free_then_fail; } #endif /* MOUNTED_GETMNT. */ #if defined (MOUNTED_FS_STAT_DEV) /* BeOS */ { /* The next_dev() and fs_stat_dev() system calls give the list of all filesystems, including the information returned by statvfs() (fs type, total blocks, free blocks etc.), but without the mount point. But on BeOS all filesystems except / are mounted in the rootfs, directly under /. The directory name of the mount point is often, but not always, identical to the volume name of the device. We therefore get the list of subdirectories of /, and the list of all filesystems, and match the two lists. */ DIR *dirp; struct rootdir_entry { char *name; dev_t dev; ino_t ino; struct rootdir_entry *next; }; struct rootdir_entry *rootdir_list; struct rootdir_entry **rootdir_tail; int32 pos; dev_t dev; fs_info fi; /* All volumes are mounted in the rootfs, directly under /. */ rootdir_list = NULL; rootdir_tail = &rootdir_list; dirp = opendir ("/"); if (dirp) { struct dirent *d; while ((d = readdir (dirp)) != NULL) { char *name; struct stat statbuf; if (strcmp (d->d_name, "..") == 0) continue; if (strcmp (d->d_name, ".") == 0) name = xstrdup ("/"); else { name = xmalloc (1 + strlen (d->d_name) + 1); name[0] = '/'; strcpy (name + 1, d->d_name); } if (lstat (name, &statbuf) >= 0 && S_ISDIR (statbuf.st_mode)) { struct rootdir_entry *re; re = (struct rootdir_entry *) xmalloc (sizeof (struct rootdir_entry)); re->name = name; re->dev = statbuf.st_dev; re->ino = statbuf.st_ino; /* Add to the linked list. */ *rootdir_tail = re; rootdir_tail = &re->next; } else free (name); } closedir (dirp); } *rootdir_tail = NULL; for (pos = 0; (dev = next_dev (&pos)) >= 0; ) if (fs_stat_dev (dev, &fi) >= 0) { /* Note: fi.dev == dev. */ struct rootdir_entry *re; for (re = rootdir_list; re; re = re->next) if (re->dev == fi.dev && re->ino == fi.root) break; me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry)); me->me_devname = xstrdup (fi.device_name[0] != '\0' ? fi.device_name : fi.fsh_name); me->me_mountdir = xstrdup (re != NULL ? re->name : fi.fsh_name); me->me_type = xstrdup (fi.fsh_name); me->me_dev = fi.dev; me->me_dummy = 0; me->me_remote = (fi.flags & B_FS_IS_SHARED) != 0; /* Add to the linked list. */ *mtail = me; mtail = &me->me_next; } *mtail = NULL; while (rootdir_list != NULL) { struct rootdir_entry *re = rootdir_list; rootdir_list = re->next; free (re->name); free (re); } } #endif /* MOUNTED_FS_STAT_DEV */ #if defined (MOUNTED_GETFSSTAT) /* __alpha running OSF_1 */ { int numsys, counter, bufsize; struct statfs *stats; numsys = getfsstat ((struct statfs *)0, 0L, MNT_WAIT); if (numsys < 0) return (NULL); bufsize = (1 + numsys) * sizeof (struct statfs); stats = (struct statfs *)xmalloc (bufsize); numsys = getfsstat (stats, bufsize, MNT_WAIT); if (numsys < 0) { free (stats); return (NULL); } for (counter = 0; counter < numsys; counter++) { me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry)); me->me_devname = xstrdup (stats[counter].f_mntfromname); me->me_mountdir = xstrdup (stats[counter].f_mntonname); me->me_type = mnt_names[stats[counter].f_type]; me->me_dummy = ME_DUMMY (me->me_devname, me->me_type); me->me_remote = ME_REMOTE (me->me_devname, me->me_type); me->me_dev = (dev_t) -1; /* Magic; means not known yet. */ /* Add to the linked list. */ *mtail = me; mtail = &me->me_next; } free (stats); } #endif /* MOUNTED_GETFSSTAT */ #if defined (MOUNTED_FREAD) || defined (MOUNTED_FREAD_FSTYP) /* SVR[23]. */ { struct mnttab mnt; char *table = "/etc/mnttab"; FILE *fp; fp = fopen (table, "r"); if (fp == NULL) return NULL; while (fread (&mnt, sizeof mnt, 1, fp) > 0) { me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry)); # ifdef GETFSTYP /* SVR3. */ me->me_devname = xstrdup (mnt.mt_dev); # else me->me_devname = xmalloc (strlen (mnt.mt_dev) + 6); strcpy (me->me_devname, "/dev/"); strcpy (me->me_devname + 5, mnt.mt_dev); # endif me->me_mountdir = xstrdup (mnt.mt_filsys); me->me_dev = (dev_t) -1; /* Magic; means not known yet. */ me->me_type = ""; # ifdef GETFSTYP /* SVR3. */ if (need_fs_type) { struct statfs fsd; char typebuf[FSTYPSZ]; if (statfs (me->me_mountdir, &fsd, sizeof fsd, 0) != -1 && sysfs (GETFSTYP, fsd.f_fstyp, typebuf) != -1) me->me_type = xstrdup (typebuf); } # endif me->me_dummy = ME_DUMMY (me->me_devname, me->me_type); me->me_remote = ME_REMOTE (me->me_devname, me->me_type); /* Add to the linked list. */ *mtail = me; mtail = &me->me_next; } if (ferror (fp)) { int saved_errno = errno; fclose (fp); errno = saved_errno; goto free_then_fail; } if (fclose (fp) == EOF) goto free_then_fail; } #endif /* MOUNTED_FREAD || MOUNTED_FREAD_FSTYP. */ #ifdef MOUNTED_GETMNTTBL /* DolphinOS goes it's own way */ { struct mntent **mnttbl=getmnttbl(),**ent; for (ent=mnttbl;*ent;ent++) { me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry)); me->me_devname = xstrdup ( (*ent)->mt_resource); me->me_mountdir = xstrdup( (*ent)->mt_directory); me->me_type = xstrdup ((*ent)->mt_fstype); me->me_dummy = ME_DUMMY (me->me_devname, me->me_type); me->me_remote = ME_REMOTE (me->me_devname, me->me_type); me->me_dev = (dev_t) -1; /* Magic; means not known yet. */ /* Add to the linked list. */ *mtail = me; mtail = &me->me_next; } endmnttbl(); } #endif #ifdef MOUNTED_GETMNTENT2 /* SVR4. */ { struct mnttab mnt; char *table = MNTTAB; FILE *fp; int ret; int lockfd = -1; # if defined F_RDLCK && defined F_SETLKW /* MNTTAB_LOCK is a macro name of our own invention; it's not present in e.g. Solaris 2.6. If the SVR4 folks ever define a macro for this file name, we should use their macro name instead. (Why not just lock MNTTAB directly? We don't know.) */ # ifndef MNTTAB_LOCK # define MNTTAB_LOCK "/etc/.mnttab.lock" # endif lockfd = open (MNTTAB_LOCK, O_RDONLY); if (0 <= lockfd) { struct flock flock; flock.l_type = F_RDLCK; flock.l_whence = SEEK_SET; flock.l_start = 0; flock.l_len = 0; while (fcntl (lockfd, F_SETLKW, &flock) == -1) if (errno != EINTR) { int saved_errno = errno; close (lockfd); errno = saved_errno; return NULL; } } else if (errno != ENOENT) return NULL; # endif errno = 0; fp = fopen (table, "r"); if (fp == NULL) ret = errno; else { while ((ret = getmntent (fp, &mnt)) == 0) { me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry)); me->me_devname = xstrdup (mnt.mnt_special); me->me_mountdir = xstrdup (mnt.mnt_mountp); me->me_type = xstrdup (mnt.mnt_fstype); me->me_dummy = MNT_IGNORE (&mnt) != 0; me->me_remote = ME_REMOTE (me->me_devname, me->me_type); me->me_dev = (dev_t) -1; /* Magic; means not known yet. */ /* Add to the linked list. */ *mtail = me; mtail = &me->me_next; } ret = fclose (fp) == EOF ? errno : 0 < ret ? 0 : -1; } if (0 <= lockfd && close (lockfd) != 0) ret = errno; if (0 <= ret) { errno = ret; goto free_then_fail; } } #endif /* MOUNTED_GETMNTENT2. */ #ifdef MOUNTED_VMOUNT /* AIX. */ { int bufsize; char *entries, *thisent; struct vmount *vmp; /* Ask how many bytes to allocate for the mounted filesystem info. */ mntctl (MCTL_QUERY, sizeof bufsize, (struct vmount *) &bufsize); entries = xmalloc (bufsize); /* Get the list of mounted filesystems. */ mntctl (MCTL_QUERY, bufsize, (struct vmount *) entries); for (thisent = entries; thisent < entries + bufsize; thisent += vmp->vmt_length) { char *options, *ignore; vmp = (struct vmount *) thisent; me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry)); if (vmp->vmt_flags & MNT_REMOTE) { char *host, *path; me->me_remote = 1; /* Prepend the remote pathname. */ host = thisent + vmp->vmt_data[VMT_HOSTNAME].vmt_off; path = thisent + vmp->vmt_data[VMT_OBJECT].vmt_off; me->me_devname = xmalloc (strlen (host) + strlen (path) + 2); strcpy (me->me_devname, host); strcat (me->me_devname, ":"); strcat (me->me_devname, path); } else { me->me_remote = 0; me->me_devname = xstrdup (thisent + vmp->vmt_data[VMT_OBJECT].vmt_off); } me->me_mountdir = xstrdup (thisent + vmp->vmt_data[VMT_STUB].vmt_off); me->me_type = xstrdup (fstype_to_string (vmp->vmt_gfstype)); options = thisent + vmp->vmt_data[VMT_ARGS].vmt_off; ignore = strstr (options, "ignore"); me->me_dummy = (ignore && (ignore == options || ignore[-1] == ',') && (ignore[sizeof "ignore" - 1] == ',' || ignore[sizeof "ignore" - 1] == '\0')); me->me_dev = (dev_t) -1; /* vmt_fsid might be the info we want. */ /* Add to the linked list. */ *mtail = me; mtail = &me->me_next; } free (entries); } #endif /* MOUNTED_VMOUNT. */ *mtail = NULL; return mount_list; free_then_fail: { int saved_errno = errno; *mtail = NULL; while (mount_list) { me = mount_list->me_next; free (mount_list->me_devname); free (mount_list->me_mountdir); /* FIXME: me_type is not always malloced. */ free (mount_list); mount_list = me; } errno = saved_errno; return NULL; } }
/* * Given a full path to a file, translate into a dataset name and a relative * path within the dataset. 'dataset' must be at least MAXNAMELEN characters, * and 'relpath' must be at least MAXPATHLEN characters. We also pass a stat * buffer, which we need later to get the object ID. */ static int parse_pathname(const char *inpath, char *dataset, char *relpath, struct stat *statbuf) { struct extmnttab mp; FILE *fp; int match; const char *rel; char fullpath[MAXPATHLEN]; compress_slashes(inpath, fullpath); if (fullpath[0] != '/') { (void) fprintf(stderr, "invalid object '%s': must be full " "path\n", fullpath); usage(); return (-1); } if (strlen(fullpath) >= MAXPATHLEN) { (void) fprintf(stderr, "invalid object; pathname too long\n"); return (-1); } if (stat(fullpath, statbuf) != 0) { (void) fprintf(stderr, "cannot open '%s': %s\n", fullpath, strerror(errno)); return (-1); } #ifdef HAVE_SETMNTENT if ((fp = setmntent(MNTTAB, "r")) == NULL) { #else if ((fp = fopen(MNTTAB, "r")) == NULL) { #endif (void) fprintf(stderr, "cannot open /etc/mtab\n"); return (-1); } match = 0; while (getextmntent(fp, &mp, sizeof (mp)) == 0) { if (makedev(mp.mnt_major, mp.mnt_minor) == statbuf->st_dev) { match = 1; break; } } if (!match) { (void) fprintf(stderr, "cannot find mountpoint for '%s'\n", fullpath); return (-1); } if (strcmp(mp.mnt_fstype, MNTTYPE_ZFS) != 0) { (void) fprintf(stderr, "invalid path '%s': not a ZFS " "filesystem\n", fullpath); return (-1); } if (strncmp(fullpath, mp.mnt_mountp, strlen(mp.mnt_mountp)) != 0) { (void) fprintf(stderr, "invalid path '%s': mountpoint " "doesn't match path\n", fullpath); return (-1); } (void) strcpy(dataset, mp.mnt_special); rel = fullpath + strlen(mp.mnt_mountp); if (rel[0] == '/') rel++; (void) strcpy(relpath, rel); return (0); } #endif //From FreeBSD static int parse_pathname(const char *inpath, char *dataset, char *relpath, struct stat *statbuf) { struct statfs sfs; const char *rel; char fullpath[MAXPATHLEN]; compress_slashes(inpath, fullpath); if (fullpath[0] != '/') { (void) fprintf(stderr, "invalid object '%s': must be full " "path\n", fullpath); usage(); return (-1); } if (strlen(fullpath) >= MAXPATHLEN) { (void) fprintf(stderr, "invalid object; pathname too long\n"); return (-1); } if (stat(fullpath, statbuf) != 0) { (void) fprintf(stderr, "cannot open '%s': %s\n", fullpath, strerror(errno)); return (-1); } if (statfs(fullpath, &sfs) == -1) { (void) fprintf(stderr, "cannot find mountpoint for '%s': %s\n", fullpath, strerror(errno)); return (-1); } if (strcmp(sfs.f_fstypename, MNTTYPE_ZFS) != 0) { (void) fprintf(stderr, "invalid path '%s': not a ZFS " "filesystem\n", fullpath); return (-1); } if (strncmp(fullpath, sfs.f_mntonname, strlen(sfs.f_mntonname)) != 0) { (void) fprintf(stderr, "invalid path '%s': mountpoint " "doesn't match path\n", fullpath); return (-1); } (void) strcpy(dataset, sfs.f_mntfromname); rel = fullpath + strlen(sfs.f_mntonname); if (rel[0] == '/') rel++; (void) strcpy(relpath, rel); return (0); } /* * Convert from a (dataset, path) pair into a (objset, object) pair. Note that * we grab the object number from the inode number, since looking this up via * libzpool is a real pain. */ /* ARGSUSED */ static int object_from_path(const char *dataset, const char *path, struct stat *statbuf, zinject_record_t *record) { objset_t *os; int err; /* * Before doing any libzpool operations, call sync() to ensure that the * on-disk state is consistent with the in-core state. */ sync(); err = dmu_objset_own(dataset, DMU_OST_ZFS, B_TRUE, B_FALSE, FTAG, &os); if (err != 0) { (void) fprintf(stderr, "cannot open dataset '%s': %s\n", dataset, strerror(err)); return (-1); } record->zi_objset = dmu_objset_id(os); record->zi_object = statbuf->st_ino; dmu_objset_disown(os, B_FALSE, FTAG); return (0); }
static void winCheckMount(void) { FILE *mnt; struct mntent *ent; enum { none = 0, sys_root, user_root, sys_tmp, user_tmp } level = none, curlevel; BOOL binary = TRUE; mnt = setmntent("/etc/mtab", "r"); if (mnt == NULL) { ErrorF("setmntent failed"); return; } while ((ent = getmntent(mnt)) != NULL) { BOOL system = (winCheckMntOpt(ent, "user") != NULL); BOOL root = (strcmp(ent->mnt_dir, "/") == 0); BOOL tmp = (strcmp(ent->mnt_dir, "/tmp") == 0); if (system) { if (root) curlevel = sys_root; else if (tmp) curlevel = sys_tmp; else continue; } else { if (root) curlevel = user_root; else if (tmp) curlevel = user_tmp; else continue; } if (curlevel <= level) continue; level = curlevel; if ((winCheckMntOpt(ent, "binary") == NULL) && (winCheckMntOpt(ent, "binmode") == NULL)) binary = FALSE; else binary = TRUE; } if (endmntent(mnt) != 1) { ErrorF("endmntent failed"); return; } if (!binary) winMsg(X_WARNING, "/tmp mounted in textmode\n"); }
int ecryptfs_mount(char *source, char *target, unsigned long flags, char *opts) { FILE *mtab_fd = NULL; struct mntent mountent; #if 1 // sw.yoo_20120110 - realpath 사용 포맷을 바꿈 char fullpath_source[PATH_MAX]; char fullpath_target[PATH_MAX]; #else char *fullpath_source = NULL; char *fullpath_target = NULL; #endif int rc; printf("[eCryptfs]:source=%s, target=%s, opts = %s, %s, %d \n", source, target, opts, __FUNCTION__, __LINE__); //sw.yoo_201120110 - debug print mountent.mnt_opts = NULL; if (!source) { rc = -EINVAL; syslog(LOG_ERR, "Invalid source directory\n"); goto out; } printf("[eCryptfs]: %s, %d \n", __FUNCTION__, __LINE__); //sw.yoo_201120110 - debug print if (!target) { rc = -EINVAL; syslog(LOG_ERR, "Invalid target directory\n"); goto out; } printf("[eCryptfs]: %s, %d \n", __FUNCTION__, __LINE__); //sw.yoo_201120110 - debug print if (strlen(opts) > 200) { rc = -EINVAL; syslog(LOG_ERR, "Invalid mount options length\n"); goto out; } printf("[eCryptfs]: %s, %d \n", __FUNCTION__, __LINE__); //sw.yoo_201120110 - debug print #if 1 // sw.yoo_20120110 - realpath 사용 포맷을 바꿈 if (!realpath(source, fullpath_source)) { rc = -errno; syslog(LOG_ERR, "could not resolve full path for source %s [%d]", source, -errno); goto out; } #else fullpath_source = realpath(source, NULL); if (!fullpath_source) { rc = -errno; syslog(LOG_ERR, "could not resolve full path for source %s [%d]", source, -errno); goto out; } #endif printf("[eCryptfs]: %s, %d \n", __FUNCTION__, __LINE__); //sw.yoo_201120110 - debug print #if 1 // sw.yoo_20120110 - realpath 사용 포맷을 바꿈 if (!realpath(target, fullpath_target)) { rc = -errno; syslog(LOG_ERR, "could not resolve full path for target %s [%d]", target, -errno); goto out; } #else fullpath_target = realpath(target, NULL); if (!fullpath_target) { rc = -errno; syslog(LOG_ERR, "could not resolve full path for target %s [%d]", target, -errno); goto out; } #endif printf("[eCryptfs]:s=%s,d=%s,flags=0x%x, opts=%s\n", fullpath_source,fullpath_target,flags,opts); //sw.yoo_201120110 - debug print if (mount(fullpath_source, fullpath_target, "ecryptfs", flags, opts)) { rc = -errno; syslog(LOG_ERR, "Failed to perform eCryptfs mount: [%m]\n"); goto out; } #if 0 //sw.yoo_20120106 - mntent.h 관련 함수 사용 막음 mtab_fd = setmntent("/etc/mtab", "a"); if (!mtab_fd) { rc = -EACCES; syslog(LOG_ERR, "Failed to update the mount table\n"); goto out; } mountent.mnt_fsname = fullpath_source; mountent.mnt_dir = fullpath_target; mountent.mnt_type = "ecryptfs"; /* we need the following byte count: * 200 max for opts * 23 max for strings below * 1 the final \0 */ mountent.mnt_opts = malloc(224); if (!mountent.mnt_opts) { rc = -ENOMEM; syslog(LOG_ERR, "Failed to allocate memory for mount " "options\n"); goto out; } memset(mountent.mnt_opts, 0, 224); /* reporting the right mount opts */ if (flags & MS_RDONLY) strcat(mountent.mnt_opts,"ro"); else strcat(mountent.mnt_opts,"rw"); if (flags & MS_NOEXEC) strcat(mountent.mnt_opts,",noexec"); if (flags & MS_NOSUID) strcat(mountent.mnt_opts,",nosuid"); if (flags & MS_NODEV) strcat(mountent.mnt_opts,",nodev"); if (opts) { strcat(mountent.mnt_opts, ","); strcat(mountent.mnt_opts, opts); } mountent.mnt_freq = 0; mountent.mnt_passno = 0; if (addmntent(mtab_fd, &mountent)) { rc = -EIO; syslog(LOG_ERR, "Failed to write to the mount " "table\n"); goto out; } #endif rc = 0; out: #if 0 free(fullpath_source); free(fullpath_target); #endif #if 0 //sw.yoo_20120106 - mntent.h 관련 함수 사용 막음 free(mountent.mnt_opts); if (mtab_fd) endmntent(mtab_fd); #endif return rc; printf("[eCryptfs]: %s, %d \n", __FUNCTION__, __LINE__); //sw.yoo_201120110 - debug print }
/* returns <0 if error */ int get_device( char *path, char *device ) { #if ( !defined( __sun ) ) FILE *tmp_streamin; char tmp_bufferin[ MAX_STRING ]; char tmp_path[ 256 ]; int l = 0; #endif #if (defined(__linux__)) struct mntent* lmount_entry; #endif #if ( defined( __sun ) ) FILE *mnttab_fp; char *mnt_special; int mntcheck; char *new_device; #endif char *pointer; char *k; bool mounted = FALSE; #ifdef USE_STATFS_FOR_DEV struct statfs buf; #endif #ifdef USE_STATVFS_FOR_DEV struct statvfs buf; #endif /* the string should have no trailing / */ if( path[ ( strlen( path ) - 1 ) ] == '/' ) { path[ ( strlen( path ) - 1 ) ] = '\0' ; } /* remove video_ts if given */ if( ( pointer = strstr( path, "/video_ts" ) ) || ( pointer = strstr( path, "/VIDEO_TS" ) ) ) { *pointer = '\0'; } /* check if it is given as /dev/xxx already */ if( strstr( path, "/dev/" ) ) { strcpy( device, path ); } else { /* *look through /etc/mtab to see if it's actually mounted */ #if ( defined( USE_STATFS_FOR_DEV ) || defined( USE_STATVFS_FOR_DEV ) ) #ifdef USE_STATFS_FOR_DEV if( !statfs( path, &buf ) ) #else if( !statvfs( path, &buf ) ) #endif { if( !strcmp( path, buf.f_mntonname ) ) { mounted = TRUE; #if defined(__FreeBSD__) && (__FreeBSD_Version > 500000) strcpy(device, buf.f_mntfromname); #else strcpy(device, "/dev/r"); strcat(device, buf.f_mntfromname + 5); #endif return mounted; } strcpy(device, buf.f_mntfromname); } else { fprintf( stderr, _("[Error] Error while reading filesystem info") ); return -1; } #elif ( defined( __sun ) ) struct mnttab mount_entry; int mntcheck; if ( ( mnttab_fp = fopen( "/etc/mnttab", "r" ) ) == NULL ) { fprintf( stderr, _(" [Error] Could not open mnttab for searching!\n") ); fprintf( stderr, _(" [Error] error: %s\n"), strerror( errno ) ); return -1; } while ( ( mntcheck = getmntent( mnttab_fp, &mount_entry ) ) == 0 ) { /* check to see if our path is this entry */ if ( strcmp( path, mount_entry.mnt_mountp ) == 0 ) { char *new_device, *mnt_special; if ( strstr( mount_entry.mnt_special, "/dsk/" ) == NULL ) { fprintf( stderr, _("[Error] %s doesn't look like a disk device to me"), mount_entry.mnt_special ); return -1; } /* we actually want the raw device name */ mnt_special = malloc( strlen( mount_entry.mnt_special ) + 1 ); new_device = malloc( strlen( mount_entry.mnt_special ) + 2 ); strcpy( mnt_special, mount_entry.mnt_special ); strcpy( new_device, mnt_special ); strcpy( strstr( new_device, "/dsk/" ), "" ); strcat( new_device, "/rdsk/" ); strcat( new_device, strstr( mnt_special, "/dsk/" ) + strlen( "/dsk/" ) ); strncpy( device, new_device, sizeof(device)-1 ); free( mnt_special ); free( new_device ); mounted = TRUE; break; } } if ( mntcheck > 0 ) { fprintf( stderr, _("[Error] Encountered error in reading mnttab file\n") ); fprintf( stderr, _("[Error] error: %s\n"), strerror( errno ) ); return -1; } else if ( mntcheck == -1 ) { fprintf( stderr, _("[Error] Did not find mount %s in mnttab!\n"), path ); return -1; } #else /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this is the code for the other-OSs, not solaris*/ #if (defined(__linux__)) if ((tmp_streamin = setmntent("/etc/mtab", "r"))){ while ((lmount_entry = getmntent(tmp_streamin))){ if (strcmp(lmount_entry->mnt_dir, path) == 0){ /* Found the mount point */ fprintf ( stderr, "[Info] Device %s mounted on %s\n", lmount_entry->mnt_fsname, lmount_entry->mnt_dir); strcpy(device, lmount_entry->mnt_fsname); mounted = TRUE; break; } } endmntent(tmp_streamin); if (mounted) { /* device was set from /etc/mtab, no need to further check * /etc/fstab */ return mounted; } } #endif if( ( tmp_streamin = fopen( "/etc/mtab", "r" ) ) ) { strcpy( tmp_path, path ); strcat( tmp_path, " " ); /* otherwise it would detect that e.g. /cdrom is mounted even if only/cdrom1 is mounted */ memset( tmp_bufferin, 0, MAX_STRING * sizeof( char ) ); while( fgets( tmp_bufferin, MAX_STRING, tmp_streamin )) { if( strstr( tmp_bufferin, tmp_path ) ) { mounted = TRUE; } } fclose( tmp_streamin ); } else { fprintf( stderr, _("[Error] Could not read /etc/mtab!\n") ); fprintf( stderr, _("[Error] error: %s\n"), strerror( errno ) ); return -1; } #endif #if defined( __sun ) } #else /* *read the device out of /etc/fstab */ if( ( tmp_streamin = fopen( "/etc/fstab", "r" ) ) ) { strcpy(tmp_path, path); memset( tmp_bufferin, 0, MAX_STRING * sizeof( char ) ); while( fgets( tmp_bufferin, MAX_STRING, tmp_streamin ) ) { if( ( pointer = strstr( tmp_bufferin, tmp_path ) ) ) { if( isgraph( ( int ) *( pointer + strlen( tmp_path ) ) ) ) break; /* there is something behind the path name, for instance like it would find /cdrom but also /cdrom1 since /cdrom is a subset of /cdrom1 */ /*isblank should work too but how do you do that with the "gnu extension"? (man isblank) */ if( ( k = strstr( tmp_bufferin, "/dev/" ) ) == NULL ) { fprintf( stderr, _("[Error] Weird, no /dev/ entry found in the line where iso9660 or udf gets mentioned in /etc/fstab\n") ); return -1; } l=0; while( isgraph( (int) *(k) ) ) { device[l] = *(k); if( device[l] == ',' ) break; l++; k++; } if( isdigit( ( int) device[l-1] ) ) { if( strstr( device, "hd" ) ) fprintf( stderr, _("[Hint] Hmm, the last char in the device path (%s) that gets mounted to %s is a number.\n"), device, path); } device[l] = '\0'; } memset( tmp_bufferin, 0, MAX_STRING * sizeof( char ) ); } fclose( tmp_streamin ); if( !strstr( device, "/dev" ) ) { fprintf( stderr, _("[Error] Could not find the provided path (%s), typo?\n"),path); device[0] = '\0'; return -1; } } else { fprintf( stderr, _("[Error] Could not read /etc/fstab!") ); fprintf( stderr, _("[Error] error: %s\n"), strerror( errno ) ); device[0] = '\0'; return -1; } }
/** * build the export entry */ fsal_status_t GPFSFSAL_BuildExportContext(fsal_export_context_t *export_context, /* OUT */ fsal_path_t * p_export_path, /* IN */ char *fs_specific_options /* IN */ ) { int rc, fd, mntexists; FILE * fp; struct mntent * p_mnt; char * mnt_dir = NULL; struct statfs stat_buf; gpfs_fsal_up_ctx_t * gpfs_fsal_up_ctx; bool_t start_fsal_up_thread = FALSE; fsal_status_t status; fsal_op_context_t op_context; gpfsfsal_export_context_t *p_export_context = (gpfsfsal_export_context_t *)export_context; /* Make sure the FSAL UP context list is initialized */ if(glist_null(&gpfs_fsal_up_ctx_list)) init_glist(&gpfs_fsal_up_ctx_list); /* sanity check */ if((p_export_context == NULL) || (p_export_path == NULL)) { LogCrit(COMPONENT_FSAL, "NULL mandatory argument passed to %s()", __FUNCTION__); Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_BuildExportContext); } /* open mnt file */ fp = setmntent(MOUNTED, "r"); if(fp == NULL) { rc = errno; LogCrit(COMPONENT_FSAL, "Error %d in setmntent(%s): %s", rc, MOUNTED, strerror(rc)); Return(posix2fsal_error(rc), rc, INDEX_FSAL_BuildExportContext); } /* Check if mount point is really a gpfs share. If not, we can't continue.*/ mntexists = 0; while((p_mnt = getmntent(fp)) != NULL) if(p_mnt->mnt_dir != NULL && p_mnt->mnt_type != NULL) /* There is probably a macro for "gpfs" type ... not sure where it is. */ if (strncmp(p_mnt->mnt_type, "gpfs", 4) == 0) { LogFullDebug(COMPONENT_FSAL, "Checking Export Path %s against GPFS fs %s", p_export_path->path, p_mnt->mnt_dir); /* If export path is shorter than fs path, then this isn't a match */ if(strlen(p_export_path->path) < strlen(p_mnt->mnt_dir)) continue; /* If export path doesn't have a path separator after mnt_dir, then it * isn't a proper sub-directory of mnt_dir. */ if((p_export_path->path[strlen(p_mnt->mnt_dir)] != '/') && (p_export_path->path[strlen(p_mnt->mnt_dir)] != '\0')) continue; if (strncmp(p_mnt->mnt_dir, p_export_path->path, strlen(p_mnt->mnt_dir)) == 0) { mnt_dir = gsh_strdup(p_mnt->mnt_dir); mntexists = 1; break; } } endmntent(fp); if (mntexists == 0) { LogMajor(COMPONENT_FSAL, "GPFS mount point %s does not exist.", p_export_path->path); gsh_free(mnt_dir); ReturnCode(ERR_FSAL_INVAL, 0); } /* save file descriptor to root of GPFS share */ fd = open(p_export_path->path, O_RDONLY | O_DIRECTORY); if(fd < 0) { if(errno == ENOENT) LogMajor(COMPONENT_FSAL, "GPFS export path %s does not exist.", p_export_path->path); else if (errno == ENOTDIR) LogMajor(COMPONENT_FSAL, "GPFS export path %s is not a directory.", p_export_path->path); else LogMajor(COMPONENT_FSAL, "Could not open GPFS export path %s: rc = %d(%s)", p_export_path->path, errno, strerror(errno)); if(mnt_dir != NULL) gsh_free(mnt_dir); ReturnCode(ERR_FSAL_INVAL, 0); } p_export_context->mount_root_fd = fd; LogFullDebug(COMPONENT_FSAL, "GPFSFSAL_BuildExportContext: %d", p_export_context->mount_root_fd); /* Save pointer to fsal_staticfsinfo_t in export context */ p_export_context->fe_static_fs_info = &global_fs_info; /* save filesystem ID */ rc = statfs(p_export_path->path, &stat_buf); if(rc) { close(fd); LogMajor(COMPONENT_FSAL, "statfs call failed on file %s: %d(%s)", p_export_path->path, errno, strerror(errno)); if(mnt_dir != NULL) gsh_free(mnt_dir); ReturnCode(ERR_FSAL_INVAL, 0); } p_export_context->fsid[0] = stat_buf.f_fsid.__val[0]; p_export_context->fsid[1] = stat_buf.f_fsid.__val[1]; /* save file handle to root of GPFS share */ op_context.export_context = export_context; // op_context.credential = ??? status = fsal_internal_get_handle(&op_context, p_export_path, (fsal_handle_t *)(&(p_export_context->mount_root_handle))); if(FSAL_IS_ERROR(status)) { close(p_export_context->mount_root_fd); LogMajor(COMPONENT_FSAL, "FSAL BUILD EXPORT CONTEXT: ERROR: Conversion from gpfs filesystem root path to handle failed : %d", status.minor); if(mnt_dir != NULL) gsh_free(mnt_dir); ReturnCode(ERR_FSAL_INVAL, 0); } gpfs_fsal_up_ctx = gpfsfsal_find_fsal_up_context(p_export_context); if(gpfs_fsal_up_ctx == NULL) { gpfs_fsal_up_ctx = gsh_calloc(1, sizeof(gpfs_fsal_up_ctx_t)); if(gpfs_fsal_up_ctx == NULL || mnt_dir == NULL) { LogFatal(COMPONENT_FSAL, "Out of memory can not continue."); } /* Initialize the gpfs_fsal_up_ctx */ init_glist(&gpfs_fsal_up_ctx->gf_exports); gpfs_fsal_up_ctx->gf_fs = mnt_dir; gpfs_fsal_up_ctx->gf_fsid[0] = p_export_context->fsid[0]; gpfs_fsal_up_ctx->gf_fsid[1] = p_export_context->fsid[1]; /* Add it to the list of contexts */ glist_add_tail(&gpfs_fsal_up_ctx_list, &gpfs_fsal_up_ctx->gf_list); start_fsal_up_thread = TRUE; } else { if(mnt_dir != NULL) gsh_free(mnt_dir); } /* Add this export context to the list for it's gpfs_fsal_up_ctx */ glist_add_tail(&gpfs_fsal_up_ctx->gf_exports, &p_export_context->fe_list); p_export_context->fe_fsal_up_ctx = gpfs_fsal_up_ctx; if(start_fsal_up_thread) { pthread_attr_t attr_thr; memset(&attr_thr, 0, sizeof(attr_thr)); /* Initialization of thread attributes borrowed from nfs_init.c */ if(pthread_attr_init(&attr_thr) != 0) LogCrit(COMPONENT_THREAD, "can't init pthread's attributes"); if(pthread_attr_setscope(&attr_thr, PTHREAD_SCOPE_SYSTEM) != 0) LogCrit(COMPONENT_THREAD, "can't set pthread's scope"); if(pthread_attr_setdetachstate(&attr_thr, PTHREAD_CREATE_JOINABLE) != 0) LogCrit(COMPONENT_THREAD, "can't set pthread's join state"); if(pthread_attr_setstacksize(&attr_thr, 2116488) != 0) LogCrit(COMPONENT_THREAD, "can't set pthread's stack size"); rc = pthread_create(&gpfs_fsal_up_ctx->gf_thread, &attr_thr, GPFSFSAL_UP_Thread, gpfs_fsal_up_ctx); if(rc != 0) { LogFatal(COMPONENT_THREAD, "Could not create GPFSFSAL_UP_Thread, error = %d (%s)", errno, strerror(errno)); } } Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_BuildExportContext); }
RTR3DECL(int) RTFsQueryType(const char *pszFsPath, PRTFSTYPE penmType) { *penmType = RTFSTYPE_UNKNOWN; /* * Validate input. */ AssertPtrReturn(pszFsPath, VERR_INVALID_POINTER); AssertReturn(*pszFsPath, VERR_INVALID_PARAMETER); /* * Convert the path and query the stats. * We're simply return the device id. */ char const *pszNativeFsPath; int rc = rtPathToNative(&pszNativeFsPath, pszFsPath, NULL); if (RT_SUCCESS(rc)) { struct stat Stat; if (!stat(pszNativeFsPath, &Stat)) { #if defined(RT_OS_LINUX) FILE *mounted = setmntent("/proc/mounts", "r"); if (!mounted) mounted = setmntent("/etc/mtab", "r"); if (mounted) { char szBuf[1024]; struct stat mntStat; struct mntent mntEnt; while (getmntent_r(mounted, &mntEnt, szBuf, sizeof(szBuf))) { if (!stat(mntEnt.mnt_dir, &mntStat)) { if (mntStat.st_dev == Stat.st_dev) { if (!strcmp("ext4", mntEnt.mnt_type)) *penmType = RTFSTYPE_EXT4; else if (!strcmp("ext3", mntEnt.mnt_type)) *penmType = RTFSTYPE_EXT3; else if (!strcmp("ext2", mntEnt.mnt_type)) *penmType = RTFSTYPE_EXT2; else if (!strcmp("jfs", mntEnt.mnt_type)) *penmType = RTFSTYPE_JFS; else if (!strcmp("xfs", mntEnt.mnt_type)) *penmType = RTFSTYPE_XFS; else if (!strcmp("btrfs", mntEnt.mnt_type)) *penmType = RTFSTYPE_BTRFS; else if ( !strcmp("vfat", mntEnt.mnt_type) || !strcmp("msdos", mntEnt.mnt_type)) *penmType = RTFSTYPE_FAT; else if (!strcmp("ntfs", mntEnt.mnt_type)) *penmType = RTFSTYPE_NTFS; else if (!strcmp("hpfs", mntEnt.mnt_type)) *penmType = RTFSTYPE_HPFS; else if (!strcmp("ufs", mntEnt.mnt_type)) *penmType = RTFSTYPE_UFS; else if (!strcmp("tmpfs", mntEnt.mnt_type)) *penmType = RTFSTYPE_TMPFS; else if (!strcmp("hfsplus", mntEnt.mnt_type)) *penmType = RTFSTYPE_HFS; else if (!strcmp("udf", mntEnt.mnt_type)) *penmType = RTFSTYPE_UDF; else if (!strcmp("iso9660", mntEnt.mnt_type)) *penmType = RTFSTYPE_ISO9660; else if (!strcmp("smbfs", mntEnt.mnt_type)) *penmType = RTFSTYPE_SMBFS; else if (!strcmp("cifs", mntEnt.mnt_type)) *penmType = RTFSTYPE_CIFS; else if (!strcmp("nfs", mntEnt.mnt_type)) *penmType = RTFSTYPE_NFS; else if (!strcmp("nfs4", mntEnt.mnt_type)) *penmType = RTFSTYPE_NFS; else if (!strcmp("ocfs2", mntEnt.mnt_type)) *penmType = RTFSTYPE_OCFS2; else if (!strcmp("sysfs", mntEnt.mnt_type)) *penmType = RTFSTYPE_SYSFS; else if (!strcmp("proc", mntEnt.mnt_type)) *penmType = RTFSTYPE_PROC; else if ( !strcmp("fuse", mntEnt.mnt_type) || !strncmp("fuse.", mntEnt.mnt_type, 5) || !strcmp("fuseblk", mntEnt.mnt_type)) *penmType = RTFSTYPE_FUSE; else { /* sometimes there are more than one entry for the same partition */ continue; } break; } } } endmntent(mounted); } #elif defined(RT_OS_SOLARIS) if (!strcmp("zfs", Stat.st_fstype)) *penmType = RTFSTYPE_ZFS; else if (!strcmp("ufs", Stat.st_fstype)) *penmType = RTFSTYPE_UFS; else if (!strcmp("nfs", Stat.st_fstype)) *penmType = RTFSTYPE_NFS; #elif defined(RT_OS_DARWIN) || defined(RT_OS_FREEBSD) struct statfs statfsBuf; if (!statfs(pszNativeFsPath, &statfsBuf)) { if (!strcmp("hfs", statfsBuf.f_fstypename)) *penmType = RTFSTYPE_HFS; else if ( !strcmp("fat", statfsBuf.f_fstypename) || !strcmp("msdos", statfsBuf.f_fstypename)) *penmType = RTFSTYPE_FAT; else if (!strcmp("ntfs", statfsBuf.f_fstypename)) *penmType = RTFSTYPE_NTFS; else if (!strcmp("autofs", statfsBuf.f_fstypename)) *penmType = RTFSTYPE_AUTOFS; else if (!strcmp("devfs", statfsBuf.f_fstypename)) *penmType = RTFSTYPE_DEVFS; else if (!strcmp("nfs", statfsBuf.f_fstypename)) *penmType = RTFSTYPE_NFS; else if (!strcmp("ufs", statfsBuf.f_fstypename)) *penmType = RTFSTYPE_UFS; else if (!strcmp("zfs", statfsBuf.f_fstypename)) *penmType = RTFSTYPE_ZFS; } else rc = RTErrConvertFromErrno(errno); #endif } else rc = RTErrConvertFromErrno(errno); rtPathFreeNative(pszNativeFsPath, pszFsPath); } return rc; }
BOOL disk_quotas(const char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize) { uid_t euser_id; int r; struct dqblk D; struct fs_disk_quota F; SMB_STRUCT_STAT S; FILE *fp; struct mntent *mnt; SMB_DEV_T devno; int found; /* find the block device file */ if ( sys_stat(path, &S) == -1 ) { return(False) ; } devno = S.st_dev ; fp = setmntent(MOUNTED,"r"); found = False ; while ((mnt = getmntent(fp))) { if ( sys_stat(mnt->mnt_dir,&S) == -1 ) continue ; if (S.st_dev == devno) { found = True ; break ; } } endmntent(fp) ; if (!found) { return(False); } euser_id=geteuid(); save_re_uid(); set_effective_uid(0); /* Use softlimit to determine disk space, except when it has been exceeded */ *bsize = 512; if ( 0 == strcmp ( mnt->mnt_type, "efs" )) { r=quotactl (Q_GETQUOTA, mnt->mnt_fsname, euser_id, (caddr_t) &D); restore_re_uid(); if (r==-1) return(False); /* Use softlimit to determine disk space, except when it has been exceeded */ if ( (D.dqb_bsoftlimit && D.dqb_curblocks>=D.dqb_bsoftlimit) || (D.dqb_bhardlimit && D.dqb_curblocks>=D.dqb_bhardlimit) || (D.dqb_fsoftlimit && D.dqb_curfiles>=D.dqb_fsoftlimit) || (D.dqb_fhardlimit && D.dqb_curfiles>=D.dqb_fhardlimit) ) { *dfree = 0; *dsize = D.dqb_curblocks; } else if (D.dqb_bsoftlimit==0 && D.dqb_bhardlimit==0) { return(False); } else { *dfree = D.dqb_bsoftlimit - D.dqb_curblocks; *dsize = D.dqb_bsoftlimit; } } else if ( 0 == strcmp ( mnt->mnt_type, "xfs" )) { r=quotactl (Q_XGETQUOTA, mnt->mnt_fsname, euser_id, (caddr_t) &F); restore_re_uid(); if (r==-1) return(False); /* Use softlimit to determine disk space, except when it has been exceeded */ if ( (F.d_blk_softlimit && F.d_bcount>=F.d_blk_softlimit) || (F.d_blk_hardlimit && F.d_bcount>=F.d_blk_hardlimit) || (F.d_ino_softlimit && F.d_icount>=F.d_ino_softlimit) || (F.d_ino_hardlimit && F.d_icount>=F.d_ino_hardlimit) ) { *dfree = 0; *dsize = F.d_bcount; } else if (F.d_blk_softlimit==0 && F.d_blk_hardlimit==0) { return(False); } else { *dfree = (F.d_blk_softlimit - F.d_bcount); *dsize = F.d_blk_softlimit; } } else { restore_re_uid(); return(False); } return (True); }
static int may_unmount(const char *mnt, int quiet) { struct mntent *entp; FILE *fp; const char *user = NULL; char uidstr[32]; unsigned uidlen = 0; int found; const char *mtab = _PATH_MOUNTED; user = get_user_name(); if (user == NULL) return -1; fp = setmntent(mtab, "r"); if (fp == NULL) { fprintf(stderr, "%s: failed to open %s: %s\n", progname, mtab, strerror(errno)); return -1; } uidlen = sprintf(uidstr, "%u", getuid()); found = 0; while ((entp = getmntent(fp)) != NULL) { if (!found && strcmp(entp->mnt_dir, mnt) == 0 && (strcmp(entp->mnt_type, "fuse") == 0 || strcmp(entp->mnt_type, "fuseblk") == 0 || strncmp(entp->mnt_type, "fuse.", 5) == 0 || strncmp(entp->mnt_type, "fuseblk.", 8) == 0)) { char *p = strstr(entp->mnt_opts, "user="******"user_id=")) && (p == entp->mnt_opts || *(p-1) == ',') && strncmp(p + 8, uidstr, uidlen) == 0 && (*(p+8+uidlen) == ',' || *(p+8+uidlen) == '\0')) { found = 1; break; } } } endmntent(fp); if (!found) { if (!quiet) fprintf(stderr, "%s: entry for %s not found in %s\n", progname, mnt, mtab); return -1; } return 0; }
BOOL disk_quotas(const char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize) { struct mntent *mnt; FILE *fd; SMB_STRUCT_STAT sbuf; SMB_DEV_T devno ; static SMB_DEV_T devno_cached = 0 ; static pstring name; struct q_request request ; struct qf_header header ; static int quota_default = 0 ; int found ; if ( sys_stat(path,&sbuf) == -1 ) return(False) ; devno = sbuf.st_dev ; if ( devno != devno_cached ) { devno_cached = devno ; if ((fd = setmntent(KMTAB)) == NULL) return(False) ; found = False ; while ((mnt = getmntent(fd)) != NULL) { if ( sys_stat(mnt->mnt_dir,&sbuf) == -1 ) continue ; if (sbuf.st_dev == devno) { found = True ; break ; } } pstrcpy(name,mnt->mnt_dir) ; endmntent(fd) ; if ( ! found ) return(False) ; } request.qf_magic = QF_MAGIC ; request.qf_entry.id = geteuid() ; if (quotactl(name, Q_GETQUOTA, &request) == -1) return(False) ; if ( ! request.user ) return(False) ; if ( request.qf_entry.user_q.f_quota == QFV_DEFAULT ) { if ( ! quota_default ) { if ( quotactl(name, Q_GETHEADER, &header) == -1 ) return(False) ; else quota_default = header.user_h.def_fq ; } *dfree = quota_default ; }else if ( request.qf_entry.user_q.f_quota == QFV_PREVENT ) { *dfree = 0 ; }else{ *dfree = request.qf_entry.user_q.f_quota ; } *dsize = request.qf_entry.user_q.f_use ; if ( *dfree < *dsize ) *dfree = 0 ; else *dfree -= *dsize ; *bsize = 4096 ; /* Cray blocksize */ return(True) ; }
BOOL disk_quotas(const char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize) { uid_t euser_id; int ret; struct dqblk D; #if defined(SUNOS5) struct quotctl command; int file; static struct mnttab mnt; static pstring name; pstring devopt; #else /* SunOS4 */ struct mntent *mnt; static pstring name; #endif FILE *fd; SMB_STRUCT_STAT sbuf; SMB_DEV_T devno ; static SMB_DEV_T devno_cached = 0 ; static int found ; euser_id = geteuid(); if ( sys_stat(path,&sbuf) == -1 ) return(False) ; devno = sbuf.st_dev ; DEBUG(5,("disk_quotas: looking for path \"%s\" devno=%x\n", path,(unsigned int)devno)); if ( devno != devno_cached ) { devno_cached = devno ; #if defined(SUNOS5) if ((fd = sys_fopen(MNTTAB, "r")) == NULL) return(False) ; found = False ; slprintf(devopt, sizeof(devopt) - 1, "dev=%x", (unsigned int)devno); while (getmntent(fd, &mnt) == 0) { if( !hasmntopt(&mnt, devopt) ) continue; DEBUG(5,("disk_quotas: testing \"%s\" %s\n", mnt.mnt_mountp,devopt)); /* quotas are only on vxfs, UFS or NFS */ if ( strcmp( mnt.mnt_fstype, MNTTYPE_UFS ) == 0 || strcmp( mnt.mnt_fstype, "nfs" ) == 0 || strcmp( mnt.mnt_fstype, "vxfs" ) == 0 ) { found = True ; break; } } pstrcpy(name,mnt.mnt_mountp) ; pstrcat(name,"/quotas") ; fclose(fd) ; #else /* SunOS4 */ if ((fd = setmntent(MOUNTED, "r")) == NULL) return(False) ; found = False ; while ((mnt = getmntent(fd)) != NULL) { if ( sys_stat(mnt->mnt_dir,&sbuf) == -1 ) continue ; DEBUG(5,("disk_quotas: testing \"%s\" devno=%x\n", mnt->mnt_dir,(unsigned int)sbuf.st_dev)); if (sbuf.st_dev == devno) { found = True ; break; } } pstrcpy(name,mnt->mnt_fsname) ; endmntent(fd) ; #endif } if ( ! found ) return(False) ; save_re_uid(); set_effective_uid(0); #if defined(SUNOS5) if ( strcmp( mnt.mnt_fstype, "nfs" ) == 0) { BOOL retval; DEBUG(5,("disk_quotas: looking for mountpath (NFS) \"%s\"\n", mnt.mnt_special)); retval = nfs_quotas(mnt.mnt_special, euser_id, bsize, dfree, dsize); restore_re_uid(); return retval; } DEBUG(5,("disk_quotas: looking for quotas file \"%s\"\n", name)); if((file=sys_open(name, O_RDONLY,0))<0) { restore_re_uid(); return(False); } command.op = Q_GETQUOTA; command.uid = euser_id; command.addr = (caddr_t) &D; ret = ioctl(file, Q_QUOTACTL, &command); close(file); #else DEBUG(5,("disk_quotas: trying quotactl on device \"%s\"\n", name)); ret = quotactl(Q_GETQUOTA, name, euser_id, &D); #endif restore_re_uid(); if (ret < 0) { DEBUG(5,("disk_quotas ioctl (Solaris) failed. Error = %s\n", strerror(errno) )); #if defined(SUNOS5) && defined(VXFS_QUOTA) /* If normal quotactl() fails, try vxfs private calls */ set_effective_uid(euser_id); DEBUG(5,("disk_quotas: mount type \"%s\"\n", mnt.mnt_fstype)); if ( 0 == strcmp ( mnt.mnt_fstype, "vxfs" )) { BOOL retval; retval = disk_quotas_vxfs(name, path, bsize, dfree, dsize); return(retval); } #else return(False); #endif } /* If softlimit is zero, set it equal to hardlimit. */ if (D.dqb_bsoftlimit==0) D.dqb_bsoftlimit = D.dqb_bhardlimit; /* Use softlimit to determine disk space. A user exceeding the quota is told * that there's no space left. Writes might actually work for a bit if the * hardlimit is set higher than softlimit. Effectively the disk becomes * made of rubber latex and begins to expand to accommodate the user :-) */ if (D.dqb_bsoftlimit==0) return(False); *bsize = DEV_BSIZE; *dsize = D.dqb_bsoftlimit; if (D.dqb_curblocks > D.dqb_bsoftlimit) { *dfree = 0; *dsize = D.dqb_curblocks; } else *dfree = D.dqb_bsoftlimit - D.dqb_curblocks; DEBUG(5,("disk_quotas for path \"%s\" returning bsize %.0f, dfree %.0f, dsize %.0f\n", path,(double)*bsize,(double)*dfree,(double)*dsize)); return(True); }
BOOL disk_quotas(const char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize) { int r; SMB_STRUCT_STAT S; FILE *fp; LINUX_SMB_DISK_QUOTA D; struct mntent *mnt; SMB_DEV_T devno; int found; uid_t euser_id; euser_id = geteuid(); /* find the block device file */ if ( sys_stat(path, &S) == -1 ) return(False) ; devno = S.st_dev ; fp = setmntent(MOUNTED,"r"); found = False ; while ((mnt = getmntent(fp))) { if ( sys_stat(mnt->mnt_dir,&S) == -1 ) continue ; if (S.st_dev == devno) { found = True ; break; } } endmntent(fp) ; if (!found) return(False); save_re_uid(); set_effective_uid(0); if (strcmp(mnt->mnt_type, "xfs")) { r=get_smb_linux_gen_quota(mnt->mnt_fsname, euser_id, &D); if (r == -1) { r=get_smb_linux_v2_quota(mnt->mnt_fsname, euser_id, &D); if (r == -1) r=get_smb_linux_v1_quota(mnt->mnt_fsname, euser_id, &D); } } else { r=get_smb_linux_xfs_quota(mnt->mnt_fsname, euser_id, &D); } restore_re_uid(); /* Use softlimit to determine disk space, except when it has been exceeded */ *bsize = D.bsize; if (r == -1) { if (errno == EDQUOT) { *dfree =0; *dsize =D.curblocks; return (True); } else { return(False); } } /* Use softlimit to determine disk space, except when it has been exceeded */ if ( (D.softlimit && D.curblocks >= D.softlimit) || (D.hardlimit && D.curblocks >= D.hardlimit) || (D.isoftlimit && D.curinodes >= D.isoftlimit) || (D.ihardlimit && D.curinodes>=D.ihardlimit) ) { *dfree = 0; *dsize = D.curblocks; } else if (D.softlimit==0 && D.hardlimit==0) { return(False); } else { if (D.softlimit == 0) D.softlimit = D.hardlimit; *dfree = D.softlimit - D.curblocks; *dsize = D.softlimit; } return (True); }
static bool below_threshold(struct statfs buf, const char *prefix_type, const char *threshold_type, const double low_threshold) { #else static bool below_threshold(struct statvfs buf, const char *prefix_type, const char *threshold_type, const double low_threshold) { #endif if (strcasecmp(threshold_type, "percentage_free") == 0) { return 100.0 * (double)buf.f_bfree / (double)buf.f_blocks < low_threshold; } else if (strcasecmp(threshold_type, "percentage_avail") == 0) { return 100.0 * (double)buf.f_bavail / (double)buf.f_blocks < low_threshold; } else if (strcasecmp(threshold_type, "bytes_free") == 0) { return (double)buf.f_bsize * (double)buf.f_bfree < low_threshold; } else if (strcasecmp(threshold_type, "bytes_avail") == 0) { return (double)buf.f_bsize * (double)buf.f_bavail < low_threshold; } else if (threshold_type[0] != '\0' && strncasecmp(threshold_type + 1, "bytes_", strlen("bytes_")) == 0) { uint64_t base = strcasecmp(prefix_type, "decimal") == 0 ? DECIMAL_BASE : BINARY_BASE; double factor = 1; switch (threshold_type[0]) { case 'T': case 't': factor *= base; case 'G': case 'g': factor *= base; case 'M': case 'm': factor *= base; case 'K': case 'k': factor *= base; break; default: return false; } if (strcasecmp(threshold_type + 1, "bytes_free") == 0) { return (double)buf.f_bsize * (double)buf.f_bfree < low_threshold * factor; } else if (strcasecmp(threshold_type + 1, "bytes_avail") == 0) { return (double)buf.f_bsize * (double)buf.f_bavail < low_threshold * factor; } } return false; } /* * Does a statvfs and prints either free, used or total amounts of bytes in a * human readable manner. * */ void print_disk_info(yajl_gen json_gen, char *buffer, const char *path, const char *format, const char *format_not_mounted, const char *prefix_type, const char *threshold_type, const double low_threshold) { const char *walk; char *outwalk = buffer; bool colorful_output = false; INSTANCE(path); #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__OpenBSD__) || defined(__DragonFly__) || defined(__APPLE__) struct statfs buf; if (statfs(path, &buf) == -1) return; #else struct statvfs buf; if (statvfs(path, &buf) == -1) { /* If statvfs errors, e.g., due to the path not existing, * we use the format for a not mounted device. */ format = format_not_mounted; } else if (format_not_mounted != NULL) { FILE *mntentfile = setmntent("/etc/mtab", "r"); struct mntent *m; bool found = false; while ((m = getmntent(mntentfile)) != NULL) { if (strcmp(m->mnt_dir, path) == 0) { found = true; break; } } endmntent(mntentfile); if (!found) { format = format_not_mounted; } } #endif if (low_threshold > 0 && below_threshold(buf, prefix_type, threshold_type, low_threshold)) { START_COLOR("color_bad"); colorful_output = true; } for (walk = format; *walk != '\0'; walk++) { if (*walk != '%') { *(outwalk++) = *walk; continue; } if (BEGINS_WITH(walk + 1, "free")) { outwalk += print_bytes_human(outwalk, (uint64_t)buf.f_bsize * (uint64_t)buf.f_bfree, prefix_type); walk += strlen("free"); } if (BEGINS_WITH(walk + 1, "used")) { outwalk += print_bytes_human(outwalk, (uint64_t)buf.f_bsize * ((uint64_t)buf.f_blocks - (uint64_t)buf.f_bfree), prefix_type); walk += strlen("used"); } if (BEGINS_WITH(walk + 1, "total")) { outwalk += print_bytes_human(outwalk, (uint64_t)buf.f_bsize * (uint64_t)buf.f_blocks, prefix_type); walk += strlen("total"); } if (BEGINS_WITH(walk + 1, "avail")) { outwalk += print_bytes_human(outwalk, (uint64_t)buf.f_bsize * (uint64_t)buf.f_bavail, prefix_type); walk += strlen("avail"); } if (BEGINS_WITH(walk + 1, "percentage_free")) { outwalk += sprintf(outwalk, "%.01f%s", 100.0 * (double)buf.f_bfree / (double)buf.f_blocks, pct_mark); walk += strlen("percentage_free"); } if (BEGINS_WITH(walk + 1, "percentage_used_of_avail")) { outwalk += sprintf(outwalk, "%.01f%s", 100.0 * (double)(buf.f_blocks - buf.f_bavail) / (double)buf.f_blocks, pct_mark); walk += strlen("percentage_used_of_avail"); } if (BEGINS_WITH(walk + 1, "percentage_used")) { outwalk += sprintf(outwalk, "%.01f%s", 100.0 * (double)(buf.f_blocks - buf.f_bfree) / (double)buf.f_blocks, pct_mark); walk += strlen("percentage_used"); } if (BEGINS_WITH(walk + 1, "percentage_avail")) { outwalk += sprintf(outwalk, "%.01f%s", 100.0 * (double)buf.f_bavail / (double)buf.f_blocks, pct_mark); walk += strlen("percentage_avail"); } } if (colorful_output) END_COLOR; *outwalk = '\0'; OUTPUT_FULL_TEXT(buffer); }
static int remove_from_mtab(char * mountpoint) { int rc; int num_matches; FILE * org_fd; FILE * new_fd; struct mntent * mount_entry; /* Do we need to check if it is a symlink to e.g. /proc/mounts in which case we probably do not want to update it? */ /* Do we first need to check if it is writable? */ atexit(unlock_mtab); if (lock_mtab()) { printf("Mount table locked\n"); return -EACCES; } if(verboseflg) printf("attempting to remove from mtab\n"); org_fd = setmntent(MOUNTED, "r"); if(org_fd == NULL) { printf("Can not open %s\n",MOUNTED); unlock_mtab(); return -EIO; } new_fd = setmntent(MOUNTED_TEMP,"w"); if(new_fd == NULL) { printf("Can not open temp file %s", MOUNTED_TEMP); endmntent(org_fd); unlock_mtab(); return -EIO; } /* BB fix so we only remove the last entry that matches BB */ num_matches = 0; while((mount_entry = getmntent(org_fd)) != NULL) { if(strcmp(mount_entry->mnt_dir, mountpoint) == 0) { num_matches++; } } if(verboseflg) printf("%d matching entries in mount table\n", num_matches); /* Is there a better way to seek back to the first entry in mtab? */ endmntent(org_fd); org_fd = setmntent(MOUNTED, "r"); if(org_fd == NULL) { printf("Can not open %s\n",MOUNTED); unlock_mtab(); return -EIO; } while((mount_entry = getmntent(org_fd)) != NULL) { if(strcmp(mount_entry->mnt_dir, mountpoint) != 0) { addmntent(new_fd, mount_entry); } else { if(num_matches != 1) { addmntent(new_fd, mount_entry); num_matches--; } else if(verboseflg) printf("entry not copied (ie entry is removed)\n"); } } if(verboseflg) printf("done updating tmp file\n"); rc = fchmod (fileno (new_fd), S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); if(rc < 0) { printf("error %s changing mode of %s\n", strerror(errno), MOUNTED_TEMP); } endmntent(new_fd); rc = rename(MOUNTED_TEMP, MOUNTED); if(rc < 0) { printf("failure %s renaming %s to %s\n",strerror(errno), MOUNTED_TEMP, MOUNTED); unlock_mtab(); return -EIO; } unlock_mtab(); return rc; }
int main(int argc, char ** argv) { int c; int flags = MS_MANDLOCK; /* no need to set legacy MS_MGC_VAL */ char * orgoptions = NULL; char * share_name = NULL; char * ipaddr = NULL; char * uuid = NULL; char * mountpoint = NULL; char * options = NULL; char * resolved_path = NULL; char * temp; int rc; int rsize = 0; int wsize = 0; int nomtab = 0; int uid = 0; int gid = 0; int optlen = 0; int orgoptlen = 0; size_t options_size = 0; int retry = 0; /* set when we have to retry mount with uppercase */ struct stat statbuf; struct utsname sysinfo; struct mntent mountent; FILE * pmntfile; /* setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); */ if(argc && argv) { thisprogram = argv[0]; } else { mount_cifs_usage(); exit(1); } if(thisprogram == NULL) thisprogram = "mount.cifs"; uname(&sysinfo); /* BB add workstation name and domain and pass down */ /* #ifdef _GNU_SOURCE printf(" node: %s machine: %s sysname %s domain %s\n", sysinfo.nodename,sysinfo.machine,sysinfo.sysname,sysinfo.domainname); #endif */ if(argc > 2) { share_name = argv[1]; mountpoint = argv[2]; } /* add sharename in opts string as unc= parm */ while ((c = getopt_long (argc, argv, "afFhilL:no:O:rsSU:vVwt:", longopts, NULL)) != -1) { switch (c) { /* No code to do the following options yet */ /* case 'l': list_with_volumelabel = 1; break; case 'L': volumelabel = optarg; break; */ /* case 'a': ++mount_all; break; */ case '?': case 'h': /* help */ mount_cifs_usage (); exit(1); case 'n': ++nomtab; break; case 'b': #ifdef MS_BIND flags |= MS_BIND; #else fprintf(stderr, "option 'b' (MS_BIND) not supported\n"); #endif break; case 'm': #ifdef MS_MOVE flags |= MS_MOVE; #else fprintf(stderr, "option 'm' (MS_MOVE) not supported\n"); #endif break; case 'o': orgoptions = strdup(optarg); break; case 'r': /* mount readonly */ flags |= MS_RDONLY; break; case 'U': uuid = optarg; break; case 'v': ++verboseflag; break; case 'V': printf ("mount.cifs version: %s.%s%s\n", MOUNT_CIFS_VERSION_MAJOR, MOUNT_CIFS_VERSION_MINOR, MOUNT_CIFS_VENDOR_SUFFIX); if(mountpassword) { memset(mountpassword,0,64); } exit (0); case 'w': flags &= ~MS_RDONLY; break; case 'R': rsize = atoi(optarg) ; break; case 'W': wsize = atoi(optarg); break; case '1': if (isdigit(*optarg)) { char *ep; uid = strtoul(optarg, &ep, 10); if (*ep) { printf("bad uid value \"%s\"\n", optarg); exit(1); } } else { struct passwd *pw; if (!(pw = getpwnam(optarg))) { printf("bad user name \"%s\"\n", optarg); exit(1); } uid = pw->pw_uid; endpwent(); } break; case '2': if (isdigit(*optarg)) { char *ep; gid = strtoul(optarg, &ep, 10); if (*ep) { printf("bad gid value \"%s\"\n", optarg); exit(1); } } else { struct group *gr; if (!(gr = getgrnam(optarg))) { printf("bad user name \"%s\"\n", optarg); exit(1); } gid = gr->gr_gid; endpwent(); } break; case 'u': got_user = 1; user_name = optarg; break; case 'd': domain_name = optarg; /* BB fix this - currently ignored */ got_domain = 1; break; case 'p': if(mountpassword == NULL) mountpassword = (char *)calloc(65,1); if(mountpassword) { got_password = 1; strncpy(mountpassword,optarg,64); } break; case 'S': get_password_from_file(0 /* stdin */,NULL); break; case 't': break; default: printf("unknown mount option %c\n",c); mount_cifs_usage(); exit(1); } } if((argc < 3) || (share_name == NULL) || (mountpoint == NULL)) { mount_cifs_usage(); exit(1); } if (getenv("PASSWD")) { if(mountpassword == NULL) mountpassword = (char *)calloc(65,1); if(mountpassword) { strncpy(mountpassword,getenv("PASSWD"),64); got_password = 1; } } else if (getenv("PASSWD_FD")) { get_password_from_file(atoi(getenv("PASSWD_FD")),NULL); } else if (getenv("PASSWD_FILE")) { get_password_from_file(0, getenv("PASSWD_FILE")); } if (orgoptions && parse_options(&orgoptions, &flags)) { rc = -1; goto mount_exit; } ipaddr = parse_server(&share_name); if((ipaddr == NULL) && (got_ip == 0)) { printf("No ip address specified and hostname not found\n"); rc = -1; goto mount_exit; } /* BB save off path and pop after mount returns? */ resolved_path = (char *)malloc(PATH_MAX+1); if(resolved_path) { /* Note that if we can not canonicalize the name, we get another chance to see if it is valid when we chdir to it */ if (realpath(mountpoint, resolved_path)) { mountpoint = resolved_path; } } if(chdir(mountpoint)) { printf("mount error: can not change directory into mount target %s\n",mountpoint); rc = -1; goto mount_exit; } if(stat (".", &statbuf)) { printf("mount error: mount point %s does not exist\n",mountpoint); rc = -1; goto mount_exit; } if (S_ISDIR(statbuf.st_mode) == 0) { printf("mount error: mount point %s is not a directory\n",mountpoint); rc = -1; goto mount_exit; } if((getuid() != 0) && (geteuid() == 0)) { if((statbuf.st_uid == getuid()) && (S_IRWXU == (statbuf.st_mode & S_IRWXU))) { #ifndef CIFS_ALLOW_USR_SUID /* Do not allow user mounts to control suid flag for mount unless explicitly built that way */ flags |= MS_NOSUID | MS_NODEV; #endif } else { printf("mount error: permission denied or not superuser and mount.cifs not installed SUID\n"); return -1; } } if(got_user == 0) { user_name = getusername(); got_user = 1; } if(got_password == 0) { char *tmp_pass; tmp_pass = getpass("Password: "******"Password not entered, exiting.\n"); return -1; } strncpy(mountpassword, tmp_pass, 64); got_password = 1; } /* FIXME launch daemon (handles dfs name resolution and credential change) remember to clear parms and overwrite password field before launching */ mount_retry: if(orgoptions) { optlen = strlen(orgoptions); orgoptlen = optlen; } else optlen = 0; if(share_name) optlen += strlen(share_name) + 4; else { printf("No server share name specified\n"); printf("\nMounting the DFS root for server not implemented yet\n"); exit(1); } if(user_name) optlen += strlen(user_name) + 6; if(ipaddr) optlen += strlen(ipaddr) + 4; if(mountpassword) optlen += strlen(mountpassword) + 6; if(options) { free(options); options = NULL; } options_size = optlen + 10 + 64; options = (char *)malloc(options_size /* space for commas in password */ + 8 /* space for domain= , domain name itself was counted as part of the length username string above */); if(options == NULL) { printf("Could not allocate memory for mount options\n"); return -1; } options[0] = 0; strlcpy(options,"unc=",options_size); strlcat(options,share_name,options_size); /* scan backwards and reverse direction of slash */ temp = strrchr(options, '/'); if(temp > options + 6) *temp = '\\'; if(ipaddr) { strlcat(options,",ip=",options_size); strlcat(options,ipaddr,options_size); } if(user_name) { /* check for syntax like user=domain\user */ if(got_domain == 0) domain_name = check_for_domain(&user_name); strlcat(options,",user="******",domain=",options_size); strlcat(options,domain_name,options_size); } } if(mountpassword) { /* Commas have to be doubled, or else they will look like the parameter separator */ /* if(sep is not set)*/ if(retry == 0) check_for_comma(&mountpassword); strlcat(options,",pass="******",ver=",options_size); strlcat(options,MOUNT_CIFS_VERSION_MAJOR,options_size); if(orgoptions) { strlcat(options,",",options_size); strlcat(options,orgoptions,options_size); } if(prefixpath) { strlcat(options,",prefixpath=",options_size); strlcat(options,prefixpath,options_size); /* no need to cat the / */ } if(verboseflag) printf("\nmount.cifs kernel mount options %s \n",options); if(mount(share_name, mountpoint, "cifs", flags, options)) { /* remember to kill daemon on error */ char * tmp; switch (errno) { case 0: printf("mount failed but no error number set\n"); break; case ENODEV: printf("mount error: cifs filesystem not supported by the system\n"); break; case ENXIO: if(retry == 0) { retry = 1; tmp = share_name; while (*tmp && !(((unsigned char)tmp[0]) & 0x80)) { *tmp = toupper((unsigned char)*tmp); tmp++; } if(!*tmp) { printf("retrying with upper case share name\n"); goto mount_retry; } } default: printf("mount error %d = %s\n",errno,strerror(errno)); } printf("Refer to the mount.cifs(8) manual page (e.g.man mount.cifs)\n"); rc = -1; goto mount_exit; } else { pmntfile = setmntent(MOUNTED, "a+"); if(pmntfile) { mountent.mnt_fsname = share_name; mountent.mnt_dir = mountpoint; mountent.mnt_type = CONST_DISCARD(char *,"cifs"); mountent.mnt_opts = (char *)malloc(220); if(mountent.mnt_opts) { char * mount_user = getusername(); memset(mountent.mnt_opts,0,200); if(flags & MS_RDONLY) strlcat(mountent.mnt_opts,"ro",220); else strlcat(mountent.mnt_opts,"rw",220); if(flags & MS_MANDLOCK) strlcat(mountent.mnt_opts,",mand",220); if(flags & MS_NOEXEC) strlcat(mountent.mnt_opts,",noexec",220); if(flags & MS_NOSUID) strlcat(mountent.mnt_opts,",nosuid",220); if(flags & MS_NODEV) strlcat(mountent.mnt_opts,",nodev",220); if(flags & MS_SYNCHRONOUS) strlcat(mountent.mnt_opts,",synch",220); if(mount_user) { if(getuid() != 0) { strlcat(mountent.mnt_opts,",user="******"could not update mount table\n"); } }
/* * Check whether the file specified in "fusermount -u" is really a * mountpoint and not a symlink. This is necessary otherwise the user * could move the mountpoint away and replace it with a symlink * pointing to an arbitrary mount, thereby tricking fusermount into * unmounting that (umount(2) will follow symlinks). * * This is the child process running in a separate mount namespace, so * we don't mess with the global namespace and if the process is * killed for any reason, mounts are automatically cleaned up. * * First make sure nothing is propagated back into the parent * namespace by marking all mounts "private". * * Then bind mount parent onto a stable base where the user can't move * it around. * * Finally check /proc/mounts for an entry matching the requested * mountpoint. If it's found then we are OK, and the user can't move * it around within the parent directory as rename() will return * EBUSY. Be careful to ignore any mounts that existed before the * bind. */ static int check_is_mount_child(void *p) { const char **a = p; const char *last = a[0]; const char *mnt = a[1]; int res; const char *procmounts = "/proc/mounts"; int found; FILE *fp; struct mntent *entp; int count; res = mount("", "/", "", MS_PRIVATE | MS_REC, NULL); if (res == -1) { fprintf(stderr, "%s: failed to mark mounts private: %s\n", progname, strerror(errno)); return 1; } fp = setmntent(procmounts, "r"); if (fp == NULL) { fprintf(stderr, "%s: failed to open %s: %s\n", progname, procmounts, strerror(errno)); return 1; } count = 0; while ((entp = getmntent(fp)) != NULL) count++; endmntent(fp); fp = setmntent(procmounts, "r"); if (fp == NULL) { fprintf(stderr, "%s: failed to open %s: %s\n", progname, procmounts, strerror(errno)); return 1; } res = mount(".", "/", "", MS_BIND | MS_REC, NULL); if (res == -1) { fprintf(stderr, "%s: failed to bind parent to /: %s\n", progname, strerror(errno)); return 1; } found = 0; while ((entp = getmntent(fp)) != NULL) { if (count > 0) { count--; continue; } if (entp->mnt_dir[0] == '/' && strcmp(entp->mnt_dir + 1, last) == 0) { found = 1; break; } } endmntent(fp); if (!found) { fprintf(stderr, "%s: %s not mounted\n", progname, mnt); return 1; } return 0; }
void sensorMonitor_adv_common_fillSensorTopic ( xme_core_component_config_t* const componentConfig ) { sensorMonitor_adv_sensorB_sensorBComponent_config_t* config = (sensorMonitor_adv_sensorB_sensorBComponent_config_t*) componentConfig; #ifndef WIN32 // Linux implementation int driveCount = 0; int selectedDrive = 0; FILE* fp; struct mntent *ent; fp = setmntent("/etc/mtab", "r"); while ((ent = getmntent(fp)) != NULL) { if (strcmp(ent->mnt_fsname, "none") == 0 || strcmp(ent->mnt_fsname, "sysfs") == 0 || strcmp(ent->mnt_fsname, "proc") == 0 || strcmp(ent->mnt_fsname, "gvfs-fuse-daemon") == 0 || strcmp(ent->mnt_fsname, "devpts") == 0) { // Ignore this partition continue; } // List this partition XME_LOG(XME_LOG_ALWAYS, "[%d] %s %s\n", driveCount++, ent->mnt_dir, ent->mnt_type); } endmntent(fp); do { XME_LOG(XME_LOG_ALWAYS, "Which partition do you wish to monitor? [0-%d]: ", driveCount-1); if (!scanf("%d", &selectedDrive)) { selectedDrive = -1; } } while (selectedDrive < 0 || selectedDrive> driveCount-1); driveCount = 0; fp = setmntent("/etc/mtab", "r"); while ((ent = getmntent(fp)) != NULL) { if (strcmp(ent->mnt_fsname, "none") == 0 || strcmp(ent->mnt_fsname, "sysfs") == 0 || strcmp(ent->mnt_fsname, "proc") == 0 || strcmp(ent->mnt_fsname, "gvfs-fuse-daemon") == 0 || strcmp(ent->mnt_fsname, "devpts") == 0) { // Ignore this partition continue; } // Check for matching drive if (driveCount++ == selectedDrive) { xme_hal_safeString_strncpy(config->sensorInstance, ent->mnt_dir, sizeof(config->sensorInstance)); break; } } endmntent(fp); #else // #ifndef WIN32 // Windows implementation char szBuffer[1024]; int driveCount = 0; int selectedDrive = 0; unsigned int i; DWORD length; length = GetLogicalDriveStrings(1024, (LPTSTR)szBuffer); XME_CHECK_MSG(0 != length, XME_CHECK_RVAL_VOID, XME_LOG_ERROR, "GetLogicalDriveStrings() failed: %d\n", GetLastError()); XME_LOG(XME_LOG_ALWAYS, "The logical drives of this machine are:\n"); for (i = 0U; i < length;) { if (szBuffer[i] != 0) { UINT type = GetDriveType((LPCSTR)(&szBuffer[i])); if (DRIVE_REMOVABLE != type && DRIVE_FIXED != type && DRIVE_RAMDISK != type) { // Ignore this drive i += strlen(&szBuffer[i]) + 1U; continue; } // List this drive XME_LOG(XME_LOG_ALWAYS, "[%d] : %s\n", driveCount++, (LPTSTR)(&szBuffer[i])); i += strlen(&szBuffer[i]) + 1U; } if (0 == szBuffer[i+1]) { i++; } } do { XME_LOG(XME_LOG_ALWAYS, "\nWhich drive do you wish to monitor? [0-%d]: ", driveCount-1); scanf_s("%d", &selectedDrive); } while (selectedDrive < 0 || selectedDrive > driveCount-1); XME_LOG(XME_LOG_ALWAYS, "\n"); driveCount = 0; for (i = 0; i < length;) { if (szBuffer[i] != 0) { UINT type = GetDriveType((LPCSTR)(&szBuffer[i])); if (DRIVE_REMOVABLE != type && DRIVE_FIXED != type && DRIVE_RAMDISK != type) { // Ignore this drive i += strlen(&szBuffer[i]) + 1; continue; } // Check for matching drive if(driveCount++ == selectedDrive) { xme_hal_safeString_strncpy(config->sensorInstance, (LPTSTR)(&szBuffer[i]), sizeof(config->sensorInstance)); break; } i += strlen(&szBuffer[i]) + 1; } if (0 == szBuffer[i+1]) { i++; } } #endif // #ifndef WIN32 }
int gp_port_library_list (GPPortInfoList *list) { GPPortInfo info; # ifdef HAVE_MNTENT_H FILE *mnt; struct mntent *mntent; char path[1024]; char *s; struct stat stbuf; mnt = setmntent ("/etc/fstab", "r"); if (mnt) { while ((mntent = getmntent (mnt))) { /* detect floppies so we don't access them with the stat() below */ GP_LOG_D ("found fstab fsname %s", mntent->mnt_fsname); if ((NULL != strstr(mntent->mnt_fsname,"fd")) || (NULL != strstr(mntent->mnt_fsname,"floppy")) || (NULL != strstr(mntent->mnt_fsname,"fuse")) || (NULL != strstr(mntent->mnt_fsname,"nfs")) || (NULL != strstr(mntent->mnt_fsname,"cifs")) || (NULL != strstr(mntent->mnt_fsname,"smbfs"))|| (NULL != strstr(mntent->mnt_fsname,"afs")) || (NULL != strstr(mntent->mnt_fsname,"autofs"))|| (NULL != strstr(mntent->mnt_fsname,"cgroup"))|| (NULL != strstr(mntent->mnt_fsname,"systemd"))|| (NULL != strstr(mntent->mnt_fsname,"mqueue"))|| (NULL != strstr(mntent->mnt_fsname,"securityfs"))|| (NULL != strstr(mntent->mnt_fsname,"proc"))|| (NULL != strstr(mntent->mnt_fsname,"devtmpfs"))|| (NULL != strstr(mntent->mnt_fsname,"devpts"))|| (NULL != strstr(mntent->mnt_fsname,"sysfs"))|| (NULL != strstr(mntent->mnt_fsname,"gphotofs")|| /* fstype based */ (NULL != strstr(mntent->mnt_type,"autofs")) || (NULL != strstr(mntent->mnt_type,"nfs")) || (NULL != strstr(mntent->mnt_type,"smbfs"))|| (NULL != strstr(mntent->mnt_type,"proc"))|| (NULL != strstr(mntent->mnt_type,"sysfs"))|| (NULL != strstr(mntent->mnt_type,"fuse"))|| (NULL != strstr(mntent->mnt_type,"cifs"))|| (NULL != strstr(mntent->mnt_type,"afs")) || /* mount options */ /* x-systemd.automount or similar */ (NULL != strstr(mntent->mnt_opts,"automount")) ) ) { continue; } snprintf (path, sizeof(path), "%s/DCIM", mntent->mnt_dir); if (-1 == stat(path, &stbuf)) { snprintf (path, sizeof(path), "%s/dcim", mntent->mnt_dir); if (-1 == stat(path, &stbuf)) continue; } s = malloc (strlen(_("Media '%s'"))+strlen(mntent->mnt_fsname)+1); sprintf (s, _("Media '%s'"), mntent->mnt_fsname); gp_port_info_new (&info); gp_port_info_set_type (info, GP_PORT_DISK); gp_port_info_set_name (info, s); free (s); s = malloc (strlen("disk:")+strlen(mntent->mnt_dir)+1); sprintf (s, "disk:%s", mntent->mnt_dir); gp_port_info_set_path (info, s); if (gp_port_info_list_lookup_path (list, s) >= GP_OK) { free (s); continue; } free(s); CHECK (gp_port_info_list_append (list, info)); } endmntent(mnt); } mnt = setmntent ("/etc/mtab", "r"); if (mnt) { while ((mntent = getmntent (mnt))) { /* detect floppies so we don't access them with the stat() below */ GP_LOG_D ("found mtab fsname %s", mntent->mnt_fsname); if ((NULL != strstr(mntent->mnt_fsname,"fd")) || (NULL != strstr(mntent->mnt_fsname,"floppy")) || (NULL != strstr(mntent->mnt_fsname,"fuse")) || (NULL != strstr(mntent->mnt_fsname,"nfs")) || (NULL != strstr(mntent->mnt_fsname,"cifs")) || (NULL != strstr(mntent->mnt_fsname,"smbfs"))|| (NULL != strstr(mntent->mnt_fsname,"afs")) || (NULL != strstr(mntent->mnt_fsname,"autofs"))|| (NULL != strstr(mntent->mnt_fsname,"cgroup"))|| (NULL != strstr(mntent->mnt_fsname,"systemd"))|| (NULL != strstr(mntent->mnt_fsname,"mqueue"))|| (NULL != strstr(mntent->mnt_fsname,"securityfs"))|| (NULL != strstr(mntent->mnt_fsname,"proc"))|| (NULL != strstr(mntent->mnt_fsname,"devtmpfs"))|| (NULL != strstr(mntent->mnt_fsname,"devpts"))|| (NULL != strstr(mntent->mnt_fsname,"sysfs"))|| (NULL != strstr(mntent->mnt_fsname,"gphotofs"))|| /* fstype based */ (NULL != strstr(mntent->mnt_type,"autofs")) || (NULL != strstr(mntent->mnt_type,"nfs")) || (NULL != strstr(mntent->mnt_type,"smbfs"))|| (NULL != strstr(mntent->mnt_type,"proc"))|| (NULL != strstr(mntent->mnt_type,"sysfs"))|| (NULL != strstr(mntent->mnt_type,"fuse"))|| (NULL != strstr(mntent->mnt_type,"cifs"))|| (NULL != strstr(mntent->mnt_type,"afs")) || /* options */ (NULL != strstr(mntent->mnt_opts,"automount")) ) { continue; } snprintf (path, sizeof(path), "%s/DCIM", mntent->mnt_dir); if (-1 == stat(path, &stbuf)) { snprintf (path, sizeof(path), "%s/dcim", mntent->mnt_dir); if (-1 == stat(path, &stbuf)) continue; } /* automount should be blacklist here, but we still need * to look it up first otherwise the automounted camera * won't appear. */ if (NULL != strstr(mntent->mnt_fsname, "automount")) { continue; } gp_port_info_new (&info); gp_port_info_set_type (info, GP_PORT_DISK); s = malloc (strlen(_("Media '%s'"))+strlen(mntent->mnt_fsname)+1); sprintf (s, _("Media '%s'"), mntent->mnt_fsname); gp_port_info_set_name (info, s); free (s); s = malloc (strlen("disk:")+strlen(mntent->mnt_dir)+1); sprintf (s, "disk:%s", mntent->mnt_dir); gp_port_info_set_path (info, s); if (gp_port_info_list_lookup_path (list, s) >= GP_OK) { free (s); continue; } free (s); CHECK (gp_port_info_list_append (list, info)); } endmntent(mnt); } # else # ifdef HAVE_MNTTAB FILE *mnt; struct mnttab mnttab; char path[1024]; struct stat stbuf; info.type = GP_PORT_DISK; mnt = fopen ("/etc/fstab", "r"); if (mnt) { while (! getmntent (mnt, &mntent)) { /* detect floppies so we don't access them with the stat() below */ if ( (NULL != strstr(mnttab.mnt_special,"fd")) || (NULL != strstr(mnttab.mnt_special,"floppy")) ) continue; snprintf (path, sizeof(path), "%s/DCIM", mnttab.mnt_mountp); if (-1 == stat(path, &stbuf)) { snprintf (path, sizeof(path), "%s/dcim", mnttab.mnt_mountp); if (-1 == stat(path, &stbuf)) continue; } snprintf (info.name, sizeof(info.name), _("Media '%s'"), mntent.mnt_special), snprintf (info.path, sizeof(info.path), "disk:%s", mntent.mnt_mountp); if (gp_port_info_list_lookup_path (list, info.path) >= GP_OK) continue; CHECK (gp_port_info_list_append (list, info)); } fclose(mnt); } mnt = fopen ("/etc/mtab", "r"); if (mnt) { while (! getmntent (mnt, &mntent)) { /* detect floppies so we don't access them with the stat() below */ if ( (NULL != strstr(mnttab.mnt_special,"fd")) || (NULL != strstr(mnttab.mnt_special,"floppy")) ) continue; snprintf (path, sizeof(path), "%s/DCIM", mnttab.mnt_mountp); if (-1 == stat(path, &stbuf)) { snprintf (path, sizeof(path), "%s/dcim", mnttab.mnt_mountp); if (-1 == stat(path, &stbuf)) continue; } snprintf (info.name, sizeof(info.name), _("Media '%s'"), mntent.mnt_special), snprintf (info.path, sizeof(info.path), "disk:%s", mntent.mnt_mountp); if (gp_port_info_list_lookup_path (list, info.path) >= GP_OK) continue; CHECK (gp_port_info_list_append (list, info)); } fclose(mnt); } # endif # endif /* generic disk:/xxx/ matcher */ gp_port_info_new (&info); gp_port_info_set_type (info, GP_PORT_DISK); gp_port_info_set_name (info, ""); gp_port_info_set_path (info, "^disk:"); CHECK (gp_port_info_list_append (list, info)); return GP_OK; }
static int HandleMTab(char *cacheMountDir) { #if (defined (AFS_HPUX_ENV) || defined(AFS_SGI_ENV) || defined(AFS_LINUX20_ENV)) FILE *tfilep; #if defined(AFS_SGI_ENV) || defined(AFS_LINUX20_ENV) struct mntent tmntent; char *dir; int i; tfilep = setmntent("/etc/mtab", "a+"); if (!tfilep) { printf("Can't open /etc/mtab for writing (errno %d); not adding " "an entry for AFS\n", errno); return 1; } dir = strdup(cacheMountDir); /* trim trailing slashes; don't look at dir[0] in case we are somehow * just "/" */ for (i = strlen(dir)-1; i > 0; i--) { if (dir[i] == '/') { dir[i] = '\0'; } else { break; } } tmntent.mnt_fsname = "AFS"; tmntent.mnt_dir = dir; tmntent.mnt_type = "afs"; tmntent.mnt_opts = "rw"; tmntent.mnt_freq = 1; tmntent.mnt_passno = 3; addmntent(tfilep, &tmntent); endmntent(tfilep); free(dir); dir = NULL; #else struct mntent tmntent; memset(&tmntent, '\0', sizeof(struct mntent)); tfilep = setmntent(MOUNTED_TABLE, "a+"); if (!tfilep) { printf("Can't open %s for write; Not adding afs entry to it\n", MOUNTED_TABLE); return 1; } tmntent.mnt_fsname = "AFS"; tmntent.mnt_dir = cacheMountDir; tmntent.mnt_type = "xx"; tmntent.mnt_opts = "rw"; tmntent.mnt_freq = 1; tmntent.mnt_passno = 3; #ifdef AFS_HPUX_ENV tmntent.mnt_type = "afs"; tmntent.mnt_time = time(0); tmntent.mnt_cnode = 0; #endif addmntent(tfilep, &tmntent); endmntent(tfilep); #endif /* AFS_SGI_ENV */ #endif /* unreasonable systems */ #ifdef AFS_DARWIN_ENV #ifndef AFS_DARWIN100_ENV mach_port_t diskarb_port; kern_return_t status; status = DiskArbStart(&diskarb_port); if (status == KERN_SUCCESS) { status = DiskArbDiskAppearedWithMountpointPing_auto("AFS", DISK_ARB_NETWORK_DISK_FLAG, cacheMountDir); } return status; #endif #endif /* AFS_DARWIN_ENV */ return 0; }
int main(int argc, char **argv) { #ifdef HAVE_FHANDLE_SYSCALLS char *filename, *file, *mount_point = NULL, *readbuf = NULL; int ret, rc = -EINVAL, mnt_id, mnt_fd, fd1, fd2, i, len, offset; struct file_handle *fh = NULL; int file_size, mtime, ctime; struct lu_fid *parent, *fid; struct mntent *ent; struct stat st; __ino_t inode; FILE *mntpt; if (argc != 2) usage(argv[0]); file = argv[1]; if (file[0] != '/') { fprintf(stderr, "Need the absolete path of the file\n"); goto out; } fd1 = open(file, O_RDONLY); if (fd1 < 0) { fprintf(stderr, "open file %s error: %s\n", file, strerror(errno)); rc = errno; goto out; } /* Get file stats using fd1 from traditional open */ bzero(&st, sizeof(struct stat)); rc = fstat(fd1, &st); if (rc < 0) { fprintf(stderr, "fstat(%s) error: %s\n", file, strerror(errno)); rc = errno; goto out_fd1; } inode = st.st_ino; mtime = st.st_mtime; ctime = st.st_ctime; file_size = st.st_size; /* Now for the setup to use fhandles */ mntpt = setmntent("/etc/mtab", "r"); if (mntpt == NULL) { fprintf(stderr, "setmntent error: %s\n", strerror(errno)); rc = errno; goto out_fd1; } while (NULL != (ent = getmntent(mntpt))) { if ((strncmp(file, ent->mnt_dir, strlen(ent->mnt_dir)) == 0) && (strcmp(ent->mnt_type, "lustre") == 0)) { mount_point = ent->mnt_dir; break; } } endmntent(mntpt); if (mount_point == NULL) { fprintf(stderr, "file is not located on a lustre file " "system?\n"); goto out_fd1; } filename = rindex(file, '/') + 1; /* Open mount point directory */ mnt_fd = open(mount_point, O_DIRECTORY); if (mnt_fd < 0) { fprintf(stderr, "open(%s) error: %s\n)", mount_point, strerror(errno)); rc = errno; goto out_fd1; } /* Allocate memory for file handle */ fh = malloc(sizeof(struct file_handle) + MAX_HANDLE_SZ); if (!fh) { fprintf(stderr, "malloc(%d) error: %s\n", MAX_HANDLE_SZ, strerror(errno)); rc = errno; goto out_mnt_fd; } fh->handle_bytes = MAX_HANDLE_SZ; /* Convert name to handle */ ret = name_to_handle_at(mnt_fd, filename, fh, &mnt_id, AT_SYMLINK_FOLLOW); if (ret) { fprintf(stderr, "name_by_handle_at(%s) error: %s\n", filename, strerror(errno)); rc = errno; goto out_f_handle; } /* Print out the contents of the file handle */ fprintf(stdout, "fh_bytes: %u\nfh_type: %d\nfh_data: ", fh->handle_bytes, fh->handle_type); for (i = 0; i < fh->handle_bytes; i++) fprintf(stdout, "%02x ", fh->f_handle[i]); fprintf(stdout, "\n"); /* Lustre stores both the parents FID and the file FID * in the f_handle. */ parent = (struct lu_fid *)(fh->f_handle + 16); fid = (struct lu_fid *)fh->f_handle; fprintf(stdout, "file's parent FID is "DFID"\n", PFID(parent)); fprintf(stdout, "file FID is "DFID"\n", PFID(fid)); /* Open the file handle */ fd2 = open_by_handle_at(mnt_fd, fh, O_RDONLY); if (fd2 < 0) { fprintf(stderr, "open_by_handle_at(%s) error: %s\n", filename, strerror(errno)); rc = errno; goto out_f_handle; } /* Get file size */ bzero(&st, sizeof(struct stat)); rc = fstat(fd2, &st); if (rc < 0) { fprintf(stderr, "fstat(%s) error: %s\n", filename, strerror(errno)); rc = errno; goto out_fd2; } if (ctime != st.st_ctime || file_size != st.st_size || inode != st.st_ino || mtime != st.st_mtime) { fprintf(stderr, "stat data does not match between fopen " "and fhandle case\n"); goto out_fd2; } if (st.st_size) { len = st.st_blksize; readbuf = malloc(len); if (readbuf == NULL) { fprintf(stderr, "malloc(%d) error: %s\n", len, strerror(errno)); rc = errno; goto out_fd2; } for (offset = 0; offset < st.st_size; offset += len) { /* read from the file */ rc = read(fd2, readbuf, len); if (rc < 0) { fprintf(stderr, "read(%s) error: %s\n", filename, strerror(errno)); rc = errno; goto out_readbuf; } } } rc = 0; fprintf(stdout, "check_fhandle_syscalls test Passed!\n"); out_readbuf: if (readbuf != NULL) free(readbuf); out_fd2: close(fd2); out_f_handle: free(fh); out_mnt_fd: close(mnt_fd); out_fd1: close(fd1); out: return rc; #else /* !HAVE_FHANDLE_SYSCALLS */ if (argc != 2) usage(argv[0]); fprintf(stderr, "HAVE_FHANDLE_SYSCALLS not defined\n"); return 0; #endif /* HAVE_FHANDLE_SYSCALLS */ }
void CDBoxInfoWidget::paint() { const int headSize = 5; const char *head[headSize] = {"Filesystem", "Size", "Used", "Available", "Use%"}; int fontWidth = g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->getWidth(); int sizeOffset = fontWidth * 7;//9999.99M int percOffset = fontWidth * 3 ;//100% int nameOffset = fontWidth * 9;//WWWwwwwwww int offsetw = nameOffset+ (sizeOffset+10)*3 +10+percOffset+10; offsetw += 20; width = offsetw + 10 + 120; height = hheight + 6 * mheight; struct statfs s; FILE * mountFile; struct mntent * mnt; /* this is lame, as it duplicates code. OTOH, it is small and fast enough... The algorithm is exactly the same as below in the display routine */ if ((mountFile = setmntent("/proc/mounts", "r")) == NULL) { perror("/proc/mounts"); } else { while ((mnt = getmntent(mountFile)) != NULL) { if (::statfs(mnt->mnt_dir, &s) == 0) { switch (s.f_type) /* f_type is long */ { case 0xEF53L: /*EXT2 & EXT3*/ case 0x6969L: /*NFS*/ case 0xFF534D42L: /*CIFS*/ case 0x517BL: /*SMB*/ case 0x52654973L: /*REISERFS*/ case 0x65735546L: /*fuse for ntfs*/ case 0x58465342L: /*xfs*/ case 0x4d44L: /*msdos*/ break; case 0x72b6L: /*jffs2*/ if (strcmp(mnt->mnt_fsname, "rootfs") == 0) continue; height += mheight; break; default: continue; } height += mheight; } } endmntent(mountFile); } width = w_max(width, 0); height = h_max(height, 0); x = getScreenStartX(width); y = getScreenStartY(height); fprintf(stderr, "CDBoxInfoWidget::CDBoxInfoWidget() x = %d, y = %d, width = %d height = %d\n", x, y, width, height); int ypos=y; int i = 0; frameBuffer->paintBoxRel(x, ypos, width, hheight, COL_MENUHEAD_PLUS_0, RADIUS_LARGE, CORNER_TOP); frameBuffer->paintBoxRel(x, ypos+ hheight, width, height- hheight, COL_MENUCONTENT_PLUS_0, RADIUS_LARGE, CORNER_BOTTOM); ypos+= hheight + (mheight >>1); FILE* fd = fopen("/proc/cpuinfo", "rt"); if (fd==NULL) { printf("error while opening proc-cpuinfo\n" ); } else { char *buffer=NULL; size_t len = 0; ssize_t read; while ((read = getline(&buffer, &len, fd)) != -1) { if (!(strncmp(const_cast<char *>("Hardware"),buffer,8))) { char *t=rindex(buffer,'\n'); if (t) *t='\0'; std::string hw; char *p=rindex(buffer,':'); if (p) hw=++p; hw+=" Info"; g_Font[SNeutrinoSettings::FONT_TYPE_MENU_TITLE]->RenderString(x+10, y + hheight+1, width - 10, hw.c_str(), COL_MENUHEAD, 0, true); // UTF-8 break; } i++; if (i > 2) continue; g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->RenderString(x+ 10, ypos+ mheight, width - 10, buffer, COL_MENUCONTENT); ypos+= mheight; } fclose(fd); if (buffer) free(buffer); } char *ubuf=NULL, *sbuf=NULL; int buf_size=256; ubuf = new char[buf_size]; sbuf = new char[buf_size]; if (sbuf != NULL && ubuf != NULL) { int updays, uphours, upminutes; struct sysinfo info; struct tm *current_time; time_t current_secs; memset(sbuf, 0, 256); time(¤t_secs); current_time = localtime(¤t_secs); sysinfo(&info); snprintf( ubuf,buf_size, "%2d:%02d%s up ", current_time->tm_hour%12 ? current_time->tm_hour%12 : 12, current_time->tm_min, current_time->tm_hour > 11 ? "pm" : "am"); strcat(sbuf, ubuf); updays = (int) info.uptime / (60*60*24); if (updays) { snprintf(ubuf,buf_size, "%d day%s, ", updays, (updays != 1) ? "s" : ""); strcat(sbuf, ubuf); } upminutes = (int) info.uptime / 60; uphours = (upminutes / 60) % 24; upminutes %= 60; if (uphours) snprintf(ubuf,buf_size,"%2d:%02d, ", uphours, upminutes); else snprintf(ubuf,buf_size,"%d min, ", upminutes); strcat(sbuf, ubuf); snprintf(ubuf,buf_size, "load: %ld.%02ld, %ld.%02ld, %ld.%02ld\n", LOAD_INT(info.loads[0]), LOAD_FRAC(info.loads[0]), LOAD_INT(info.loads[1]), LOAD_FRAC(info.loads[1]), LOAD_INT(info.loads[2]), LOAD_FRAC(info.loads[2])); strcat(sbuf, ubuf); ypos+= mheight/2; g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->RenderString(x+ 10, ypos+ mheight, width - 10, sbuf, COL_MENUCONTENT); ypos+= mheight; snprintf(ubuf,buf_size, "memory total %dKb, free %dKb", (int) info.totalram/1024, (int) info.freeram/1024); ypos+= mheight/2; g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->RenderString(x+ 10, ypos+ mheight, width - 10, ubuf, COL_MENUCONTENT); ypos+= mheight; int headOffset=0; int mpOffset=0; bool rec_mp=false; if ((mountFile = setmntent("/proc/mounts", "r")) == 0 ) { perror("/proc/mounts"); } else { float gb=0; char c=' '; while ((mnt = getmntent(mountFile)) != 0) { if (::statfs(mnt->mnt_dir, &s) == 0) { switch (s.f_type) { case (int) 0xEF53: /*EXT2 & EXT3*/ case (int) 0x6969: /*NFS*/ case (int) 0xFF534D42: /*CIFS*/ case (int) 0x517B: /*SMB*/ case (int) 0x52654973: /*REISERFS*/ case (int) 0x65735546: /*fuse for ntfs*/ case (int) 0x58465342: /*xfs*/ case (int) 0x4d44: /*msdos*/ gb = 1024.0*1024.0; c = 'G'; break; case (int) 0x72b6: /*jffs2*/ if (strcmp(mnt->mnt_fsname, "rootfs") == 0) continue; // paint mount head for (int j = 0; j < headSize; j++) { switch (j) { case 0: headOffset = 10; break; case 1: headOffset = nameOffset + 20; break; case 2: headOffset = nameOffset + sizeOffset+10 +20; break; case 3: headOffset = nameOffset + (sizeOffset+10)*2+15; break; case 4: headOffset = nameOffset + (sizeOffset+10)*3+15; break; } g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->RenderString(x+ headOffset, ypos+ mheight, width - 10, head[j], COL_MENUCONTENTINACTIVE); } ypos+= mheight; gb = 1024.0; c = 'M'; break; default: continue; } if ( s.f_blocks > 0 ) { long blocks_used; long blocks_percent_used; blocks_used = s.f_blocks - s.f_bfree; blocks_percent_used = (long)(blocks_used * 100.0 / (blocks_used + s.f_bavail) + 0.5); //paint mountpoints for (int j = 0; j < headSize; j++) { switch (j) { case 0: { if (s.f_type != 0x72b6) { char *p1=NULL, *p2=NULL; p1=strchr(g_settings.network_nfs_recordingdir+1,'/') ; p2=strchr(mnt->mnt_dir+1,'/') ; if (p2) { if (strstr(p1,p2)) { rec_mp = true; } } else { if (strstr(g_settings.network_nfs_recordingdir,mnt->mnt_dir)) { rec_mp = true; } } } mpOffset = 10; snprintf(ubuf,buf_size,"%-10.10s",basename(mnt->mnt_fsname)); } break; case 1: mpOffset = nameOffset + 10; snprintf(ubuf,buf_size,"%7.2f%c", (s.f_blocks * (s.f_bsize / 1024.0)) / gb, c); break; case 2: mpOffset = nameOffset+ (sizeOffset+10)*1+10; snprintf(ubuf,buf_size,"%7.2f%c", ((s.f_blocks - s.f_bfree) * (s.f_bsize / 1024.0)) / gb, c); break; case 3: mpOffset = nameOffset+ (sizeOffset+10)*2+10; snprintf(ubuf,buf_size,"%7.2f%c", s.f_bavail * (s.f_bsize / 1024.0) / gb, c); break; case 4: mpOffset = nameOffset+ (sizeOffset+10)*3+10; snprintf(ubuf,buf_size,"%4ld%c", blocks_percent_used,'%'); break; } g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->RenderString(x + mpOffset, ypos+ mheight, width - 10, ubuf, rec_mp ? COL_MENUHEAD+2:COL_MENUCONTENT); rec_mp = false; } int pbw = width - offsetw - 10; //fprintf(stderr, "width: %d offsetw: %d pbw: %d\n", width, offsetw, pbw); if (pbw > 8) /* smaller progressbar is not useful ;) */ { CProgressBar pb(true, -1, -1, 30, 100, 70, true); pb.paintProgressBarDefault(x+offsetw, ypos+3, pbw, mheight-10, blocks_percent_used, 100); } ypos+= mheight; } i++; } if (ypos > y + height - mheight) /* the screen is not high enough */ break; /* todo: scrolling? */ } endmntent(mountFile); } } if (sbuf) delete[] sbuf; if (ubuf) delete[] ubuf; }
/* * Helper function which checks a file in /etc/mtab format to see if a * filesystem is mounted. Returns an error if the file doesn't exist * or can't be opened. */ static errcode_t check_mntent_file(const char *mtab_file, const char *file, int *mount_flags, char *mtpt, int mtlen) { struct mntent *mnt; struct stat st_buf; errcode_t retval = 0; dev_t file_dev=0, file_rdev=0; ino_t file_ino=0; FILE *f; int fd; *mount_flags = 0; if ((f = setmntent (mtab_file, "r")) == NULL) return errno; if (stat(file, &st_buf) == 0) { if (S_ISBLK(st_buf.st_mode)) { #ifndef __GNU__ /* The GNU hurd is broken with respect to stat devices */ file_rdev = st_buf.st_rdev; #endif /* __GNU__ */ } else { file_dev = st_buf.st_dev; file_ino = st_buf.st_ino; } } while ((mnt = getmntent (f)) != NULL) { if (strcmp(file, mnt->mnt_fsname) == 0) break; if (stat(mnt->mnt_fsname, &st_buf) == 0) { if (S_ISBLK(st_buf.st_mode)) { #ifndef __GNU__ if (file_rdev && (file_rdev == st_buf.st_rdev)) break; #endif /* __GNU__ */ } else { if (file_dev && ((file_dev == st_buf.st_dev) && (file_ino == st_buf.st_ino))) break; } } } if (mnt == 0) { #ifndef __GNU__ /* The GNU hurd is broken with respect to stat devices */ /* * Do an extra check to see if this is the root device. We * can't trust /etc/mtab, and /proc/mounts will only list * /dev/root for the root filesystem. Argh. Instead we * check if the given device has the same major/minor number * as the device that the root directory is on. */ if (file_rdev && stat("/", &st_buf) == 0) { if (st_buf.st_dev == file_rdev) { *mount_flags = EXT2_MF_MOUNTED; if (mtpt) strncpy(mtpt, "/", mtlen); goto is_root; } } #endif /* __GNU__ */ goto errout; } #ifndef __GNU__ /* The GNU hurd is deficient; what else is new? */ /* Validate the entry in case /etc/mtab is out of date */ /* * We need to be paranoid, because some broken distributions * (read: Slackware) don't initialize /etc/mtab before checking * all of the non-root filesystems on the disk. */ if (stat(mnt->mnt_dir, &st_buf) < 0) { retval = errno; if (retval == ENOENT) { #ifdef DEBUG printf("Bogus entry in %s! (%s does not exist)\n", mtab_file, mnt->mnt_dir); #endif /* DEBUG */ retval = 0; } goto errout; } if (file_rdev && (st_buf.st_dev != file_rdev)) { #ifdef DEBUG printf("Bogus entry in %s! (%s not mounted on %s)\n", mtab_file, file, mnt->mnt_dir); #endif /* DEBUG */ goto errout; } #endif /* __GNU__ */ *mount_flags = EXT2_MF_MOUNTED; #ifdef MNTOPT_RO /* Check to see if the ro option is set */ if (hasmntopt(mnt, MNTOPT_RO)) *mount_flags |= EXT2_MF_READONLY; #endif if (mtpt) strncpy(mtpt, mnt->mnt_dir, mtlen); /* * Check to see if we're referring to the root filesystem. * If so, do a manual check to see if we can open /etc/mtab * read/write, since if the root is mounted read/only, the * contents of /etc/mtab may not be accurate. */ if (LONE_CHAR(mnt->mnt_dir, '/')) { is_root: #define TEST_FILE "/.ismount-test-file" *mount_flags |= EXT2_MF_ISROOT; fd = open(TEST_FILE, O_RDWR|O_CREAT); if (fd < 0) { if (errno == EROFS) *mount_flags |= EXT2_MF_READONLY; } else close(fd); (void) unlink(TEST_FILE); } retval = 0; errout: endmntent (f); return retval; }
Errors Device_getDeviceInfo(DeviceInfo *deviceInfo, const String deviceName ) { FileStat fileStat; int handle; #if defined(HAVE_IOCTL) && defined(HAVE_BLKSSZGET) int i; #endif #if defined(HAVE_IOCTL) && defined(HAVE_BLKGETSIZE) long l; #endif FILE *mtab; struct mntent mountEntry; char buffer[4096]; assert(deviceName != NULL); assert(deviceInfo != NULL); // initialize variables deviceInfo->type = DEVICE_TYPE_UNKNOWN; deviceInfo->size = -1LL; deviceInfo->blockSize = 0L; // deviceInfo->freeBlocks = 0LL; // deviceInfo->totalBlocks = 0LL; deviceInfo->mountedFlag = FALSE; // get device meta data if (LSTAT(String_cString(deviceName),&fileStat) == 0) { deviceInfo->timeLastAccess = fileStat.st_atime; deviceInfo->timeModified = fileStat.st_mtime; deviceInfo->timeLastChanged = fileStat.st_ctime; deviceInfo->userId = fileStat.st_uid; deviceInfo->groupId = fileStat.st_gid; deviceInfo->permission = (DevicePermission)fileStat.st_mode; #ifdef HAVE_MAJOR deviceInfo->major = major(fileStat.st_rdev); #else deviceInfo->major = 0; #endif #ifdef HAVE_MINOR deviceInfo->minor = minor(fileStat.st_rdev); #else deviceInfo->minor = 0; #endif deviceInfo->id = (uint64)fileStat.st_ino; if (S_ISCHR(fileStat.st_mode)) deviceInfo->type = DEVICE_TYPE_CHARACTER; else if (S_ISBLK(fileStat.st_mode)) deviceInfo->type = DEVICE_TYPE_BLOCK; } if (deviceInfo->type == DEVICE_TYPE_BLOCK) { // try to get block size, total size handle = open(String_cString(deviceName),O_RDONLY); if (handle != -1) { #if defined(HAVE_IOCTL) && defined(HAVE_BLKSSZGET) if (ioctl(handle,BLKSSZGET, &i) == 0) deviceInfo->blockSize = (ulong)i; #endif #if defined(HAVE_IOCTL) && defined(HAVE_BLKGETSIZE) if (ioctl(handle,BLKGETSIZE,&l) == 0) deviceInfo->size = (int64)l*512; #endif close(handle); } } // check if mounted mtab = setmntent("/etc/mtab","r"); if (mtab != NULL) { while (getmntent_r(mtab,&mountEntry,buffer,sizeof(buffer)) != NULL) { if (String_equalsCString(deviceName,mountEntry.mnt_fsname)) { deviceInfo->mountedFlag = TRUE; break; } } endmntent(mtab); } return ERROR_NONE; }
/* * Write out a mount list */ void rewrite_mtab(mntlist *mp, const char *mnttabname) { FILE *mfp; int error = 0; /* * Concoct a temporary name in the same directory as the target mount * table so that rename() will work. */ char tmpname[64]; int retries; int tmpfd; char *cp; char mcp[128]; xstrlcpy(mcp, mnttabname, sizeof(mcp)); cp = strrchr(mcp, '/'); if (cp) { memmove(tmpname, mcp, cp - mcp); tmpname[cp - mcp] = '\0'; } else { plog(XLOG_WARNING, "No '/' in mtab (%s), using \".\" as tmp directory", mnttabname); tmpname[0] = '.'; tmpname[1] = '\0'; } xstrlcat(tmpname, "/mtabXXXXXX", sizeof(tmpname)); retries = 0; enfile1: #ifdef HAVE_MKSTEMP tmpfd = mkstemp(tmpname); fchmod(tmpfd, 0644); #else /* not HAVE_MKSTEMP */ mktemp(tmpname); tmpfd = open(tmpname, O_RDWR | O_CREAT | O_TRUNC, 0644); #endif /* not HAVE_MKSTEMP */ if (tmpfd < 0) { if (errno == ENFILE && retries++ < NFILE_RETRIES) { sleep(1); goto enfile1; } plog(XLOG_ERROR, "%s: open: %m", tmpname); return; } if (close(tmpfd) < 0) plog(XLOG_ERROR, "Couldn't close tmp file descriptor: %m"); retries = 0; enfile2: mfp = setmntent(tmpname, "w"); if (!mfp) { if (errno == ENFILE && retries++ < NFILE_RETRIES) { sleep(1); goto enfile2; } plog(XLOG_ERROR, "setmntent(\"%s\", \"w\"): %m", tmpname); error = 1; goto out; } while (mp) { if (mp->mnt) { if (addmntent(mfp, mp->mnt)) { plog(XLOG_ERROR, "Can't write entry to %s", tmpname); error = 1; goto out; } } mp = mp->mnext; } /* * SunOS 4.1 manuals say that the return code from entmntent() * is always 1 and to treat as a void. That means we need to * call fflush() to make sure the new mtab file got written. */ if (fflush(mfp)) { plog(XLOG_ERROR, "flush new mtab file: %m"); error = 1; goto out; } (void) endmntent(mfp); /* * Rename temporary mtab to real mtab */ if (rename(tmpname, mnttabname) < 0) { plog(XLOG_ERROR, "rename %s to %s: %m", tmpname, mnttabname); error = 1; goto out; } out: if (error) (void) unlink(tmpname); }
int main(int argc, char *argv[]) { int fd; char* mount_point; struct mntent *mnt; FILE* mtab; FILE* new_mtab; progname = argv[0]; if (argc != 2) { usage(); exit(1); } if (geteuid() != 0) { fprintf(stderr, "%s must be installed suid root\n", progname); exit(1); } mount_point = canonicalize(argv[1]); if (mount_point == NULL) { exit(1); } if (umount_ok(mount_point) != 0) { exit(1); } if (umount(mount_point) != 0) { fprintf(stderr, "Could not umount %s: %s\n", mount_point, strerror(errno)); exit(1); } #ifndef EMBED if ((fd = open(MOUNTED"~", O_RDWR|O_CREAT|O_EXCL, 0600)) == -1) { fprintf(stderr, "Can't get "MOUNTED"~ lock file"); return 1; } close(fd); if ((mtab = setmntent(MOUNTED, "r")) == NULL) { fprintf(stderr, "Can't open " MOUNTED ": %s\n", strerror(errno)); return 1; } #define MOUNTED_TMP MOUNTED".tmp" if ((new_mtab = setmntent(MOUNTED_TMP, "w")) == NULL) { fprintf(stderr, "Can't open " MOUNTED_TMP ": %s\n", strerror(errno)); endmntent(mtab); return 1; } while ((mnt = getmntent(mtab)) != NULL) { if (strcmp(mnt->mnt_dir, mount_point) != 0) { addmntent(new_mtab, mnt); } } endmntent(mtab); if (fchmod (fileno (new_mtab), S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) < 0) { fprintf(stderr, "Error changing mode of %s: %s\n", MOUNTED_TMP, strerror(errno)); exit(1); } endmntent(new_mtab); if (rename(MOUNTED_TMP, MOUNTED) < 0) { fprintf(stderr, "Cannot rename %s to %s: %s\n", MOUNTED, MOUNTED_TMP, strerror(errno)); exit(1); } if (unlink(MOUNTED"~") == -1) { fprintf(stderr, "Can't remove "MOUNTED"~"); return 1; } #endif /* EMBED */ return 0; }
static FILE * open_locked_mtab(const char *mnttabname, char *mode, char *fs) { FILE *mfp = NULL; /* * There is a possible race condition if two processes enter * this routine at the same time. One will be blocked by the * exclusive lock below (or by the shared lock in setmntent) * and by the time the second process has the exclusive lock * it will be on the wrong underlying object. To check for this * the mtab file is stat'ed before and after all the locking * sequence, and if it is a different file then we assume that * it may be the wrong file (only "may", since there is another * race between the initial stat and the setmntent). * * Simpler solutions to this problem are invited... */ int racing = 2; int rc; int retries = 0; struct stat st_before, st_after; if (mnt_file) { # ifdef DEBUG dlog("Forced close on %s in read_mtab", mnttabname); # endif /* DEBUG */ endmntent(mnt_file); mnt_file = NULL; } again: if (mfp) { endmntent(mfp); mfp = NULL; } if (stat(mnttabname, &st_before) < 0) { plog(XLOG_ERROR, "%s: stat: %m", mnttabname); if (errno == ESTALE) { /* happens occasionally */ sleep(1); goto again; } /* * If 'mnttabname' file does not exist give setmntent() a * chance to create it (depending on the mode). * Otherwise, bail out. */ else if (errno != ENOENT) { return 0; } } eacces: mfp = setmntent((char *)mnttabname, mode); if (!mfp) { /* * Since setmntent locks the descriptor, it * is possible it can fail... so retry if * needed. */ if (errno == EACCES || errno == EAGAIN) { # ifdef DEBUG dlog("Blocked, trying to obtain exclusive mtab lock"); # endif /* DEBUG */ goto eacces; } else if (errno == ENFILE && retries++ < NFILE_RETRIES) { sleep(1); goto eacces; } plog(XLOG_ERROR, "setmntent(\"%s\", \"%s\"): %m", mnttabname, mode); return 0; } /* * At this point we have an exclusive lock on the mount list, * but it may be the wrong one so... */ /* * Need to get an exclusive lock on the current * mount table until we have a new copy written * out, when the lock is released in free_mntlist. * flock is good enough since the mount table is * not shared between machines. */ do rc = lock(fileno(mfp)); while (rc < 0 && errno == EINTR); if (rc < 0) { plog(XLOG_ERROR, "Couldn't lock %s: %m", mnttabname); endmntent(mfp); return 0; } /* * Now check whether the mtab file has changed under our feet */ if (stat(mnttabname, &st_after) < 0) { plog(XLOG_ERROR, "%s: stat: %m", mnttabname); goto again; } if (st_before.st_dev != st_after.st_dev || st_before.st_ino != st_after.st_ino) { struct timeval tv; if (racing == 0) { /* Sometimes print a warning */ plog(XLOG_WARNING, "Possible mount table race - retrying %s", fs); } racing = (racing + 1) & 3; /* * Take a nap. From: Doug Kingston <*****@*****.**> */ tv.tv_sec = 0; tv.tv_usec = (am_mypid & 0x07) << 17; if (tv.tv_usec) if (select(0, (voidp) 0, (voidp) 0, (voidp) 0, &tv) < 0) plog(XLOG_WARNING, "mtab nap failed: %m"); goto again; } return mfp; }
psi_mountlist_t * psi_arch_mountlist(const int remote) { FILE *mntent; struct mntent mnt; char buf[PATH_MAX * 3]; /* size used in autofs so I hope it's okay */ psi_mountlist_t *ml = NULL; psi_mountinfo_t *mounti, **mounts; /* Open /etc/mtab */ mntent = setmntent(_PATH_MOUNTED, "r"); if (mntent == NULL) return (psi_mountlist_t *) PyErr_SetFromErrnoWithFilename( PyExc_OSError, _PATH_MOUNTED); /* Create our (empty) mountlist */ ml = (psi_mountlist_t *)psi_calloc(sizeof(psi_mountlist_t)); if (ml == NULL) { fclose(mntent); return NULL; } /* Step through each line in the mount file */ while (getmntent_r(mntent, &mnt, buf, sizeof(buf)) != NULL) { /* Skip remote filesystems if not asked for them */ if (!remote && (strchr(mnt.mnt_fsname, ':') != NULL || strncmp(mnt.mnt_fsname, "//", 2) == 0)) continue; /* Allocate space for the mount information */ if ((mounti = psi_calloc(sizeof(psi_mountinfo_t))) == NULL) { fclose(mntent); psi_free_mountlist(ml); return NULL; } /* And then allocate more space for the mount list */ mounts = (psi_mountinfo_t **)psi_realloc( ml->mounts, (ml->count + 1) * sizeof(psi_mountinfo_t *)); if (mounts == NULL) { fclose(mntent); psi_free_mountinfo(mounti); psi_free_mountlist(ml); return NULL; } ml->mounts = mounts; ml->mounts[ml->count] = mounti; ml->count += 1; /* Finally add the information to mounti */ if (set_mntent(mounti, &mnt) < 0) { fclose(mntent); psi_free_mountlist(ml); return NULL; } if (posix_set_vfs(mounti) < 0) { fclose(mntent); psi_free_mountlist(ml); return NULL; } } if (!feof(mntent)) { /* Uh oh, we had a read error */ endmntent(mntent); psi_free_mountlist(ml); PyErr_Format(PyExc_OSError, "Read error in %s", _PATH_MOUNTED); return NULL; } endmntent(mntent); return ml; }
static void CheckMounts(const char *mtab) { FILE *mntfp; struct mntent *mntent; struct stat stbuf; mntfp = setmntent(mtab, "r"); if ( mntfp != NULL ) { char *tmp; char *mnt_type; char *mnt_dev; while ( (mntent=getmntent(mntfp)) != NULL ) { mnt_type = malloc(strlen(mntent->mnt_type) + 1); if (mnt_type == NULL) continue; /* maybe you'll get lucky next time. */ mnt_dev = malloc(strlen(mntent->mnt_fsname) + 1); if (mnt_dev == NULL) { free(mnt_type); continue; } strcpy(mnt_type, mntent->mnt_type); strcpy(mnt_dev, mntent->mnt_fsname); /* Handle "supermount" filesystem mounts */ if ( strcmp(mnt_type, MNTTYPE_SUPER) == 0 ) { tmp = strstr(mntent->mnt_opts, "fs="); if ( tmp ) { free(mnt_type); mnt_type = strdup(tmp + strlen("fs=")); if ( mnt_type ) { tmp = strchr(mnt_type, ','); if ( tmp ) { *tmp = '\0'; } } } tmp = strstr(mntent->mnt_opts, "dev="); if ( tmp ) { free(mnt_dev); mnt_dev = strdup(tmp + strlen("dev=")); if ( mnt_dev ) { tmp = strchr(mnt_dev, ','); if ( tmp ) { *tmp = '\0'; } } } } if ( strcmp(mnt_type, MNTTYPE_CDROM) == 0 ) { #ifdef DEBUG_CDROM fprintf(stderr, "Checking mount path from %s: %s mounted on %s of %s\n", mtab, mnt_dev, mntent->mnt_dir, mnt_type); #endif if (CheckDrive(mnt_dev, mnt_type, &stbuf) > 0) { AddDrive(mnt_dev, &stbuf); } } free(mnt_dev); free(mnt_type); } endmntent(mntfp); } }
static int main_swapoff(int argc, char *argv[]) { FILE *fp; struct mntent *fstab; int status = 0; int c, i; while ((c = getopt_long(argc, argv, "ahvVL:U:", longswapoffopts, NULL)) != -1) { switch (c) { case 'a': /* all */ ++all; break; case 'h': /* help */ swapoff_usage(stdout, 0); break; case 'v': /* be chatty */ ++verbose; break; case 'V': /* version */ printf("%s (%s)\n", progname, PACKAGE_STRING); exit(0); case 'L': addl(optarg); break; case 'U': addu(optarg); break; case 0: break; case '?': default: swapoff_usage(stderr, 1); } } argv += optind; if (!all && !llct && !ulct && *argv == NULL) swapoff_usage(stderr, 2); /* * swapoff any explicitly given arguments. * Complain in case the swapoff call fails. */ for (i = 0; i < llct; i++) status |= swapoff_by_label(llist[i], !QUIET); for (i = 0; i < ulct; i++) status |= swapoff_by_uuid(ulist[i], !QUIET); while (*argv != NULL) status |= do_swapoff(*argv++, !QUIET, !CANONIC); if (all) { /* * In case /proc/swaps exists, unswap stuff listed there. * We are quiet but report errors in status. * Errors might mean that /proc/swaps * exists as ordinary file, not in procfs. * do_swapoff() exits immediately on EPERM. */ read_proc_swaps(); for(i=0; i<numSwaps; i++) status |= do_swapoff(swapFiles[i], QUIET, CANONIC); /* * Unswap stuff mentioned in /etc/fstab. * Probably it was unmounted already, so errors are not bad. * Doing swapoff -a twice should not give error messages. */ fp = setmntent(_PATH_FSTAB, "r"); if (fp == NULL) { int errsv = errno; fprintf(stderr, _("%s: cannot open %s: %s\n"), progname, _PATH_FSTAB, strerror(errsv)); exit(2); } while ((fstab = getmntent(fp)) != NULL) { const char *special; if (!streq(fstab->mnt_type, MNTTYPE_SWAP)) continue; special = fsprobe_get_devname(fstab->mnt_fsname); if (!special) continue; if (!is_in_proc_swaps(special)) do_swapoff(special, QUIET, CANONIC); } fclose(fp); } return status; }
static int parse_fstab(bool initrd) { _cleanup_endmntent_ FILE *f = NULL; const char *fstab_path; struct mntent *me; int r = 0; fstab_path = initrd ? "/sysroot/etc/fstab" : "/etc/fstab"; f = setmntent(fstab_path, "re"); if (!f) { if (errno == ENOENT) return 0; log_error("Failed to open %s: %m", fstab_path); return -errno; } while ((me = getmntent(f))) { _cleanup_free_ char *where = NULL, *what = NULL; int k; if (initrd && !mount_in_initrd(me)) continue; what = fstab_node_to_udev_node(me->mnt_fsname); if (!what) return log_oom(); if (detect_container(NULL) > 0 && is_device_path(what)) { log_info("Running in a container, ignoring fstab device entry for %s.", what); continue; } where = initrd ? strappend("/sysroot/", me->mnt_dir) : strdup(me->mnt_dir); if (!where) return log_oom(); if (is_path(where)) path_kill_slashes(where); log_debug("Found entry what=%s where=%s type=%s", what, where, me->mnt_type); if (streq(me->mnt_type, "swap")) k = add_swap(what, me); else { bool noauto, nofail, automount; const char *post; noauto = !!hasmntopt(me, "noauto"); nofail = !!hasmntopt(me, "nofail"); automount = hasmntopt(me, "comment=systemd.automount") || hasmntopt(me, "x-systemd.automount"); if (initrd) post = SPECIAL_INITRD_FS_TARGET; else if (mount_in_initrd(me)) post = SPECIAL_INITRD_ROOT_FS_TARGET; else if (mount_is_network(me)) post = SPECIAL_REMOTE_FS_TARGET; else post = SPECIAL_LOCAL_FS_TARGET; k = add_mount(what, where, me->mnt_type, me->mnt_opts, me->mnt_passno, noauto, nofail, automount, post, fstab_path); } if (k < 0) r = k; } return r; }