From 27138ef6d2725a873a9d5cbc4800650026206804 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Thu, 21 Dec 2017 14:11:38 +0000 Subject: [PATCH] mntent: Library methods for managing mtab and fstab We don't use these or hook them in yet but add them ready --- Library/include/mntent.h | 25 +++++++ Library/libs/mntent.c | 150 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 175 insertions(+) create mode 100644 Library/include/mntent.h create mode 100644 Library/libs/mntent.c diff --git a/Library/include/mntent.h b/Library/include/mntent.h new file mode 100644 index 00000000..62d27603 --- /dev/null +++ b/Library/include/mntent.h @@ -0,0 +1,25 @@ +#ifndef _MNTENT_H +#define _MNTENT_H + +struct mntent { + char *mnt_fsname; + char *mnt_dir; + char *mnt_type; + char *mnt_opts; + int mnt_freq; + int mnt_passno; +}; + +#define _MAX_MNTLEN 512 + +/* Standard functions */ +extern FILE *setmntent(char *filep, char *type); +extern struct mntent *getmntent(FILE *fp); +extern int addmntent(FILE *fp, struct mntent *mnt); +extern int endmntent(FILE *fp); +extern char *hasmntopt(struct mntent *mnt, char *opt); + +/* Extended function found in some Unixen */ +extern int delmntent(FILE *fp, struct mntent *mnt); + +#endif diff --git a/Library/libs/mntent.c b/Library/libs/mntent.c new file mode 100644 index 00000000..e1af5d74 --- /dev/null +++ b/Library/libs/mntent.c @@ -0,0 +1,150 @@ +/* + * An implementation of the mountpoint handling library. This one + * handles all the modern quoting rules for spaces in mount entries + * but does not currently implement the delmntent() extension as we + * can't do that easily without ftruncate(). + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +static char mntbuf[_MAX_MNTLEN]; + +FILE *setmntent(char *filep, char *type) +{ + int lock; + FILE *fp = fopen(filep, type); + + if (fp == NULL) + return NULL; + if (strchr(type,'w') || strchr(type,'a')) + lock = LOCK_SH; + else + lock = LOCK_EX; + if (flock(fileno(fp), lock) == -1) { + fclose(fp); + return NULL; + } + return fp; +} + +static int isoct(char c) +{ + if (c >= '0' && c <= '7') + return 1; + return 0; +} + +static int mntparse(char *p, char **t, char *def) +{ + char *d = strtok(p, " \t\n"); + if (d == NULL) + d = def; + else { + /* Dequote */ + char *s = d; + while (*s) { + if (*s == '\\' && isoct(s[1]) && isoct(s[2]) && isoct(s[3])) { + *d++ = ((s[1] - '0') << 6) | ((s[2] - '0') << 3) | (s[3] - '0'); + s += 4; + } else + *d++ = *s++; + } + } + if (t) + *t = d; + return atoi(d); +} + +struct mntent *getmntent(FILE * fp) +{ + static struct mntent me; + char *p = mntbuf; + /* Skip blank lines and comments */ + do { + if (fgets(mntbuf, _MAX_MNTLEN, fp) == NULL) + return NULL; + } while(*p == '\n' || *p == '#'); + mntparse(mntbuf, &me.mnt_fsname, NULL); + mntparse(NULL, &me.mnt_dir, NULL); + mntparse(NULL, &me.mnt_type, "fuzix"); + mntparse(NULL, &me.mnt_opts, ""); + me.mnt_freq = mntparse(NULL, NULL, "0"); + me.mnt_passno = mntparse(NULL, NULL, "0"); + if (me.mnt_fsname == NULL || me.mnt_dir == NULL) + return NULL; + return &me; +} + +void quote_out(char **p, char *s) +{ + char *t = *p; + if (t == NULL) + return; + while (t < mntbuf + _MAX_MNTLEN - 1) { + if (*s == 0) { + *p = t; + return; + } + if (*s == ' ' || *s == '\n' || *s == '\t' || *s == '\\') { + if (t < mntbuf + _MAX_MNTLEN - 5) { + sprintf(t, "\\%3o", *s); + t += 4; + s++; + } else + break; + } else { + *t++ = *s++; + } + } + /* Overrun */ + *p = NULL; +} + +void quote_out_int(char **p, int s) +{ + quote_out(p, _itoa(s)); +} + +int addmntent(FILE * fp, struct mntent *mnt) +{ + char *p = mntbuf; + quote_out(&p, mnt->mnt_fsname); + quote_out(&p, mnt->mnt_dir); + quote_out(&p, mnt->mnt_type); + quote_out(&p, mnt->mnt_opts); + quote_out_int(&p, mnt->mnt_freq); + quote_out_int(&p, mnt->mnt_passno); + if (p) { + *p = '\n'; + if (fwrite(mntbuf, p - mntbuf, 1, fp) == 1) + return 0; + } + return 1; +} + +int endmntent(FILE *fp) +{ + /* Will automatically drop the flock */ + return fclose(fp); +} + +char *hasmntopt(struct mntent *mnt, char *opt) +{ + char *p = mnt->mnt_opts; + ssize_t o = strlen(opt); + + while (p) { + if (memcmp(p, opt, o) == 0 && (p[o] == ',' || isspace(p[o]) || p[o] == 0 || p[o] == '=')) + return p; + p = strchr(p, ','); + if (p) + p++; + } +} -- 2.34.1