📄 cfg.c
字号:
static char *cfg_get_token(void){ char buf[MAX_TOKEN+1]; char *here; int ch,escaped; if (last_token) { here = last_token; last_token = NULL; return here; } while (1) { while ((ch = next()), ch == ' ' || ch == '\t' || ch == '\n') if (ch == '\n') line_num++; if (ch == EOF) return NULL; if (ch != '#') break; while ((ch = next_raw()), ch != '\n') if (ch == EOF) return NULL; line_num++; } if (ch == '=') return stralloc("="); if (ch == '"') { here = buf; while (here-buf < MAX_TOKEN) { if ((ch = next()) == EOF) cfg_error("EOF in quoted string"); if (ch == '"') { *here = 0; return stralloc(buf); } if (ch == '\\') { ch = next(); if (ch != '"' && ch != '\\' && ch != '\n') cfg_error("Bad use of \\ in quoted string"); if (ch == '\n') { while ((ch = next()), ch == ' ' || ch == '\t'); if (!ch) continue; again(ch); ch = ' '; } } if (ch == '\n' || ch == '\t') cfg_error("\\n and \\t are not allowed in quoted strings"); *here++ = ch; } cfg_error("Quoted string is too long"); return 0; /* not reached */ } here = buf; escaped = 0; while (here-buf < MAX_TOKEN) { if (escaped) { if (ch == EOF) cfg_error("\\ precedes EOF"); if (ch == '\n') line_num++; else *here++ = ch == '\t' ? ' ' : ch; escaped = 0; } else { if (ch == ' ' || ch == '\t' || ch == '\n' || ch == '#' || ch == '=' || ch == EOF) { again(ch); *here = 0; return stralloc(buf); }#if !__MSDOS__ if (!(escaped = (ch == '\\')))#endif /* !__MSDOS__ */ *here++ = ch; } ch = next(); } cfg_error("Token is too long"); return 0; /* not reached */}static void cfg_return_token(char *token){ last_token = token;}static int cfg_next(char **item,char **value){ char *this; if (last_item) { *item = last_item; *value = last_value; last_item = NULL; return 1; } *value = NULL; if (!(*item = cfg_get_token())) return 0; if (!strcmp(*item,"=")) cfg_error("Syntax error"); if (!(this = cfg_get_token())) return 1; if (strcmp(this,"=")) { cfg_return_token(this); return 1; } if (!(*value = cfg_get_token())) cfg_error("Value expected at EOF"); if (!strcmp(*value,"=")) cfg_error("Syntax error after %s",*item); return 1;}static void cfg_return(char *item,char *value){ last_item = item; last_value = value;}void cfg_init(CONFIG *table){ while (table->type != cft_end) { switch (table->type) { case cft_strg: if (table->data) free(table->data); case cft_flag: table->data = NULL; break; case cft_link: table = ((CONFIG *) table->action)-1; break; default: die("Unknown syntax code %d",table->type); } table++; }}static int cfg_do_set(CONFIG *table,char *item,char *value,int copy, void *context){ CONFIG *walk; for (walk = table; walk->type != cft_end; walk++) { if (walk->name && !strcasecmp(walk->name,item)) { if (value && walk->type != cft_strg) cfg_error("'%s' doesn't have a value",walk->name); if (!value && walk->type == cft_strg) cfg_error("Value expected for '%s'",walk->name); if (walk->data) { if (walk->context == context) cfg_error("Duplicate entry '%s'",walk->name); else { fprintf(errstd,"Ignoring entry '%s'\n",walk->name); if (!copy) free(value); return 1; } } if (walk->type == cft_flag) walk->data = &flag_set; else if (walk->type == cft_strg) walk->data = copy ? stralloc(value) : value; walk->context = context; if (walk->action) ((void (*)(void)) walk->action)(); break; } if (walk->type == cft_link) walk = ((CONFIG *) walk->action)-1; } if (walk->type != cft_end) return 1; cfg_return(item,value); return 0;}void cfg_set(CONFIG *table,char *item,char *value,void *context){ if (cfg_do_set(table,item,value,1,context) != 1) cfg_error("cfg_set: Can't set %s",item);}void cfg_unset(CONFIG *table,char *item){ CONFIG *walk; for (walk = table; walk->type != cft_end; walk++) if (walk->name && !strcasecmp(walk->name,item)) { if (!walk->data) die("internal error (cfg_unset %s, unset)",item); if (walk->type == cft_strg) free(walk->data); walk->data = NULL; return; } die("internal error (cfg_unset %s, unknown",item);}#if NEW_PARSEstatic int cfg_end (char *item){ CONFIG **key; CONFIG *c;key = keywords;while ((c = *key++)) { while (c->name) { if (!strcasecmp(c->name, item)) return 1; c++; }} return 0;}#endifint cfg_parse(CONFIG *table){ char *item,*value; while (1) { if (!cfg_next(&item,&value)) return 0;if(verbose>=6) printf("cfg_parse: item=\"%s\" value=\"%s\"\n", item, value); if (!cfg_do_set(table,item,value,0,table)) {#if NEW_PARSE==0 return 1;#else if (cfg_end(item)) return 1; else cfg_error("Unrecognized token \"%s\"", item);#endif } free(item); }}int cfg_get_flag(CONFIG *table,char *item){ CONFIG *walk; for (walk = table; walk->type != cft_end; walk++) { if (walk->name && !strcasecmp(walk->name,item)) { if (walk->type != cft_flag) die("cfg_get_flag: operating on non-flag %s",item); return !!walk->data; } if (walk->type == cft_link) walk = ((CONFIG *) walk->action)-1; } die("cfg_get_flag: unknown item %s",item); return 0; /* not reached */}char *cfg_get_strg(CONFIG *table,char *item){ CONFIG *walk; for (walk = table; walk->type != cft_end; walk++) { if (walk->name && !strcasecmp(walk->name,item)) { if (walk->type != cft_strg) die("cfg_get_strg: operating on non-string %s",item); return walk->data; } if (walk->type == cft_link) walk = ((CONFIG *) walk->action)-1; } die("cfg_get_strg: unknown item %s",item); return 0; /* not reached */}#if !__MSDOS__/* open the password file, passw=1 forces a new file to be created */static char *pw_file_name;FILE *pw_file = NULL;FILE *cfg_pw_open(void){ char name[MAX_TOKEN+1]; struct stat buf; time_t conf; int fd; strcpy(name, file_name); /* copy name of config file '/etc/lilo.conf' */ strcat(name, PW_FILE_SUFFIX); pw_file_name = stralloc(name);#if 1 if (stat(file_name, &buf)) die("Cannot stat '%s'", file_name); conf = buf.st_mtime; if (!stat(pw_file_name, &buf) && conf>buf.st_mtime && !nowarn && !passw) { fprintf(errstd,"Warning: '%s' more recent than '%s'\n", file_name, pw_file_name); fprintf(errstd," Running 'lilo -p' is recommended.\n"); }#endif if (passw & !test) { if (unlink(pw_file_name) && errno != ENOENT) die("Could not delete '%s'", pw_file_name); if ((fd = creat(pw_file_name, 0600)) < 0) die("Could not create '%s'", pw_file_name); (void) close(fd); pw_file = fopen(pw_file_name, "w+"); } else if (passw) return (pw_file=NULL); else { if (!(pw_file = fopen(pw_file_name, "r"))) { if (!test) { passw = 1; /* force writing */ if ((fd = creat(pw_file_name, 0600)) < 0) die("Could not create '%s'", pw_file_name); (void) close(fd); pw_file = fopen(pw_file_name, "w+"); } else return (pw_file=NULL); } } if (!pw_file) die("Could not create '%s'", pw_file_name);#if 1 if (!stat(pw_file_name, &buf) && (buf.st_mode&0044) && !nowarn) { fprintf(errstd,"Warning: '%s' readable by other than 'root'\n", pw_file_name); }#endif return pw_file;}/* allow only the "bitmap" keywords */void cfg_bitmap_only(void){ keywords[0] = cf_bitmap; keywords[1] = NULL;}#if BETA_TESTvoid cfg_alpha_check(void){ CONFIG **kw = keywords; CONFIG *cfg; while ((cfg=*kw)) { while (cfg[1].name) { if (strcmp(cfg[0].name, cfg[1].name) >= 0) { die("cfg_alpha_check: failure at '%s', '%s'", cfg[0].name, cfg[1].name); } cfg++; } kw++; }}#endif#endif /* !__MSDOS__ */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -