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

📄 mount.c

📁 linux mount的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	while ((fsname = procnext()) != NULL)	  if (!strcmp(fsname, type))	    return 1;    }    return 0;}#endifstatic intalready (char *spec, char *node) {    return 0;}#if 0/* Create mtab with a root entry.  */static voidcreate_mtab (void) {}#endif/* 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 (*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){  int mnt_err;  int flags;  char *extra_opts;		/* written in mtab */  char *mount_opts;		/* actually used on system call */  char *spec, *node, *type, *opts;  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 (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;  if (!fake && type && streq (type, "nfs")) {#ifdef 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  }  block_signals (SIG_BLOCK);  if (fake      || (try_mount5 (spec, node, &type, flags & ~MS_NOSYS, mount_opts)) == 0)    /* Mount succeeded, report this (if verbose) and write mtab entry.  */    {      block_signals (SIG_UNBLOCK);      return 0;    }  mnt_err = errno;  block_signals (SIG_UNBLOCK);  /* Mount failed */  printf("mount failed \n");  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}static 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 (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 */#ifdef EMBED  printf("mount: not forking...\n");#else  if (fork() > 0)    return 0;			/* parent returns "success" */#endif  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 (verbose && status2)    printf ("mount: giving up \"%s\"\n", spec);  exit (0);			/* child stops here */}#if 0/* 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;}#endif/* 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) {     return -1;}extern char version[];#ifdef EMBED#define	getopt_long(a,b,c,d,e)	getopt(a,b,c)#elsestatic 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' },  { "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 }};#endif#ifndef NAOSI_ABS32const#endifchar *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", usage_string);  unlock_mtab();  exit (n);}intmain (int argc, char *argv[]) {  int c, result = 0;  char *options = NULL;  string_list types = NULL;  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 */	++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 */	++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 ()) {      suid = 1;      if (types || options || readwrite || nomtab || all || fake || argc != 1)	die (EX_USAGE, "mount: only root can do that");  }  switch (argc) {    case 0:      /* mount -a */      result = mount_all (types, options);      if (result == 0 && verbose)	   error("not mounted anything");      break;    case 1:	printf("specify more\n");      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);}#ifdef EMBEDint getdtablesize(){	return(64);}#endif#ifdef NAOSI_ABS32void naosi(void *pp, int *type);static char* naosi_tab[] = {        (char*)naosi,        (char*)naosi_tab,};void naosi(void *ptr, int *type){        int t, dt, dd;        char *p, **pp;        dt = (char*)naosi - naosi_tab[0];        dd = (char*)naosi_tab - naosi_tab[1];        for(pp = (char**)ptr; (t = *type++) >= 0; ++pp){                if((p = *pp) != 0){                        if(t == 1){                                p += dt;                        }else if(t == 2){                                p += dd;                        }                        *pp = p;                }        }}int type_func[] = { 1, -1 };int type_data[] = { 2, -1 };#endif /* NAOSI_ABS32 */#ifdef NAOSI_ABS32#include <linux/init.h>static voidnaosi_mount(){	int i;	/* printf("naosi_mount():\n"); */	for (i = 0; i < sizeof(opt_map) / sizeof(*opt_map); i++) {		naosi(&opt_map[i].opt, type_data);	}	for (i = 0; i < sizeof(string_opt_map) / sizeof(*string_opt_map); i++) {		naosi(&string_opt_map[i].tag, type_data);		naosi(&string_opt_map[i].valptr, type_data);	}	for (i = 0; i < sizeof(magic_known) / sizeof(*magic_known); i++) {		naosi(&magic_known[i], type_data);	}	naosi(&usage_string, type_data);}__initcall(naosi_mount);#endif /* NAOSI_ABS32 */

⌨️ 快捷键说明

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