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

📄 fstab.c

📁 Util-linux 软件包包含许多工具。其中比较重要的是加载、卸载、格式化、分区和管理硬盘驱动器
💻 C
📖 第 1 页 / 共 2 页
字号:
/* 1999-02-22 Arkadiusz Mi秌iewicz <misiek@pld.ORG.PL> * - added Native Language Support * Sun Mar 21 1999 - Arnaldo Carvalho de Melo <acme@conectiva.com.br> * - fixed strerr(errno) in gettext calls */#include <unistd.h>#include <errno.h>#include <stdio.h>#include <string.h>#include <sys/stat.h>#include "mntent.h"#include "fstab.h"#include "sundries.h"		/* for xmalloc() etc */#include "mount_blkid.h"#include "paths.h"#include "nls.h"#define streq(s, t)	(strcmp ((s), (t)) == 0)#define PROC_MOUNTS		"/proc/mounts"/* Information about mtab. ------------------------------------*/static int have_mtab_info = 0;static int var_mtab_does_not_exist = 0;static int var_mtab_is_a_symlink = 0;static voidget_mtab_info(void) {	struct stat mtab_stat;	if (!have_mtab_info) {		if (lstat(MOUNTED, &mtab_stat))			var_mtab_does_not_exist = 1;		else if (S_ISLNK(mtab_stat.st_mode))			var_mtab_is_a_symlink = 1;		have_mtab_info = 1;	}}intmtab_does_not_exist(void) {	get_mtab_info();	return var_mtab_does_not_exist;}intmtab_is_a_symlink(void) {	get_mtab_info();	return var_mtab_is_a_symlink;}intmtab_is_writable() {	static int ret = -1;	/* Should we write to /etc/mtab upon an update?	   Probably not if it is a symlink to /proc/mounts, since that	   would create a file /proc/mounts in case the proc filesystem	   is not mounted. */	if (mtab_is_a_symlink())		return 0;	if (ret == -1) {		int fd = open(MOUNTED, O_RDWR | O_CREAT, 0644);		if (fd >= 0) {			close(fd);			ret = 1;		} else			ret = 0;	}	return ret;}/* Contents of mtab and fstab ---------------------------------*/struct mntentchn mounttable, fstab;static int got_mtab = 0;static int got_fstab = 0;static void read_mounttable(void), read_fstab(void);struct mntentchn *mtab_head() {	if (!got_mtab)		read_mounttable();	return &mounttable;}struct mntentchn *fstab_head() {	if (!got_fstab)		read_fstab();	return &fstab;}static voidmy_free(const void *s) {	if (s)		free((void *) s);}static voiddiscard_mntentchn(struct mntentchn *mc0) {	struct mntentchn *mc, *mc1;	for (mc = mc0->nxt; mc && mc != mc0; mc = mc1) {		mc1 = mc->nxt;		my_free(mc->m.mnt_fsname);		my_free(mc->m.mnt_dir);		my_free(mc->m.mnt_type);		my_free(mc->m.mnt_opts);		free(mc);	}}static voidread_mntentchn(mntFILE *mfp, const char *fnam, struct mntentchn *mc0) {	struct mntentchn *mc = mc0;	struct my_mntent *mnt;	while ((mnt = my_getmntent(mfp)) != NULL) {		if (!streq(mnt->mnt_type, MNTTYPE_IGNORE)) {			mc->nxt = (struct mntentchn *) xmalloc(sizeof(*mc));			mc->nxt->prev = mc;			mc = mc->nxt;			mc->m = *mnt;			mc->nxt = mc0;		}	}	mc0->prev = mc;	if (ferror(mfp->mntent_fp)) {		int errsv = errno;		error(_("warning: error reading %s: %s"),		      fnam, strerror (errsv));		mc0->nxt = mc0->prev = NULL;	}	my_endmntent(mfp);}/* * Read /etc/mtab.  If that fails, try /proc/mounts. * This produces a linked list. The list head mounttable is a dummy. * Return 0 on success. */static voidread_mounttable() {	mntFILE *mfp;	const char *fnam;	struct mntentchn *mc = &mounttable;	got_mtab = 1;	mc->nxt = mc->prev = NULL;	fnam = MOUNTED;	mfp = my_setmntent (fnam, "r");	if (mfp == NULL || mfp->mntent_fp == NULL) {		int errsv = errno;		fnam = PROC_MOUNTS;		mfp = my_setmntent (fnam, "r");		if (mfp == NULL || mfp->mntent_fp == NULL) {			error(_("warning: can't open %s: %s"),			      MOUNTED, strerror (errsv));			return;		}		if (verbose)			printf (_("mount: could not open %s - "				  "using %s instead\n"),				MOUNTED, PROC_MOUNTS);	}	read_mntentchn(mfp, fnam, mc);}static voidread_fstab() {	mntFILE *mfp = NULL;	const char *fnam;	struct mntentchn *mc = &fstab;	got_fstab = 1;	mc->nxt = mc->prev = NULL;	fnam = _PATH_FSTAB;	mfp = my_setmntent (fnam, "r");	if (mfp == NULL || mfp->mntent_fp == NULL) {		int errsv = errno;		error(_("warning: can't open %s: %s"),		      _PATH_FSTAB, strerror (errsv));		return;	}	read_mntentchn(mfp, fnam, mc);}     /* Given the name NAME, try to find it in mtab.  */ struct mntentchn *getmntfile (const char *name) {	struct mntentchn *mc, *mc0;	mc0 = mtab_head();	for (mc = mc0->nxt; mc && mc != mc0; mc = mc->nxt)		if (streq(mc->m.mnt_dir, name) ||		    streq(mc->m.mnt_fsname, name))			return mc;	return NULL;}/* * Given the directory name NAME, and the place MCPREV we found it last time, * try to find more occurrences. */ struct mntentchn *getmntdirbackward (const char *name, struct mntentchn *mcprev) {	struct mntentchn *mc, *mc0;	mc0 = mtab_head();	if (!mcprev)		mcprev = mc0;	for (mc = mcprev->prev; mc && mc != mc0; mc = mc->prev)		if (streq(mc->m.mnt_dir, name))			return mc;	return NULL;}/* * Given the device name NAME, and the place MCPREV we found it last time, * try to find more occurrences. */ struct mntentchn *getmntdevbackward (const char *name, struct mntentchn *mcprev) {	struct mntentchn *mc, *mc0;	mc0 = mtab_head();	if (!mcprev)		mcprev = mc0;	for (mc = mcprev->prev; mc && mc != mc0; mc = mc->prev)		if (streq(mc->m.mnt_fsname, name))			return mc;	return NULL;}/* * Given the name NAME, check that it occurs precisely once as dir or dev. */intis_mounted_once(const char *name) {	struct mntentchn *mc, *mc0;	int ct = 0;	mc0 = mtab_head();	for (mc = mc0->prev; mc && mc != mc0; mc = mc->prev)		if (streq(mc->m.mnt_dir, name) ||		    streq(mc->m.mnt_fsname, name))			ct++;	return (ct == 1);}/* Given the name FILE, try to find the option "loop=FILE" in mtab.  */ struct mntentchn *getmntoptfile (const char *file) {	struct mntentchn *mc, *mc0;	const char *opts, *s;	int l;	if (!file)		return NULL;	l = strlen(file);	mc0 = mtab_head();	for (mc = mc0->nxt; mc && mc != mc0; mc = mc->nxt)		if ((opts = mc->m.mnt_opts) != NULL		    && (s = strstr(opts, "loop="))		    && !strncmp(s+5, file, l)		    && (s == opts || s[-1] == ',')		    && (s[l+5] == 0 || s[l+5] == ','))			return mc;	return NULL;}static inthas_label(const char *device, const char *label) {	const char *devlabel;	int ret;	devlabel = mount_get_volume_label_by_spec(device);	ret = !strcmp(label, devlabel);	/* free(devlabel); */	return ret;}static inthas_uuid(const char *device, const char *uuid){	const char *devuuid;	int ret;	devuuid = mount_get_devname_by_uuid(device);	ret = !strcmp(uuid, devuuid);	/* free(devuuid); */	return ret;}/* Find the entry (SPEC,FILE) in fstab */struct mntentchn *getfsspecfile (const char *spec, const char *file) {	struct mntentchn *mc, *mc0;	mc0 = fstab_head();	/* first attempt: names occur precisely as given */	for (mc = mc0->nxt; mc && mc != mc0; mc = mc->nxt)		if (streq(mc->m.mnt_dir, file) &&		    streq(mc->m.mnt_fsname, spec))			return mc;	/* second attempt: names found after symlink resolution */	for (mc = mc0->nxt; mc && mc != mc0; mc = mc->nxt)		if ((streq(mc->m.mnt_dir, file) ||		     streq(canonicalize(mc->m.mnt_dir), file))		    && (streq(mc->m.mnt_fsname, spec) ||			streq(canonicalize(mc->m.mnt_fsname), spec)))			return mc;	/* third attempt: names found after LABEL= or UUID= resolution */	for (mc = mc0->nxt; mc && mc != mc0; mc = mc->nxt) {		if (!strncmp (mc->m.mnt_fsname, "LABEL=", 6) &&		    (streq(mc->m.mnt_dir, file) ||		     streq(canonicalize(mc->m.mnt_dir), file))) {			if (has_label(spec, mc->m.mnt_fsname+6))				return mc;		}		if (!strncmp (mc->m.mnt_fsname, "UUID=", 5) &&

⌨️ 快捷键说明

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