📄 main.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. *//* * main.c: main() and assorted routines * Fistgen sources. */#ifdef HAVE_CONFIG_H# include <config.h>#endif /* HAVE_CONFIG_H *//* globals */fist_globals_t fist_globals;fist_rules_t fist_rules;char in_file[MAXPATHLEN], in_dir[MAXPATHLEN];const char *current_file;char out_file_h[MAXPATHLEN], out_file_c[MAXPATHLEN];char real_file_h[MAXPATHLEN], real_file_c[MAXPATHLEN];FILE *in_fp, *out_fp_c, *out_fp_h, *sed_fp;static char *out_dir = NULL, out_dir2[MAXPATHLEN], out_dir3[MAXPATHLEN];char *fs_type = NULL;char wrapfs_dir[MAXPATHLEN], uname_dir[MAX_BUF_LEN];time_t start_time;int need_aux_sources; /* do we need to include aux.c? */int opt_verbose = 0;char *opt_u = NULL;/* externals */static voidfist_init(void){ /* initialize file names */ in_file[0] = out_file_h[0] = out_file_c[0] = '\0'; current_file = NULL; /* do you know what time it is? */ if (time(&start_time) < 0) { perror("time"); exit(1); } parsing_fist_rules = FALSE; need_aux_sources = FALSE; /* initialize globals */ memset(&fist_globals, 0, sizeof(fist_globals_t)); memset(&fist_rules, 0, sizeof(fist_rules_t)); memset(&auto_generated_functions, 0, sizeof(bdt_t *)); memset(&auto_generated_externs, 0, sizeof(ecl_t)); fist_globals.fg_accessmode = FF_ACCESSMODE_READWRITE; fist_globals.fg_mntstyle = FF_MNTSTYLE_REGULAR; fist_globals.fg_fanout = 1; /* no fan-out by default */ fist_globals.fg_encoding_type = FF_ENCODING_TYPE_BLOCK; /* block encoding by default */ fist_globals.fg_encoding_blocksize = 1; /* 1b encoding alg "chunking" size */}static voidusage(void){ fprintf(stderr, "Usage: %s [-v] [-o output-dir] [-u uname] fistfile\n", "fistgen"); exit(1);}intmain(int argc, char *argv[], char *envp[]){ int ret, opt_ch, i; char *cp; struct utsname utsname; char buf[MAX_BUF_LEN], in_name[MAXPATHLEN], out_name[MAXPATHLEN]; DIR *tdir; struct dirent *dent; struct stat statbuf; /* initialize */ fist_init(); /* check usage */ while ((opt_ch = getopt(argc, argv, "vHo:u:")) != -1) switch (opt_ch) { case 'v': opt_verbose = 1; break; case 'o': out_dir = optarg; break; case 'u': opt_u = optarg; break; case 'H': default: usage(); } if (optind + 1 != argc) usage(); /* find system name (uname) and OS release (uname -r) */ if (uname(&utsname) < 0) { perror("uname"); exit(1); } /* We only want the first two digits out of the release number */ strcpy(buf, utsname.release); cp = strchr(buf, '.'); if (cp && (cp = strchr(++cp, '.'))) *cp = '\0'; if (opt_u) sprintf(uname_dir, opt_u); else sprintf(uname_dir, "%s-%s", utsname.sysname, buf); sprintf(wrapfs_dir, "templates/%s", uname_dir); /* set default output dir prefix */ if (!out_dir) out_dir = "out"; /* set input file */ cp = basename(argv[optind]); if (*cp == '/') cp++; strcpy(fist_globals.fg_fsname, cp); strcpy(in_file, argv[optind]); /* name may include a ".fist" extension. ensure fs_name is short */ cp = strrchr(fist_globals.fg_fsname, '.'); if (cp && STREQ(cp, ".fist")) { *cp = '\0'; /* chop off '.fist' extension */ } else { strcat(in_file, ".fist"); } /* save input file directory name */ if (strchr(in_file, '/')) { cp = strdup(in_file); strcpy(in_dir, dirname(cp)); free(cp); cp = NULL; } else { strcpy(in_dir, "."); } /* produce uppercase version of fsname */ strcpy(fist_globals.fg_upper_fsname, fist_globals.fg_fsname); uppercase_string(fist_globals.fg_upper_fsname); /* set output files */ sprintf(out_dir2, "%s/%s", out_dir, uname_dir); sprintf(out_dir3, "%s/%s", out_dir2, fist_globals.fg_fsname); sprintf(out_file_h, "%s/fist_%s.h-tmp", out_dir3, fist_globals.fg_fsname); sprintf(out_file_c, "%s/fist_%s.c-tmp", out_dir3, fist_globals.fg_fsname); sprintf(real_file_h, "%s/fist_%s.h", out_dir3, fist_globals.fg_fsname); sprintf(real_file_c, "%s/fist_%s.c", out_dir3, fist_globals.fg_fsname); /* ensure output directories exist */ ret = mkdir(out_dir, 0775); if (ret < 0 && errno != EEXIST) { perror(out_dir); exit(1); } ret = mkdir(out_dir2, 0775); if (ret < 0 && errno != EEXIST) { perror(out_dir2); exit(1); } ret = mkdir(out_dir3, 0775); if (ret < 0 && errno != EEXIST) { perror(out_dir3); exit(1); } /* set input file descriptor */ in_fp = fopen(in_file, "r"); if (!in_fp) { perror(in_file); exit(1); } /* set output header/code file descriptor */ out_fp_h = fopen(out_file_h, "w"); if (!out_fp_h) { perror(out_file_h); exit(1); } else { fprintf(out_fp_h, "/*\n * Do not edit by hand.\n * Automatically generated by fistgen.\n */\n"); fprintf(out_fp_h, "#ifndef _fist_%s_h\n#define _fist_%s_h\n\n", fist_globals.fg_fsname, fist_globals.fg_fsname); } out_fp_c = fopen(out_file_c, "w"); if (!out_fp_c) { perror(out_file_c); exit(1); } /* parse input file */ fyyin = in_fp; /* unmatched text gets copied to output stream by default */ fyyout = out_fp_c; fyyparse(); generate_header(); /* add trailing code for header file */ fprintf(out_fp_h, "\n#endif /* not _fist_%s_h */\n", fist_globals.fg_fsname); /* close any opened files and generate any auxiliary functions */ fclose(in_fp); fclose(out_fp_h); print_auto_generated_functions(out_fp_c); fclose(out_fp_c); /* copy fistfs header/source if needed */ if (equal_files(out_file_h, real_file_h)) { unlink(out_file_h); } else { fprintf(stderr, "NEW: %s\n", real_file_h); rename(out_file_h, real_file_h); } if (equal_files(out_file_c, real_file_c)) { unlink(out_file_c); } else { fprintf(stderr, "NEW: %s\n", real_file_c); rename(out_file_c, real_file_c); } /* open templates directory */ tdir = opendir(wrapfs_dir); if (!tdir) { perror(wrapfs_dir); exit(1); } while ((dent = readdir(tdir))) { int len = strlen(dent->d_name); sprintf(in_name, "%s/%s", wrapfs_dir, dent->d_name); if (lstat(in_name, &statbuf) < 0) { perror(in_name); exit(1); } if (!S_ISREG(statbuf.st_mode)) /* skip non-regular files! */ continue; /* skip temp '#', backup '~', and '.' files */ if (dent->d_name[len-1] == '#' || dent->d_name[len-1] == '~' || dent->d_name[0] == '.' || STREQ(dent->d_name, "ChangeLog") || STREQ(dent->d_name, "commit") ) continue; sprintf(out_name, "%s/%s", out_dir3, replace_fsname(dent->d_name)); if (opt_verbose) printf("fistgen: %s\n\t-> %s\n", in_name, out_name); gen_code(in_name, out_name); } closedir(tdir); /* * copy extra files if needed */ /* module sources */ for (i=0; i<fist_globals.fg_num_msources; ++i) { sprintf(in_name, "%s/%s", in_dir, fist_globals.fg_msources[i]); sprintf(out_name, "%s/%s", out_dir3, fist_globals.fg_msources[i]); copy_if_newer(in_name, out_name); } /* module headers */ for (i=0; i<fist_globals.fg_num_mheaders; ++i) { sprintf(in_name, "%s/%s", in_dir, fist_globals.fg_mheaders[i]); sprintf(out_name, "%s/%s", out_dir3, fist_globals.fg_mheaders[i]); copy_if_newer(in_name, out_name); } /* user sources */ for (i=0; i<fist_globals.fg_num_usources; ++i) { sprintf(in_name, "%s/%s", in_dir, fist_globals.fg_usources[i]); sprintf(out_name, "%s/%s", out_dir3, fist_globals.fg_usources[i]);#if 1 if (opt_verbose) printf("fistgen: %s\n\t-> %s\n", in_name, out_name); gen_code(in_name, out_name);#else copy_if_newer(in_name, out_name);#endif } /* extra sca sources: must have an sca_code.c file (encode/decode) */ if (fist_globals.fg_filter & FF_FILTER_SCA) { char *names[] = { "sca_code.c", "sca_code.h", }; for (i=0; i<sizeof(names)/sizeof(char *); i++) { sprintf(in_name, "%s/%s", in_dir, names[i]); sprintf(out_name, "%s/%s", out_dir3, names[i]); copy_if_newer(in_name, out_name); } }#if 0 print_fist_rules();#endif exit(0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -