📄 gen.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. *//* * gen.c: generate headers and sources * Fistgen sources. */#ifdef HAVE_CONFIG_H# include <config.h>#endif /* HAVE_CONFIG_H */#define GENDEF(cond, str) \ strcpy(symbol, (str)); \ if ((cond)) { \ fprintf(out_fp_h, "#define %s 1\n", symbol); \ symtab_add(symbol, TRUE); \ } else { \ fprintf(out_fp_h, "/* #undef %s */\n", symbol); \ symtab_add(symbol, FALSE); \ }/* * generate fist header file for the file system. * This just defines structures and macros needed, based on fist_globals. */voidgenerate_header(void){ u_int i, j, num; bdt_t *bp; char symbol[MAX_BUF_LEN]; fprintf(out_fp_h, "/* MACROS AND STRUCTURES BASED ON FIST FILE %s */\n", in_file); /* fsname */ fprintf(out_fp_h, "\n/* Name of the file system? */\n"); fprintf(out_fp_h, "#define FIST_FSNAME \"%s\"\n", fist_globals.fg_fsname); /* accessmode */ fprintf(out_fp_h, "\n/* What access mode: readonly, writeonly, or readwrite? */\n"); GENDEF(fist_globals.fg_accessmode & FF_ACCESSMODE_READONLY, "FIST_ACCESSMODE_READONLY"); GENDEF(fist_globals.fg_accessmode & FF_ACCESSMODE_WRITEONLY, "FIST_ACCESSMODE_WRITEONLY"); GENDEF(fist_globals.fg_accessmode & FF_ACCESSMODE_READWRITE, "FIST_ACCESSMODE_READWRITE"); /* debug */ fprintf(out_fp_h, "\n/* Turn on debugging? */\n"); GENDEF(fist_globals.fg_debug, "FIST_DEBUG"); /* * dynamic_inode_numbers: * we turn this on automatically if using attach-mode mount style. */ fprintf(out_fp_h, "\n/* Turn on dynamic_inode_numbers? */\n"); GENDEF(fist_globals.fg_dynamic_inode_numbers || fist_globals.fg_mntstyle & FF_MNTSTYLE_ATTACH, "FIST_DYNAMIC_INODE_NUMBERS"); /* filter data */ fprintf(out_fp_h, "\n/* Manipulate file data? */\n");#if 0 /* if I'm using an SCA filter, I don't need the following hack */ if (!(fist_globals.fg_filter & FF_FILTER_SCA)) { fprintf(out_fp_h, " /* * XXX: must copy data even in lofs, until lofs can stack only on * directory vnodes. */\n"); GENDEF(TRUE, "FIST_FILTER_DATA"); } else { GENDEF(fist_globals.fg_filter & FF_FILTER_DATA, "FIST_FILTER_DATA"); }#else GENDEF(fist_globals.fg_filter & FF_FILTER_DATA, "FIST_FILTER_DATA");#endif /* filter names */ fprintf(out_fp_h, "\n/* Manipulate file names? */\n"); GENDEF(fist_globals.fg_filter & FF_FILTER_NAME, "FIST_FILTER_NAME"); /* size-changing algorithm filter */ fprintf(out_fp_h, "\n/* Size changing algorithm filter? */\n"); GENDEF(fist_globals.fg_filter & FF_FILTER_SCA, "FIST_FILTER_SCA"); fprintf(out_fp_h, "\n/* What mount style: regular, overlay, or attach? */\n"); GENDEF(fist_globals.fg_mntstyle & FF_MNTSTYLE_REGULAR, "FIST_MNTSTYLE_REGULAR"); GENDEF(fist_globals.fg_mntstyle & FF_MNTSTYLE_OVERLAY, "FIST_MNTSTYLE_OVERLAY"); GENDEF(fist_globals.fg_mntstyle & FF_MNTSTYLE_ATTACH, "FIST_MNTSTYLE_ATTACH"); /* fan-out */ fprintf(out_fp_h, "\n/* fan-out value */\n"); fprintf(out_fp_h, "#define FIST_FANOUT %d\n", fist_globals.fg_fanout); /* encoding-type */ fprintf(out_fp_h, "\n/* What encoding type: none, stream, or block? */\n"); GENDEF(fist_globals.fg_encoding_type & FF_ENCODING_TYPE_NONE, "FIST_ENCODING_TYPE_NONE"); GENDEF(fist_globals.fg_encoding_type & FF_ENCODING_TYPE_STREAM, "FIST_ENCODING_TYPE_STREAM"); GENDEF(fist_globals.fg_encoding_type & FF_ENCODING_TYPE_BLOCK, "FIST_ENCODING_TYPE_BLOCK"); /* encoding-blocksize */ fprintf(out_fp_h, "\n/* encoding-blocksize VALUE */\n"); fprintf(out_fp_h, "#define FIST_ENCODING_BLOCKSIZE %d\n", fist_globals.fg_encoding_blocksize); fprintf(out_fp_h, "\n/* Error codes? */\n"); if (fist_globals.fg_num_errorcodes) { for (i=0; i<fist_globals.fg_num_errorcodes; ++i) fprintf(out_fp_h, "#define %-20s (MAX_OS_ERRNO + %d)\n", fist_globals.fg_errorcodes[i], i+1); } else { fprintf(out_fp_h, "/* no error codes defined */\n"); } /* mount flags */ fprintf(out_fp_h, "\n/* Mount flags? */\n"); if (fist_globals.fg_num_mntflags) { for (i=0; i<fist_globals.fg_num_mntflags; ++i) { j = (1 << i); fprintf(out_fp_h, "#define %-20s (MAX_OS_MNTFLAGS + 0x%x)\n", fist_globals.fg_mntflags[i], j); } } else { fprintf(out_fp_h, "/* no error codes defined */\n"); } /* mount data arguments */ fprintf(out_fp_h, "\n/* Mount data arguments? */\n"); if ((bp = fist_globals.fg_mntdata)) { fprintf(out_fp_h, "typedef struct %s_mount_args {\n", fist_globals.fg_fsname); while (bp) { fputs(bp->full_line, out_fp_h); bp = bp->next; } fprintf(out_fp_h, "} %s_mount_args_t;\n", fist_globals.fg_fsname); } else { fprintf(out_fp_h, "/* no mount data defined */\n"); } /* per-vfs data */ fprintf(out_fp_h, "\n/* Per-VFS data? */\n"); if ((bp = fist_globals.fg_pervfs)) { fprintf(out_fp_h, "typedef struct %s_pervfs {\n", fist_globals.fg_fsname); while (bp) { fputs(bp->full_line, out_fp_h); bp = bp->next; } fprintf(out_fp_h, "} %s_pervfs_t;\n", fist_globals.fg_fsname); } else { fprintf(out_fp_h, "/* no per-VFS data defined */\n"); } /* per vnode data */ fprintf(out_fp_h, "\n/* Per-vnode data? */\n"); if ((bp = fist_globals.fg_pervnode)) { fprintf(out_fp_h, "typedef struct %s_pervnode {\n", fist_globals.fg_fsname); while (bp) { fputs(bp->full_line, out_fp_h); bp = bp->next; } fprintf(out_fp_h, "} %s_pervnode_t;\n", fist_globals.fg_fsname); } else { fprintf(out_fp_h, "/* no per-vnode data defined */\n"); } /* fileformat entries */ fprintf(out_fp_h, "\n/* file formats */\n"); num = fist_globals.fg_num_fileformats; fprintf(out_fp_h, "/* using auxiliary sources? */\n"); GENDEF(need_aux_sources || num > 0, "FIST_USE_AUX_SRC"); if (num <= 0) { fprintf(out_fp_h, "/* no fileformats defined */\n"); } else { /* print fileformat structures */ char *ffname; bdt_t *bdt; for (i = 0; i < num; i++) { ffname = fist_globals.fg_fileformat_name[i]; fprintf(out_fp_h, "struct _fist_fileformat_%s {\n", ffname); bdt = fist_globals.fg_fileformat[i]; while (bdt) { fprintf(out_fp_h, bdt->full_line); bdt = bdt->next; } fprintf(out_fp_h, "};\n"); } } /* * Note: ioctl entries go into wrapfs.h, because they need to be * available for both user and kernel code. */}/* * Replace the first 'wrapfs/WRAPFS' instance in a string with fsname. * Returns pointer to static area! */char *replace_fsname(const char *in_str){ static char out_str[MAXPATHLEN]; char *mp; int upper = 0; mp = strstr(in_str, "wrapfs"); if (!mp) mp = strstr(in_str, "WRAPFS"); if (!mp) { strcpy(out_str, in_str); return out_str; } if (mp[0] == 'W') { upper = 1; } memset(out_str, 0, MAXPATHLEN); /* copy substring (if any) before match */ if (mp != in_str) strncpy(out_str, in_str, (int) mp - (int) in_str); /* copy new fsname */ strcat(out_str, (upper ? fist_globals.fg_upper_fsname : fist_globals.fg_fsname)); /* copy substring (if any) past match */ strcat(out_str, &mp[strlen("wrapfs")]); return out_str;}/* copy modes */staticvoid copy_mode(const char *f1, const char *f2){ struct stat b1, b2; if (lstat(f1, &b1) < 0) { perror(f1); return; } if (lstat(f2, &b2) < 0) { perror(f2); return; } if (chmod(f2, b1.st_mode & 0775) < 0) { perror(f2); return; }}/* * Check if two files are equal. * Return TRUE/FALSE. */intequal_files(const char *f1, const char *f2){ struct stat b1, b2; FILE *fp1, *fp2; int i1, i2; /* compare file sizes */ if (lstat(f1, &b1) < 0) { perror(f1); return FALSE; } if (lstat(f2, &b2) < 0) { if (errno != ENOENT) perror(f2); return FALSE; } if (b1.st_size != b2.st_size) return FALSE; /* compare bytes */ fp1 = fopen(f1, "r"); if (!fp1) { perror(f1); return FALSE; } fp2 = fopen(f2, "r"); if (!fp2) { perror(f2); fclose(fp1); return FALSE; } while ((i1 = getc(fp1)) == (i2 = getc(fp2)) && i1 != EOF && i2 != EOF); fclose(fp2); fclose(fp1); if (i1 != i2) return FALSE; return TRUE;}/* * Generate code */voidgen_code(const char *in_name, const char *out_name){ char cmd[MAX_BUF_LEN]; char tmpfile[MAXPATHLEN]; int fd; FILE *tmp_fp, *cmd_fp; /* get temp file name */ sprintf(tmpfile, "%s_XXXXXX", out_name); fd = mkstemp(tmpfile); if (!fd) { perror(tmpfile); exit(1); } tmp_fp = fdopen(fd, "w"); if (!tmp_fp) { perror("fdopen"); exit(1); } /* open command to rename file system from wrapfs to "fsname" */ sprintf(cmd, "sed -e 's/wrapfs/%s/g' -e 's/WRAPFS/%s/g' < %s", fist_globals.fg_fsname, fist_globals.fg_upper_fsname, in_name); cmd_fp = popen(cmd, "r"); if (!cmd_fp) { perror(cmd); exit(1); } wyyin = cmd_fp; wyyout = tmp_fp; current_file = in_name; /* so correct file is reported if error */ wyyparse(); pclose(cmd_fp); fclose(tmp_fp); close(fd); if (equal_files(tmpfile, out_name)) { // fprintf(stderr, "unchanged: %s\n", out_name); unlink(tmpfile); } else { fprintf(stderr, "NEW: %s\n", out_name); rename(tmpfile, out_name); copy_mode(in_name, out_name); }}/* copy file f1 to f2 if f1 is newer */voidcopy_if_newer(const char *f1, const char *f2){ struct stat b1, b2; int fd1, fd2, i; char buf[MAX_BUF_LEN]; /* compare file modification dates */ if (lstat(f1, &b1) < 0) { perror(f1); return; } if (lstat(f2, &b2) < 0) { b2.st_mtime = 0; } if (b1.st_mtime <= b2.st_mtime) return; /* nothing to do */ fprintf(stderr, "NEW: %s\n", f2); /* copy bytes */ fd1 = open(f1, O_RDONLY); if (fd1 < 0) { perror(f1); return; } fd2 = open(f2, O_RDWR | O_CREAT, b1.st_mode & 0775); if (fd2 < 0) { close(fd1); perror(f2); return; } while ((i = read(fd1, buf, MAX_BUF_LEN)) > 0) { write(fd2, buf, i); } if (i < 0) { perror(f1); } if (i == 0) { if (ftruncate(fd2, b1.st_size) < 0) { perror(f2); } } close(fd2); close(fd1); return;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -