📄 mount_guess_fstype.c
字号:
else if (minixmagic(sb.ms) == MINIX_SUPER_MAGIC || minixmagic(sb.ms) == MINIX_SUPER_MAGIC2 || minixmagic(sb.ms) == swapped(MINIX_SUPER_MAGIC2) || minixmagic(sb.ms) == MINIX2_SUPER_MAGIC || minixmagic(sb.ms) == MINIX2_SUPER_MAGIC2) type = "minix"; else if (extmagic(sb.es) == EXT_SUPER_MAGIC) type = "ext"; else if (vxfsmagic(sb.vs) == VXFS_SUPER_MAGIC) type = "vxfs"; } if (!type) { /* block 1 */ if (lseek(fd, 0x400, SEEK_SET) != 0x400 || read(fd, (char *) &hfssb, sizeof(hfssb)) != sizeof(hfssb)) goto io_error; /* also check if block size is equal to 512 bytes, or a multiple. (I see 1536 here.) */ if (hfsmagic(hfssb) == HFS_SUPER_MAGIC && /* always BE */ hfsblksize(hfssb) != 0 && (hfsblksize(hfssb) & 0x1ff) == 0) type = "hfs"; } if (!type) { /* block 3 */ if (lseek(fd, 0xc00, SEEK_SET) != 0xc00 || read(fd, (char *) &adfssb, sizeof(adfssb)) != sizeof(adfssb)) goto io_error; /* only a weak test */ if (may_be_adfs((u_char *) &adfssb) && (adfsblksize(adfssb) >= 8 && adfsblksize(adfssb) <= 10)) type = "adfs"; } if (!type) { int mag; /* block 8 */ if (lseek(fd, 8192, SEEK_SET) != 8192 || read(fd, (char *) &ufssb, sizeof(ufssb)) != sizeof(ufssb)) goto io_error; mag = ufsmagic(ufssb); if (mag == UFS_SUPER_MAGIC_LE || mag == UFS_SUPER_MAGIC_BE) type = "ufs"; } if (!type) { /* block 8 */ if (lseek(fd, REISERFS_OLD_DISK_OFFSET_IN_BYTES, SEEK_SET) != REISERFS_OLD_DISK_OFFSET_IN_BYTES || read(fd, (char *) &reiserfssb, sizeof(reiserfssb)) != sizeof(reiserfssb)) goto io_error; if (reiserfs_magic_version(reiserfssb.s_magic)) type = "reiserfs"; } if (!type) { /* block 8 */ if (lseek(fd, 0x2000, SEEK_SET) != 0x2000 || read(fd, (char *) &hpfssb, sizeof(hpfssb)) != sizeof(hpfssb)) goto io_error; if (hpfsmagic(hpfssb) == HPFS_SUPER_MAGIC) type = "hpfs"; } if (!type) { /* block 32 */ if (lseek(fd, JFS_SUPER1_OFF, SEEK_SET) != JFS_SUPER1_OFF || read(fd, (char *) &jfssb, sizeof(jfssb)) != sizeof(jfssb)) goto io_error; if (!strncmp(jfssb.s_magic, JFS_MAGIC, 4)) type = "jfs"; } if (!type) { /* block 32 */ try_iso9660: if (lseek(fd, 0x8000, SEEK_SET) != 0x8000 || read(fd, (char *) &isosb, sizeof(isosb)) != sizeof(isosb)) goto io_error; if (strncmp(isosb.hs.id, HS_STANDARD_ID, sizeof(isosb.hs.id)) == 0) { /* "CDROM" */ type = "iso9660"; } else if (strncmp(isosb.iso.id, ISO_STANDARD_ID, sizeof(isosb.iso.id)) == 0) { /* CD001 */ type = "iso9660"; if (is_really_udf(fd)) type = "udf"; } else if (may_be_udf(isosb.iso.id)) type = "udf"; } if (!type) { /* block 64 */ if (lseek(fd, REISERFS_DISK_OFFSET_IN_BYTES, SEEK_SET) != REISERFS_DISK_OFFSET_IN_BYTES || read(fd, (char *) &reiserfssb, sizeof(reiserfssb)) != sizeof(reiserfssb)) goto io_error; if (reiserfs_magic_version(reiserfssb.s_magic)) type = "reiserfs"; } if (!type) { int blksize, blkoff; for (blksize = OCFS2_MIN_BLOCKSIZE; blksize <= OCFS2_MAX_BLOCKSIZE; blksize <<= 1) { blkoff = blksize * OCFS2_SUPER_BLOCK_BLKNO; if (lseek(fd, blkoff, SEEK_SET) != blkoff || read(fd, (char *) &osb, sizeof(osb)) != sizeof(osb)) goto io_error; if (strncmp(osb.signature, OCFS2_SUPER_BLOCK_SIGNATURE, sizeof(OCFS2_SUPER_BLOCK_SIGNATURE)) == 0) type = "ocfs2"; } } if (!type) { /* perhaps the user tries to mount the swap space on a new disk; warn her before she does mke2fs on it */ int pagesize = getpagesize(); int rd; char buf[32768]; rd = pagesize; if (rd < 8192) rd = 8192; if (rd > sizeof(buf)) rd = sizeof(buf); if (lseek(fd, 0, SEEK_SET) != 0 || read(fd, buf, rd) != rd) goto io_error; if (may_be_swap(buf+pagesize) || may_be_swap(buf+4096) || may_be_swap(buf+8192)) type = "swap"; } close (fd); return(type);io_error: if (errno) perror(device); else fprintf(stderr, _("mount: error while guessing filesystem type\n")); close(fd); return 0;}#endifstatic struct tried { struct tried *next; char *type;} *tried = NULL;static intwas_tested(const char *fstype) { struct tried *t; if (known_fstype(fstype)) return 1; for (t = tried; t; t = t->next) { if (!strcmp(t->type, fstype)) return 1; } return 0;}static voidset_tested(const char *fstype) { struct tried *t = xmalloc(sizeof(struct tried)); t->next = tried; t->type = xstrdup(fstype); tried = t;}static voidfree_tested(void) { struct tried *t, *tt; t = tried; while(t) { free(t->type); tt = t->next; free(t); t = tt; } tried = NULL;}char *guess_fstype(const char *spec) { char *type = do_guess_fstype(spec); if (verbose) { printf (_("mount: you didn't specify a filesystem type for %s\n"), spec); if (!type) printf (_(" I will try all types mentioned in %s or %s\n"), ETC_FILESYSTEMS, PROC_FILESYSTEMS); else if (!strcmp(type, "swap")) printf (_(" and it looks like this is swapspace\n")); else printf (_(" I will try type %s\n"), type); } return type;}static char *procfsnext(FILE *procfs) { char line[100]; char fsname[100]; while (fgets(line, sizeof(line), procfs)) { if (sscanf (line, "nodev %[^\n]\n", fsname) == 1) continue; if (sscanf (line, " %[^ \n]\n", fsname) != 1) continue; return xstrdup(fsname); } return 0;}/* Only use /proc/filesystems here, this is meant to test what the kernel knows about, so /etc/filesystems is irrelevant. Return: 1: yes, 0: no, -1: cannot open procfs */intis_in_procfs(const char *type) { FILE *procfs; char *fsname; int ret = -1; procfs = fopen(PROC_FILESYSTEMS, "r"); if (procfs) { ret = 0; while ((fsname = procfsnext(procfs)) != NULL) if (!strcmp(fsname, type)) { ret = 1; break; } fclose(procfs); procfs = NULL; } return ret;}/* Try all types in FILESYSTEMS, except those in *types, in case *types starts with "no" *//* return: 0: OK, -1: error in errno, 1: type not found *//* when 0 or -1 is returned, *types contains the type used *//* when 1 is returned, *types is NULL */intprocfsloop(int (*mount_fn)(struct mountargs *), struct mountargs *args, const char **types) { char *files[2] = { ETC_FILESYSTEMS, PROC_FILESYSTEMS }; FILE *procfs; char *fsname; const char *notypes = NULL; int no = 0; int ret = 1; int errsv = 0; int i; if (*types && !strncmp(*types, "no", 2)) { no = 1; notypes = (*types) + 2; } *types = NULL; /* Use PROC_FILESYSTEMS only when ETC_FILESYSTEMS does not exist. In some cases trying a filesystem that the kernel knows about on the wrong data will crash the kernel; in such cases ETC_FILESYSTEMS can be used to list the filesystems that we are allowed to try, and in the order they should be tried. End ETC_FILESYSTEMS with a line containing a single '*' only, if PROC_FILESYSTEMS should be tried afterwards. */ for (i=0; i<2; i++) { procfs = fopen(files[i], "r"); if (!procfs) continue; while ((fsname = procfsnext(procfs)) != NULL) { if (!strcmp(fsname, "*")) { fclose(procfs); goto nexti; } if (was_tested (fsname)) continue; if (no && matching_type(fsname, notypes)) continue; set_tested (fsname); args->type = fsname; if (verbose) { printf(_("Trying %s\n"), fsname); fflush(stdout); } if ((*mount_fn) (args) == 0) { *types = fsname; ret = 0; break; } else if (errno != EINVAL && is_in_procfs(fsname) == 1) { *types = "guess"; ret = -1; errsv = errno; break; } } free_tested(); fclose(procfs); errno = errsv; return ret; nexti:; } return 1;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -