📄 dollar_vars.c
字号:
/* * Copyright (c) 1997-2003 Erez Zadok * Copyright (c) 2001-2003 Stony Brook University * Copyright (c) 1997-2000 Columbia University * * For specific licensing information, see the COPYING file distributed with * this package, or get one from ftp://ftp.filesystems.org/pub/fist/COPYING. * * This Copyright notice must be kept intact and distributed with all * fistgen sources INCLUDING sources generated by fistgen. *//* * dollar_vars.c: validate/expand dollar variable names to their values * Fistgen sources. */#ifdef HAVE_CONFIG_H# include <config.h>#endif /* HAVE_CONFIG_H *//****************************************************************************/char *valid_dollar_vargs[] = { "this", "dir", "from", "to", "fromdir", "todir", "vfs", NULL /* must be last entry */};/* * List of static vnode attributes. Others can be defined dynamically * using the %pervfs and %pervnode declarations. */char *valid_dollar_vnode_attrs[] = { "ext", "name", "symlinkval", "type", /* the rest are stat(2) like attributes */ "atime", "blocks", "ctime", "group", "mode", "mtime", "nlink", "size", "owner", /* was "user" */ "inum", /* inode/vnode number */ NULL /* must be last entry */};/* list of common VFS attributes */static fword_exp_fxn_t valid_dollar_vfs_attrs[] = { {"blocksize", NULL}, {"fstype", NULL}, /* F/S type: wrapfs, nfs, ext2fs, etc. */ /* add "bitsize" (32/64) */ {NULL, NULL} /* must be last entry */};/****************************************************************************//* * Validate that a $varg is a valid v-arg keyword. * Return TRUE/FALSE. */static intfist_validate_dollar_varg(const char *str, char *errmsg){ char **tmp = valid_dollar_vargs; /* NULL is valid $varg. It means "this." */ if (!str) return TRUE; if (!str[0]) return FALSE; while (*tmp) { if (STREQ(*tmp, str)) return TRUE; tmp++; } return FALSE;}/* * Validate that 'num' is within the valid range. * Return TRUE/FALSE. */static intfist_validate_dollar_num(const char *str, char *errmsg){ int i; /* NULL is valid 'num'. It means "0". */ if (!str) return TRUE; if (!str[0]) return FALSE; i = atoi(str); if (i < 0) { sprintf(errmsg, "negative/illegal $%d value", i); return FALSE; } if (i > MAX_FAN_OUT) { sprintf(errmsg, "$%d value exceeds MAX_FAN_OUT (%d)", i, MAX_FAN_OUT); return FALSE; } if (i > fist_globals.fg_fanout) { sprintf(errmsg, "$%d value exceeds fanout level (%d)", i, fist_globals.fg_fanout); return FALSE; } return TRUE; /* all OK */}/* * Validate that a vnode 'attr' is a valid attribute keyword. * Return TRUE/FALSE. */static intfist_validate_dollar_vnode_attr(const char *str, char *errmsg){ char **tmp = valid_dollar_vnode_attrs; /* NULL is valid 'attr' */ if (!str) return TRUE; if (!str[0]) return FALSE; /* search for standard attributes */ while (*tmp) { if (STREQ(*tmp, str)) return TRUE; tmp++; } /* search in per-vnode attributes */ if (fist_search_bdt(str, fist_globals.fg_pervnode)) return TRUE; strcpy(errmsg, "invalid vnode attribute"); return FALSE;}/* * Validate that a VFS 'attr' is a valid attribute keyword. * Return TRUE/FALSE. */static intfist_validate_dollar_vfs_attr(const char *str, char *errmsg){ fword_exp_fxn_t *efp; /* NULL is valid 'attr' */ if (!str) return TRUE; if (!str[0]) return FALSE; /* search for standard attributes */ for (efp = valid_dollar_vfs_attrs; efp->name; efp++) if (STREQ(str, efp->name)) return TRUE; /* search in per-VFS attributes */ if (fist_search_bdt(str, fist_globals.fg_pervfs)) return TRUE; strcpy(errmsg, "invalid VFS attribute"); return FALSE;}/* * Validate that a $something is a valid dollar variable. * Return TRUE/FALSE. */intfist_validate_dollar_variable(const char *str, const char *dv, const char *dn, const char *da, char *errmsg){ strcpy(errmsg, "unknown FiST dollar variable"); /* default error */ if (!str || !str[0] || !str[1]) return FALSE; /* validate varg */ if (!fist_validate_dollar_varg(dv, errmsg)) return FALSE; /* validate num */ if (!fist_validate_dollar_num(dn, errmsg)) return FALSE; /* validate attr */ if (dv && STREQ(dv, "vfs")) { if (!fist_validate_dollar_vfs_attr(da, errmsg)) return FALSE; } else { if (!fist_validate_dollar_vnode_attr(da, errmsg)) return FALSE; } /* all ok */ return TRUE;}/****************************************************************************//*** FUNCTIONS TO EXPAND DOLLAR VARIABLES ***//****************************************************************************//* * Static expand $vfs with a given fanout number (dn) and attribute name (da) * Both dn and da may be NULL, but everything is valid. */static voidexpand_dollar_vfs(const char *dn, const char *da, char *buf){ fword_exp_fxn_t *efp; /* simple case: wants back the vfs */ if (!dn && !da) { strcpy(buf, "this_vfs"); return; } /* no explicit fanout (n=1): wants vfs attribute or pervfs attribute */ if (!dn) { /* search for normal attributes */ for (efp = valid_dollar_vfs_attrs; efp->name; efp++) { if (STREQ(da, efp->name)) { if (efp->func) (efp->func)(buf, NULL); else sprintf(buf, "unimplemented_dollar_vfs(%s,%s)", dn, da); return; } } /* search for pervfs attributes */ if (fist_search_bdt(da, fist_globals.fg_pervfs)) { sprintf(buf, "vfs2priv(this_vfs)->%s", da); return; } } /* if nothing matched, enclose string in "unknown" params */ sprintf(buf, "unknown_dollar_vfs(%s,%s)", dn, da); return;}/* * Expand a dollar variable into its value. * Note: value returned is a static variable. * If cannot expand value, leaves it the same. * var: full string * dv: variable portion of var * dn: fanout number * da: attribute of var */const char *expand_dollar_var(const char *var, const char *dv, const char *dn, const char *da){ static char buf[MAX_BUF_LEN]; char vnode_name[MAX_BUF_LEN]; int n = 0; if (dn) n = atoi(dn); if (dv && STREQ(dv, "vfs")) { expand_dollar_vfs(dn, da, buf); return buf; } /* process vnode names and fan-outs (lower vnodes) */ strcpy(vnode_name, "unknown_vnode"); /* default */ if (!dv) strcpy(vnode_name, "this_vnode"); else { if (STREQ(dv, "dir")) { strcpy(vnode_name, "this_dir"); } /* fill in for other names */ } if (dn) { if (STREQ(dn, "1")) { sprintf(buf, "%s2lower(%s)", (dv && STREQ(dv, "dir")) ? "dir" : "vnode", vnode_name); strcpy(vnode_name, buf); } } if (da && dv && STREQ(dv, "dir")) strcat(vnode_name, FIST_DIR_TO_VNODE); if (!da) { strcpy(buf, vnode_name); return buf; } /* * If got here, then dealing with vnode attributes. */ /* inode number */ if (STREQ(da, "inum")) {#ifdef __linux__ sprintf(buf, "%s->%s", vnode_name, FIST_DA_INUM);#else /* not __linux__ */ char name[MAX_BUF_LEN], fxnbuf[MAX_BUF_LEN]; /* form name of special getattr function */ sprintf(name, "fist_getattr_%s", da); /* replace function with code */ sprintf(buf, "%s(%s, cr)", name, vnode_name); /* check if support function is needed */#ifdef __solaris__ if (!fist_search_bdt(name, auto_generated_functions)) { /* XXX: on Solaris, inums are 64-bit. We cast to 32 bits */ sprintf(fxnbuf, "unsigned long%s(vnode_t *vp, cred_t *cr)\n{ vattr_t va; int err; va.va_mask = AT_ALL; err = VOP_GETATTR(vp, &va, 0, cr); if (err) return -1; return (unsigned long) va.va_nodeid;}", name);#endif /* __solaris__ */#ifdef __freebsd__ if (!fist_search_bdt(name, auto_generated_functions)) { sprintf(fxnbuf, "unsigned long%s(vnode_t *vp, cred_t *cr)\n{ vattr_t va; int err; VATTR_NULL(&va); err = VOP_GETATTR(vp, &va, cr, curproc); if (err) return -1; return (unsigned long) va.va_fileid;}", name);#endif /* __freebsd__ */ if (!append_to_bdt(&auto_generated_functions, fxnbuf, name)) { sprintf(buf, "cannot store getattr function %s", name); return buf; } /* side effect: append "extern" definition to fist header file */ sprintf(fxnbuf, "extern unsigned long %s(vnode_t *vp, cred_t *cr);\n", name); if (!ecl_strcat(&auto_generated_externs, fxnbuf)) { sprintf(buf, "cannot store getattr extern definition %s", name); return buf; } }#endif /* not __linux__ */ return buf; } /* file owner */ if (STREQ(da, "owner")) {#ifdef __linux__ sprintf(buf, "%s->%s", vnode_name, FIST_DA_USER);#else /* not __linux__ */ char name[MAX_BUF_LEN], fxnbuf[MAX_BUF_LEN]; /* form name of special getattr function */ sprintf(name, "fist_getattr_%s", da); /* replace function with code */ sprintf(buf, "%s(%s, cr)", name, vnode_name); /* check if support function is needed */#ifdef __solaris__ if (!fist_search_bdt(name, auto_generated_functions)) { sprintf(fxnbuf, "uid_t%s(vnode_t *vp, cred_t *cr)\n{ vattr_t va; int err; va.va_mask = AT_ALL; err = VOP_GETATTR(vp, &va, 0, cr); if (err) return -1; return va.va_uid;}", name);#endif /* __solaris__ */#ifdef __freebsd__ if (!fist_search_bdt(name, auto_generated_functions)) { sprintf(fxnbuf, "uid_t%s(vnode_t *vp, cred_t *cr)\n{ vattr_t va; int err; VATTR_NULL(&va); err = VOP_GETATTR(vp, &va, cr, curproc); if (err) return -1; return va.va_uid;}", name);#endif /* __freebsd__ */ if (!append_to_bdt(&auto_generated_functions, fxnbuf, name)) { sprintf(buf, "cannot store getattr function %s", name); return buf; } /* side effect: append "extern" definition to fist header file */ sprintf(fxnbuf, "extern uid_t %s(vnode_t *vp, cred_t *cr);\n", name); if (!ecl_strcat(&auto_generated_externs, fxnbuf)) { sprintf(buf, "cannot store getattr extern definition %s", name); return buf; } }#endif /* not __linux__ */ return buf; } /* file group */ if (STREQ(da, "group")) {#ifdef __linux__ sprintf(buf, "%s->%s", vnode_name, FIST_DA_GROUP);#else /* not __linux__ */ char name[MAX_BUF_LEN], fxnbuf[MAX_BUF_LEN]; /* form name of special getattr function */ sprintf(name, "fist_getattr_%s", da); /* replace function with code */ sprintf(buf, "%s(%s, cr)", name, vnode_name); /* check if support function is needed */#ifdef __solaris__ if (!fist_search_bdt(name, auto_generated_functions)) { sprintf(fxnbuf, "gid_t%s(vnode_t *vp, cred_t *cr)\n{ vattr_t va; int err; va.va_mask = AT_ALL; err = VOP_GETATTR(vp, &va, 0, cr); if (err) return -1; return va.va_gid;}", name);#endif /* __solaris__ */#ifdef __freebsd__ if (!fist_search_bdt(name, auto_generated_functions)) { sprintf(fxnbuf, "gid_t%s(vnode_t *vp, cred_t *cr)\n{ vattr_t va; int err; VATTR_NULL(&va); err = VOP_GETATTR(vp, &va, cr, curproc); if (err) return -1; return va.va_gid;}", name);#endif /* __freebsd__ */ if (!append_to_bdt(&auto_generated_functions, fxnbuf, name)) { sprintf(buf, "cannot store getattr function %s", name); return buf; } /* side effect: append "extern" definition to fist header file */ sprintf(fxnbuf, "extern gid_t %s(vnode_t *vp, cred_t *cr);\n", name); if (!ecl_strcat(&auto_generated_externs, fxnbuf)) { sprintf(buf, "cannot store getattr extern definition %s", name); return buf; } }#endif /* not __linux__ */ return buf; } /* XXX: fix me */ sprintf(buf, "unknown_dollar_var(%s,%s,%s,%s)", var, (dv ? dv : "null"), (dn ? dn : "null"), (da ? da : "null")); return buf;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -