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

📄 mount.c

📁 watchdog source watchdog source
💻 C
📖 第 1 页 / 共 3 页
字号:
	}	if (u && is_in_proc(lowtype))	  error ("mount: probably you meant %s", lowtype);	else if (!strncmp(lowtype, "iso", 3) && is_in_proc("iso9660"))	  error ("mount: maybe you meant iso9660 ?");	free(lowtype);      } else	error ("mount: %s has wrong device number or fs type %s not supported",	       spec, type);      break;    case ENOTBLK:      if (stat (spec, &statbuf)) /* strange ... */	error ("mount: %s is not a block device, and stat fails?", spec);      else if (S_ISBLK(statbuf.st_mode))        error ("mount: the kernel does not recognize %s as a block device\n"	       "       (maybe `insmod driver'?)", spec);      else if (S_ISREG(statbuf.st_mode))	error ("mount: %s is not a block device (maybe try `-o loop'?)",		 spec);      else	error ("mount: %s is not a block device", spec);      break;    case ENXIO:      error ("mount: %s is not a valid block device", spec); break;    case EACCES:  /* pre-linux 1.1.38, 1.1.41 and later */    case EROFS:   /* linux 1.1.38 and later */      if (added_ro) {          error ("mount: block device %s is not permitted on its filesystem",		 spec);          break;      } else {         added_ro = 1;	 if (loop) {	     opts = opts0;	     type = type0;	 }         if (opts) {             opts = realloc(xstrdup(opts), strlen(opts)+4);             strcat(opts, ",ro");         } else             opts = "ro";	 if (type && !strcmp(type, "guess"))	     type = 0;         error ("mount: %s%s is write-protected, mounting read-only",		loop ? "" : "block device ", spec0);	 return try_mount_one (spec0, node0, type, opts, freq, pass, bg);      }      break;    default:      error ("mount: %s", strerror (mnt_err)); break;    }  return EX_FAIL;}/* * set_proc_name() *	Update the argument vector, so that this process may be easily *	identified in a "ps" listing. */static voidset_proc_name (char *spec){#ifdef DO_PS_FIDDLING  int i, l;  /*   * Move the environment so we can reuse the memory.   * (Code borrowed from sendmail.)   * WARNING: ugly assumptions on memory layout here; if this ever causes   *          problems, #undef DO_PS_FIDDLING   */  for (i = 0; envp0[i] != NULL; i++)    continue;  environ = (char **) xmalloc(sizeof(char *) * (i + 1));  for (i = 0; envp0[i] != NULL; i++)    environ[i] = xstrdup(envp0[i]);  environ[i] = NULL;  if (i > 0)    l = envp0[i-1] + strlen(envp0[i-1]) - argv0[0];  else    l = argv0[argc0-1] + strlen(argv0[argc0-1]) - argv0[0];  if (l > sizeof(PROC_NAME)) {    strcpy(argv0[0], PROC_NAME);    strncpy(argv0[0] + sizeof(PROC_NAME) - 1, spec, l - sizeof(PROC_NAME) - 1);    argv0[1] = NULL;  }#endif}intmount_one (char *spec, char *node, char *type, char *opts, char *cmdlineopts,	   int freq, int pass){  int status;  int status2;  /* Merge the fstab and command line options.  */  if (opts == NULL)       opts = cmdlineopts;  else if (cmdlineopts != NULL)       opts = xstrconcat3(opts, ",", cmdlineopts);  if (type == NULL) {      if (strchr (spec, ':') != NULL) {	type = "nfs";	if (mount_verbose)	  printf("mount: no type was given - "		 "I'll assume nfs because of the colon\n");      }  }  /*   * Try to mount the file system. When the exit status is EX_BG,   * we will retry in the background. Otherwise, we're done.   */  status = try_mount_one (spec, node, type, opts, freq, pass, 0);  if (status != EX_BG)    return status;  /*   * Retry in the background.   */  printf ("mount: backgrounding \"%s\"\n", spec);  fflush( stdout );		/* prevent duplicate output */  if (fork() > 0)    return 0;			/* parent returns "success" */  spec = xstrdup(spec);		/* arguments will be destroyed */  node = xstrdup(node);		/* by set_proc_name()          */  type = xstrdup(type);  opts = xstrdup(opts);  set_proc_name (spec);		/* make a nice "ps" listing */  status2 = try_mount_one (spec, node, type, opts, freq, pass, 1);  if (mount_verbose && status2)    printf ("mount: giving up \"%s\"\n", spec);  exit (0);			/* child stops here */}/* Check if an fsname/dir pair was already in the old mtab.  */static intmounted (char *spec, char *node) {     struct mntentchn *mc;     spec = canonicalize (spec);     node = canonicalize (node);     for (mc = mtab_head()->nxt; mc; mc = mc->nxt)	  if (streq (spec, mc->mnt_fsname) && streq (node, mc->mnt_dir))	       return 1;     return 0;}/* Mount all filesystems of the specified types except swap and root.  *//* With the --fork option: fork and let different incarnations of   mount handle different filesystems.  However, try to avoid several   simultaneous mounts on the same physical disk, since that is very slow. */#define DISKMAJOR(m)	(((int) m) & ~0xf)static intmount_all (string_list types, char *options) {     struct mntentchn *mc, *mtmp;     int status = 0;     struct stat statbuf;     struct child {	  pid_t pid;	  char *group;	  struct mntentchn *mec;	  struct mntentchn *meclast;	  struct child *nxt;     } childhead, *childtail, *cp;     char major[22];     char *g, *colon;     /* build a chain of what we have to do, or maybe	several chains, one for each major or NFS host */     childhead.nxt = 0;     childtail = &childhead;     for (mc = fstab_head()->nxt; mc; mc = mc->nxt) {	  if (matching_type (mc->mnt_type, types)	      && !streq (mc->mnt_dir, "/")	      && !streq (mc->mnt_dir, "root")) {	       if (mounted (mc->mnt_fsname, mc->mnt_dir)) {		    if (mount_verbose)			 printf("mount: %s already mounted on %s\n",				mc->mnt_fsname, mc->mnt_dir);	       } else {		    mtmp = (struct mntentchn *) xmalloc(sizeof(*mtmp));		    *mtmp = *mc;		    mtmp->nxt = 0;		    g = NULL;		    if (optfork) {			 if (stat(mc->mnt_fsname, &statbuf) == 0 &&			     S_ISBLK(statbuf.st_mode)) {			      sprintf(major, "#%x", DISKMAJOR(statbuf.st_rdev));			      g = major;			 }#if HAVE_NFS			 if (strcmp(mc->mnt_type, "nfs") == 0) {			      g = xstrdup(mc->mnt_fsname);			      colon = strchr(g, ':');			      if (colon)				   *colon = '\0';			 }#endif		    }		    if (g) {			 for (cp = childhead.nxt; cp; cp = cp->nxt)			      if (cp->group && strcmp(cp->group, g) == 0) {				   cp->meclast->nxt = mtmp;				   cp->meclast = mtmp;				   goto fnd;			      }		    }		    cp = (struct child *) xmalloc(sizeof *cp);		    cp->nxt = 0;		    cp->mec = cp->meclast = mtmp;		    cp->group = xstrdup(g);		    cp->pid = 0;		    childtail->nxt = cp;		    childtail = cp;	       fnd:;	       }	  }     }			           /* now do everything */     for (cp = childhead.nxt; cp; cp = cp->nxt) {	  pid_t p = -1;	  if (optfork) {	       p = fork();	       if (p == -1)		    error("mount: cannot fork: %s", strerror (errno));	       else if (p != 0)		    cp->pid = p;	  }	  /* if child, or not forked, do the mounting */	  if (p == 0 || p == -1) {	       for (mc = cp->mec; mc; mc = mc->nxt)		    status |= mount_one (mc->mnt_fsname, mc->mnt_dir,					 mc->mnt_type, mc->mnt_opts,					 options, 0, 0);	       if (mountcount)		    status |= EX_SOMEOK;	       if (p == 0)		    exit(status);	  }     }     /* wait for children, if any */     while ((cp = childhead.nxt) != NULL) {	  childhead.nxt = cp->nxt;	  if (cp->pid) {	       int ret;	  keep_waiting:	       if(waitpid(cp->pid, &ret, 0) == -1) {		    if (errno == EINTR)			 goto keep_waiting;		    perror("waitpid");	       } else if (WIFEXITED(ret))		    status |= WEXITSTATUS(ret);	       else		    status |= EX_SYSERR;	  }     }     if (mountcount)	  status |= EX_SOMEOK;     return status;}extern char version[];static struct option longopts[] ={  { "all", 0, 0, 'a' },  { "fake", 0, 0, 'f' },  { "fork", 0, 0, 'F' },  { "help", 0, 0, 'h' },  { "no-mtab", 0, 0, 'n' },  { "read-only", 0, 0, 'r' },  { "ro", 0, 0, 'r' },  { "mount_verbose", 0, 0, 'v' },  { "version", 0, 0, 'V' },  { "read-write", 0, 0, 'w' },  { "rw", 0, 0, 'w' },  { "options", 1, 0, 'o' },  { "types", 1, 0, 't' },  { NULL, 0, 0, 0 }};const char *mount_usage_string = "\usage: mount [-hV]\n\       mount -a [-nfFrsvw] [-t vfstypes]\n\       mount [-nfrsvw] [-o options] special | node\n\       mount [-nfrsvw] [-t vfstype] [-o options] special node\n\";static voidusage (FILE *fp, int n){  fprintf (fp, "%s", mount_usage_string);  unlock_mtab();  exit (n);}intmain_but_defunct (int argc, char *argv[]) {  int c, result = 0;  char *options = NULL, *spec;  string_list types = NULL;  struct mntentchn *mc;  int fd;  /* People report that a mount called from init without console     writes error messages to /etc/mtab     Let us try to avoid getting fd's 0,1,2 */  while((fd = open("/dev/null", O_RDWR)) == 0 || fd == 1 || fd == 2) ;  if (fd > 2)     close(fd);#ifdef DO_PS_FIDDLING  argc0 = argc;  argv0 = argv;  envp0 = environ;#endif  while ((c = getopt_long (argc, argv, "afFhno:rsvVwt:", longopts, NULL))	 != EOF)    switch (c) {      case 'a':			/* mount everything in fstab */	++all;	break;      case 'f':			/* fake (don't actually do mount(2) call) */	++fake;	break;      case 'F':	++optfork;	break;      case 'h':			/* help */	usage (stdout, 0);	break;      case 'n':			/* mount without writing in /etc/mtab */	++mount_nomtab;	break;      case 'o':			/* specify mount options */	if (options)	     options = xstrconcat3(options, ",", optarg);	else	     options = xstrdup(optarg);	break;      case 'r':			/* mount readonly */	readonly = 1;	readwrite = 0;	break;      case 's':			/* allow sloppy mount options */	sloppy = 1;	break;      case 't':			/* specify file system types */	types = parse_list (optarg);	break;      case 'v':			/* be chatty - very chatty if repeated */	++mount_verbose;	break;      case 'V':			/* version */	printf ("mount: %s\n", version);	exit (0);      case 'w':			/* mount read/write */	readwrite = 1;	readonly = 0;	break;      case 0:	break;      case '?':      default:	usage (stderr, EX_USAGE);    }  argc -= optind;  argv += optind;  if (argc == 0 && !all) {      if (options)	usage (stderr, EX_USAGE);      return print_all (types);  }  if (getuid () != geteuid ()) {      mount_suid = 1;      if (types || options || readwrite || mount_nomtab || all || fake || argc != 1)	die (EX_USAGE, "mount: only root can do that");  }  if (!mount_nomtab && mtab_does_not_exist()) {       if (mount_verbose > 1)	    printf("mount: no %s found - creating it..\n", MOUNTED);       create_mtab ();  }  switch (argc) {    case 0:      /* mount -a */      result = mount_all (types, options);      if (result == 0 && mount_verbose)	   error("not mounted anything");      break;    case 1:      /* mount [-nfrvw] [-o options] special | node */      if (types != NULL)	usage (stderr, EX_USAGE);      /* Try to find the other pathname in fstab.  */      spec = canonicalize (*argv);      if ((mc = getmntfile (spec)) == NULL &&	  (mc = getfsspec (spec)) == NULL &&	  (mc = getfsfile (spec)) == NULL &&	     /* Try noncanonical name in fstab	        perhaps /dev/cdrom or /dos is a symlink */	  (mc = getfsspec (*argv)) == NULL &&	  (mc = getfsfile (*argv)) == NULL)	   die (EX_USAGE, "mount: can't find %s in %s or %s",		spec, MOUNTED, _PATH_FSTAB);      result = mount_one (xstrdup (mc->mnt_fsname), xstrdup (mc->mnt_dir),			  xstrdup (mc->mnt_type), mc->mnt_opts, options, 0, 0);      break;    case 2:      /* mount [-nfrvw] [-t vfstype] [-o options] special node */      if (types == NULL)	result = mount_one (argv[0], argv[1],			    NULL, NULL, options, 0, 0);      else if (cdr (types) == NULL)	result = mount_one (argv[0], argv[1],			    car (types), NULL, options, 0, 0);      else	usage (stderr, EX_USAGE);      break;          default:      usage (stderr, EX_USAGE);  }  if (result == EX_SOMEOK)       result = 0;  exit (result);}

⌨️ 快捷键说明

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