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

📄 mount_guess_fstype.c

📁 linux下mount各种文件系统的程序submount的源代码
💻 C
字号:
/* 2003-05-14 Eugene S. Weiss <eweiss@sbcglobal.net> Added the central * routine, do_guess_fstype(), to submountd, adding the necessary support * functions, and removing unnecessary material from the file.  Also added * a few new fat identifiers. *//* * Thu Jul 14 07:32:40 1994: faith@cs.unc.edu added changes from Adam * J. Richter (adam@adam.yggdrasil.com) so that /proc/filesystems is used * if no -t option is given.  I modified his patches so that, if * /proc/filesystems is not available, the behavior of mount is the same as * it was previously. * * Wed Feb 8 09:23:18 1995: Mike Grupenhoff <kashmir@umiacs.UMD.EDU> added * a probe of the superblock for the type before /proc/filesystems is * checked. * * Fri Apr  5 01:13:33 1996: quinlan@bucknell.edu, fixed up iso9660 autodetect * * Wed Nov  11 11:33:55 1998: K.Garloff@ping.de, try /etc/filesystems before * /proc/filesystems * [This was mainly in order to specify vfat before fat; these days we often *  detect *fat and then assume vfat, so perhaps /etc/filesystems isnt *  so useful anymore.] * * 1999-02-22 Arkadiusz Mi秌iewicz <misiek@pld.ORG.PL> * added Native Language Support * * 2000-12-01 Sepp Wijnands <mrrazz@garbage-coderz.net> * added probes for cramfs, hfs, hpfs and adfs. * * 2001-10-26 Tim Launchbury * added sysv magic. * * aeb - many changes. * */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <fcntl.h>#include <errno.h>#include <unistd.h>#include <malloc.h>#include <sys/stat.h>#include <sys/types.h>#include <syslog.h>#include "submountd.h"#include "linux_fs.h"#define ETC_FILESYSTEMS		"/etc/filesystems"#define PROC_FILESYSTEMS	"/proc/filesystems"#define SIZE(a) (sizeof(a)/sizeof(a[0]))void *xmalloc (size_t size) {     void *t;     if (size == 0)          return NULL;     t = malloc (size);     if (t == NULL)          ERR("not enough memory\n");     return t;}char *xstrdup (const char *s) {	char *t;	if (s == NULL)		return NULL;	t = strdup (s);	if (t == NULL) {		ERR("not enough memory\n");		exit(1);	}	return t;}/* Most file system types can be recognized by a `magic' number   in the superblock.  Note that the order of the tests is   significant: by coincidence a filesystem can have the   magic numbers for several file system types simultaneously.   For example, the romfs magic lives in the 1st sector;   xiafs does not touch the 1st sector and has its magic in   the 2nd sector; ext2 does not touch the first two sectors. */static inline unsigned shortswapped(unsigned short a) {     return (a>>8) | (a<<8);}/*    char *guess_fstype(const char *device);    Probes the device and attempts to determine the type of filesystem    contained within.    Original routine by <jmorriso@bogomips.ww.ubc.ca>; made into a function    for mount(8) by Mike Grupenhoff <kashmir@umiacs.umd.edu>.    Corrected the test for xiafs - aeb    Read the superblock only once - aeb    Added a very weak heuristic for vfat - aeb    Added iso9660, minix-v2, romfs, qnx4, udf, vxfs, swap - aeb    Added a test for high sierra (iso9660) - quinlan@bucknell.edu    Added ufs from a patch by jj. But maybe there are several types of ufs?    Added ntfs from a patch by Richard Russon.    Added xfs - 2000-03-21 Martin K. Petersen <mkp@linuxcare.com>    Added cramfs, hfs, hpfs, adfs - Sepp Wijnands <mrrazz@garbage-coderz.net>    Added ext3 - Andrew Morton    Added jfs - Christoph Hellwig    Added sysv - Tim Launchbury    Added udf - Bryce Nesbitt*//* * udf magic - I find that trying to mount garbage as an udf fs * causes a very large kernel delay, almost killing the machine. * So, we do not try udf unless there is positive evidence that it * might work. Strings below taken from ECMA 167. *//* * It seems that before udf 2.00 the volume descriptor was not well * defined.  For 2.00 you're supposed to keep scanning records until * you find one NOT in this list.  (See ECMA 2/8.3.1). */static char*udf_magic[] = { "BEA01", "BOOT2", "CD001", "CDW02", "NSR02",		 "NSR03", "TEA01" };static intmay_be_udf(const char *id) {    char **m;    for (m = udf_magic; m - udf_magic < SIZE(udf_magic); m++)       if (!strncmp(*m, id, 5))	  return 1;    return 0;}/* we saw "CD001" - may be iso9660 or udf - Bryce Nesbitt */static intis_really_udf(int fd) {	int j, bs;	struct iso_volume_descriptor isosb;	/* determine the block size by scanning in 2K increments	   (block sizes larger than 2K will be null padded) */	for (bs = 1; bs < 16; bs++) {		lseek(fd, bs*2048+32768, SEEK_SET);		if (read(fd, (char *)&isosb, sizeof(isosb)) != sizeof(isosb))			return 0;		if (isosb.id[0])			break;	}	/* Scan up to another 64 blocks looking for additional VSD's */	for (j = 1; j < 64; j++) {		if (j > 1) {			lseek(fd, j*bs*2048+32768, SEEK_SET);			if (read(fd, (char *)&isosb, sizeof(isosb))			    != sizeof(isosb))				return 0;		}		/* If we find NSR0x then call it udf:		   NSR01 for UDF 1.00		   NSR02 for UDF 1.50		   NSR03 for UDF 2.00 */		if (!strncmp(isosb.id, "NSR0", 4))			return 1;		if (!may_be_udf(isosb.id))			return 0;	}	return 0;}static intmay_be_swap(const char *s) {	return (strncmp(s-10, "SWAP-SPACE", 10) == 0 ||		strncmp(s-10, "SWAPSPACE2", 10) == 0);}/* rather weak necessary condition */static intmay_be_adfs(const u_char *s) {	u_char *p;	int sum;	p = (u_char *) s + 511;	sum = 0;	while(--p != s)		sum = (sum >> 8) + (sum & 0xff) + *p;	return (sum == p[511]);}static int is_reiserfs_magic_string (struct reiserfs_super_block * rs){    return (!strncmp (rs->s_magic, REISERFS_SUPER_MAGIC_STRING, 		      strlen ( REISERFS_SUPER_MAGIC_STRING)) ||	    !strncmp (rs->s_magic, REISER2FS_SUPER_MAGIC_STRING, 		      strlen ( REISER2FS_SUPER_MAGIC_STRING)));}char *do_guess_fstype(const char *device) {    int fd;    char *type = NULL;    union {	struct minix_super_block ms;	struct ext_super_block es;	struct ext2_super_block e2s;	struct vxfs_super_block vs;    } sb;			/* stuff at 1024 */    union {	struct xiafs_super_block xiasb;	char romfs_magic[8];	char qnx4fs_magic[10];	/* ignore first 4 bytes */	long bfs_magic;	struct ntfs_super_block ntfssb;	struct fat_super_block fatsb;	struct xfs_super_block xfsb;	struct cramfs_super_block cramfssb;    } xsb;    struct ufs_super_block ufssb;    union {	struct iso_volume_descriptor iso;	struct hs_volume_descriptor hs;    } isosb;    struct reiserfs_super_block reiserfssb;	/* block 64 or 8 */    struct jfs_super_block jfssb;		/* block 32 */    struct hfs_super_block hfssb;    struct hpfs_super_block hpfssb;    struct adfs_super_block adfssb;    struct sysv_super_block svsb;    struct stat statbuf;    /* opening and reading an arbitrary unknown path can have       undesired side effects - first check that `device' refers       to a block device or ordinary file */    if (stat (device, &statbuf) ||	!(S_ISBLK(statbuf.st_mode) || S_ISREG(statbuf.st_mode)))      return 0;    fd = open(device, O_RDONLY);    if (fd < 0)      return 0;    /* do seeks and reads in disk order, otherwise a very short       partition may cause a failure because of read error */    if (!type) {	 /* block 0 */	 if (lseek(fd, 0, SEEK_SET) != 0	     || read(fd, (char *) &xsb, sizeof(xsb)) != sizeof(xsb))	      goto try_iso9660;	 /* Gyorgy Kovesdi: none of my photocds has a readable block 0 */	 if (xiafsmagic(xsb.xiasb) == _XIAFS_SUPER_MAGIC)	      type = "xiafs";	 else if(!strncmp(xsb.romfs_magic, "-rom1fs-", 8))	      type = "romfs";	 else if(!strncmp(xsb.xfsb.s_magic, XFS_SUPER_MAGIC, 4))	      type = "xfs";	 else if(!strncmp(xsb.qnx4fs_magic+4, "QNX4FS", 6))	      type = "qnx4";	 else if(xsb.bfs_magic == 0x1badface)	      type = "bfs";	 else if(!strncmp(xsb.ntfssb.s_magic, NTFS_SUPER_MAGIC,			  sizeof(xsb.ntfssb.s_magic)))	      type = "ntfs";	 else if(cramfsmagic(xsb.cramfssb) == CRAMFS_SUPER_MAGIC ||		 cramfsmagic(xsb.cramfssb) == CRAMFS_SUPER_MAGIC_BE)	      type = "cramfs";	 else if (((!strncmp(xsb.fatsb.s_os, "MSDOS", 5) ||		!strncmp(xsb.fatsb.s_os, "MSWIN", 5) ||		!strncmp(xsb.fatsb.s_os, "MTOOL", 5) ||		!strncmp(xsb.fatsb.s_os, "mkdosfs", 7) ||		!strncmp(xsb.fatsb.s_os, "kmkdosfs", 8) ||		!strncmp(xsb.fatsb.s_os, "SYSLINUX", 8) ||		/* Michal Svec: created by fdformat, old msdos utility for		   formatting large (1.7) floppy disks. */		!strncmp(xsb.fatsb.s_os, "CH-FOR18", 8))		&& (!strncmp(xsb.fatsb.s_fs, "FAT12   ", 8) ||		!strncmp(xsb.fatsb.s_fs, "FAT16   ", 8) ||		!strncmp(xsb.fatsb.s_fs2, "FAT32   ", 8)))        	|| (!strncmp(xsb.fatsb.s_os, "FreeDOS", 7))        	|| (!strncmp(xsb.fatsb.s_os, "TracerST", 8)))		type = "vfat";	/* only guessing - might as well be fat or umsdos */    }    if (!type) {	    /* sector 1 */	    if (lseek(fd, 512 , SEEK_SET) != 512		|| read(fd, (char *) &svsb, sizeof(svsb)) != sizeof(svsb))		    goto io_error;	    if (sysvmagic(svsb) == SYSV_SUPER_MAGIC )		    type = "sysv";    }    if (!type) {	/* block 1 */	if (lseek(fd, 1024, SEEK_SET) != 1024 ||	    read(fd, (char *) &sb, sizeof(sb)) != sizeof(sb))		goto io_error;	/* ext2 has magic in little-endian on disk, so "swapped" is	   superfluous; however, there have existed strange byteswapped	   PPC ext2 systems */	if (ext2magic(sb.e2s) == EXT2_SUPER_MAGIC ||	    ext2magic(sb.e2s) == EXT2_PRE_02B_MAGIC ||	    ext2magic(sb.e2s) == swapped(EXT2_SUPER_MAGIC)) {		type = "ext2";	     /* maybe even ext3? */	     if ((assemble4le(sb.e2s.s_feature_compat)		  & EXT3_FEATURE_COMPAT_HAS_JOURNAL) &&		 assemble4le(sb.e2s.s_journal_inum) != 0)		     type = "ext3";	/* "ext3,ext2" */	}	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 (is_reiserfs_magic_string(&reiserfssb))	    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 (is_reiserfs_magic_string(&reiserfssb))	    type = "reiserfs";    }    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)	 ERR("error while guessing filesystem type %s\n", strerror(errno));    else	 ERR("error while guessing filesystem type\n");    close(fd);    return 0;}

⌨️ 快捷键说明

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