⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mount.c

📁 watchdog source watchdog source
💻 C
📖 第 1 页 / 共 3 页
字号:
io_error:    perror(device);    close(fd);    return 0;}FILE *procfs;static voidprocclose(void) {    if (procfs)        fclose (procfs);    procfs = 0;}static intprocopen(void) {    return ((procfs = fopen(PROC_FILESYSTEMS, "r")) != NULL);}static char *procnext(void) {   char line[100];   static char fsname[50];   while (fgets(line, sizeof(line), procfs)) {      if (sscanf (line, "nodev %[^\n]\n", fsname) == 1) continue;      if (sscanf (line, " %[^ \n]\n", fsname) != 1) continue;      return fsname;   }   return 0;}static intis_in_proc(char *type) {    char *fsname;    if (procopen()) {	while ((fsname = procnext()) != NULL)	  if (!strcmp(fsname, type))	    return 1;    }    return 0;}static intalready (char *spec, char *node) {    struct mntentchn *mc;    int ret = 1;    if ((mc = getmntfile(node)) != NULL)        error ("mount: according to mtab, %s is already mounted on %s",	       mc->mnt_fsname, node);    else if ((mc = getmntfile(spec)) != NULL)        error ("mount: according to mtab, %s is mounted on %s",	       spec, mc->mnt_dir);    else        ret = 0;    return ret;}/* Create mtab with a root entry.  */static voidcreate_mtab (void) {  struct mntentchn *fstab;  struct mntent mnt;  int flags;  char *extra_opts;  mntFILE *mfp;  lock_mtab();  mfp = my_setmntent (MOUNTED, "a+");  if (mfp == NULL || mfp->mntent_fp == NULL)    die (EX_FILEIO, "mount: can't open %s for writing: %s",	 MOUNTED, strerror (errno));  /* Find the root entry by looking it up in fstab */  if ((fstab = getfsfile ("/")) || (fstab = getfsfile ("root"))) {      parse_opts (xstrdup (fstab->mnt_opts), &flags, &extra_opts);      mnt.mnt_dir = "/";      mnt.mnt_fsname = canonicalize (fstab->mnt_fsname);      mnt.mnt_type = fstab->mnt_type;      mnt.mnt_opts = fix_opts_string (flags, extra_opts);      mnt.mnt_freq = mnt.mnt_passno = 0;      if (my_addmntent (mfp, &mnt) == 1)	die (EX_FILEIO, "mount: error writing %s: %s",	     MOUNTED, strerror (errno));  }  if (fchmod (fileno (mfp->mntent_fp), S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) < 0)    if (errno != EROFS)      die (EX_FILEIO, "mount: error changing mode of %s: %s",	   MOUNTED, strerror (errno));  my_endmntent (mfp);  unlock_mtab();}/* count successful mount system calls */static int mountcount = 0;static intmount5 (char *special, char *dir, char *type, int flags, void *data) {     int ret = mount (special, dir, type, 0xC0ED0000 | (flags), data);     if (ret == 0)	  mountcount++;     return ret;}/* Mount a single file system.  Return status,   so don't exit on non-fatal errors.  */ static inttry_mount5 (char *spec, char *node, char **type, int flags, char *mount_opts) {   char *fsname;      if (*type && strcasecmp (*type, "auto") == 0)      *type = NULL;   if (!*type && !(flags & MS_REMOUNT)) {      *type = fstype(spec);      if (mount_verbose) {	  printf ("mount: you didn't specify a filesystem type for %s\n",		  spec);	  if (*type)	    printf ("       I will try type %s\n", *type);	  else	    printf ("       I will try all types mentioned in %s\n",		    PROC_FILESYSTEMS);      }   }   if (*type || (flags & MS_REMOUNT))      return mount5 (spec, node, *type, flags & ~MS_NOSYS, mount_opts);   if (!procopen())     return -1;   while ((fsname = procnext()) != NULL) {      if (tested (fsname))	 continue;      if (mount5 (spec, node, fsname, flags & ~MS_NOSYS, mount_opts) == 0) {	 *type = xstrdup(fsname);	 procclose();	 return 0;      } else if (errno != EINVAL) {         *type = "guess";	 procclose();	 return 1;      }   }   procclose();   *type = NULL;   return -1;}/* * try_mount_one() *	Try to mount one file system. When "bg" is 1, this is a retry *	in the background. One additional exit code EX_BG is used here. *	It is used to instruct the caller to retry the mount in the *	background. */static inttry_mount_one (char *spec0, char *node0, char *type0, char *opts0,	       int freq, int pass, int bg){  struct mntentchn mcn;  struct mntent mnt;  int mnt_err;  int flags;  char *extra_opts;		/* written in mtab */  char *mount_opts;		/* actually used on system call */  static int added_ro = 0;  int loop, looptype, offset;  char *spec, *node, *type, *opts, *loopdev, *loopfile;  struct stat statbuf;  spec = xstrdup(spec0);  node = xstrdup(node0);  type = xstrdup(type0);  opts = xstrdup(opts0);  parse_opts (xstrdup (opts), &flags, &extra_opts);  /* root may allow certain types of mounts by ordinary users */  if (mount_suid && !(flags & MS_USER)) {      if (already (spec, node))	die (EX_USAGE, "mount failed");      else        die (EX_USAGE, "mount: only root can mount %s on %s", spec, node);  }  /* quietly succeed for fstab entries that don't get mounted automatically */  if (all && (flags & MS_NOAUTO))    return 0;  mount_opts = extra_opts;  /*   * In the case of a loop mount, either type is of the form lo@/dev/loop5   * or the option "-o loop=/dev/loop5" or just "-o loop" is given, or   * mount just has to figure things out for itself from the fact that   * spec is not a block device. We do not test for a block device   * immediately: maybe later other types of mountable objects will occur.   */  loopdev = opt_loopdev;  looptype = (type && strncmp("lo@", type, 3) == 0);  if (looptype) {    if (loopdev)      error("mount: loop device specified twice");    loopdev = type+3;    type = opt_vfstype;  }  else if (opt_vfstype) {    if (type)      error("mount: type specified twice");    else      type = opt_vfstype;  }  loop = ((flags & MS_LOOP) || loopdev || opt_offset || opt_encryption);  loopfile = spec;  if (loop) {    flags |= MS_LOOP;    if (fake) {      if (mount_verbose)	printf("mount: skipping the setup of a loop device\n");    } else {      int loopro = (flags & MS_RDONLY);      if (!loopdev || !*loopdev)	loopdev = find_unused_loop_device();      if (!loopdev)	return EX_SYSERR;	/* no more loop devices */      if (mount_verbose)	printf("mount: going to use the loop device %s\n", loopdev);      offset = opt_offset ? strtoul(opt_offset, NULL, 0) : 0;      if (set_loop (loopdev, loopfile, offset, opt_encryption, &loopro))	return EX_FAIL;      spec = loopdev;      if (loopro)	flags |= MS_RDONLY;    }  }  if (!fake && type && streq (type, "nfs")) {#if HAVE_NFS    mnt_err = nfsmount (spec, node, &flags, &extra_opts, &mount_opts, bg);    if (mnt_err)      return mnt_err;#else    die (EX_SOFTWARE, "mount: this version was compiled "	              "without support for the type `nfs'");#endif  }  /*   * Call mount.TYPE for types that require a separate   * mount program.  For the moment these types are ncp and smb.   */  if (type)#ifndef ALWAYS_STAT  if (streq (type, "smb") || streq (type, "ncp"))#else  if (strlen (type) < 100)#endif  {       char mountprog[120];       sprintf(mountprog, "/sbin/mount.%s", type);       if (stat(mountprog, &statbuf) == 0) {	    if (fork() == 0) {		 char *oo, *mountargs[10];		 int i = 0;		 setuid(getuid());		 setgid(getgid());		 oo = fix_opts_string (flags, extra_opts);		 mountargs[i++] = mountprog;		 mountargs[i++] = spec;		 mountargs[i++] = node;		 if (mount_nomtab)		      mountargs[i++] = "-n";		 if (mount_verbose)		      mountargs[i++] = "-v";		 if (oo && *oo) {		      mountargs[i++] = "-o";		      mountargs[i++] = oo;		 }		 mountargs[i] = NULL;		 execv(mountprog, mountargs);		 exit(1);	/* exec failed */	    } else if (fork() != -1) {		 int status;		 wait(&status);		 return status;	    } else		 error("cannot fork: %s", strerror(errno));       }  }  block_signals (SIG_BLOCK);  if (fake      || (try_mount5 (spec, node, &type, flags & ~MS_NOSYS, mount_opts)) == 0)    /* Mount succeeded, report this (if mount_verbose) and write mtab entry.  */    {      if (loop)	  opt_loopdev = loopdev;      mcn.mnt_fsname = mnt.mnt_fsname = canonicalize (loop ? loopfile : spec);      mcn.mnt_dir = mnt.mnt_dir = canonicalize (node);      mcn.mnt_type = mnt.mnt_type = type ? type : "unknown";      mcn.mnt_opts = mnt.mnt_opts = fix_opts_string (flags & ~MS_NOMTAB, extra_opts);      mcn.nxt = 0;      mnt.mnt_freq = freq;      mnt.mnt_passno = pass;            /* We get chatty now rather than after the update to mtab since the	 mount succeeded, even if the write to /etc/mtab should fail.  */      if (mount_verbose)	   print_one (&mcn);      if (!mount_nomtab && mtab_is_writable()) {	  if (flags & MS_REMOUNT)	       update_mtab (mnt.mnt_dir, &mnt);	  else {	       mntFILE *mfp;	       lock_mtab();	       mfp = my_setmntent(MOUNTED, "a+");	       if (mfp == NULL || mfp->mntent_fp == NULL) {		    error("mount: can't open %s: %s", MOUNTED,			  strerror (errno));	       } else {		    if ((my_addmntent (mfp, &mnt)) == 1)			 error("mount: error writing %s: %s", MOUNTED,			       strerror (errno));		    my_endmntent(mfp);	       }	       unlock_mtab();	  }      }      block_signals (SIG_UNBLOCK);      return 0;    }  mnt_err = errno;  if (loop)	del_loop(spec);  block_signals (SIG_UNBLOCK);  /* Mount failed, complain, but don't die.  */  if (type == 0)    error ("mount: you must specify the filesystem type");  else  switch (mnt_err)    {    case EPERM:      if (geteuid() == 0) {	   if (stat (node, &statbuf) || !S_ISDIR(statbuf.st_mode))		error ("mount: mount point %s is not a directory", node);	   else		error ("mount: permission denied");      } else	error ("mount: must be superuser to use mount");      break;    case EBUSY:      if (flags & MS_REMOUNT) {	error ("mount: %s is busy", node);      } else if (!strcmp(type, "proc") && !strcmp(node, "/proc")) {	/* heuristic: if /proc/version exists, then probably proc is mounted */	if (stat ("/proc/version", &statbuf))   /* proc mounted? */	   error ("mount: %s is busy", node);   /* no */	else if(!all || mount_verbose)                /* yes, don't mention it */	   error ("mount: proc already mounted");      } else {	error ("mount: %s already mounted or %s busy", spec, node);	already (spec, node);      }      break;    case ENOENT:      if (lstat (node, &statbuf))	   error ("mount: mount point %s does not exist", node);      else if (stat (node, &statbuf))	   error ("mount: mount point %s is a symbolic link to nowhere",		  node);      else if (stat (spec, &statbuf))	   error ("mount: special device %s does not exist", spec);      else {           errno = mnt_err;           perror("mount");      }      break;    case ENOTDIR:      error ("mount: mount point %s is not a directory", node);      break;    case EINVAL:    { int fd, size;      if (flags & MS_REMOUNT) {	error ("mount: %s not mounted already, or bad option", node);      } else {	error ("mount: wrong fs type, bad option, bad superblock on %s,\n"	       "       or too many mounted file systems",	       spec);	if (stat (spec, &statbuf) == 0 && S_ISBLK(statbuf.st_mode)	   && (fd = open(spec, O_RDONLY)) >= 0) {	  if(ioctl(fd, BLKGETSIZE, &size) == 0 && size <= 2)	  error ("       (aren't you trying to mount an extended partition,\n"		 "       instead of some logical partition inside?)");	  close(fd);	}      }      break;    }    case EMFILE:      error ("mount table full"); break;    case EIO:      error ("mount: %s: can't read superblock", spec); break;    case ENODEV:      if (is_in_proc(type) || !strcmp(type, "guess"))        error("mount: %s has wrong major or minor number", spec);      else if (procfs) {	char *lowtype, *p;	int u;	error ("mount: fs type %s not supported by kernel", type);	/* maybe this loser asked for FAT or ISO9660 or isofs */	lowtype = xstrdup(type);	u = 0;	for(p=lowtype; *p; p++) {	  if(tolower(*p) != *p) {	    *p = tolower(*p);	    u++;	  }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -