📄 tables.c
字号:
fprintf(stderr, _("unrecognized option \"%s\"\n"), buff); *t_state = T_ERROR; } break; default: break; }}cment_t *parse_config(const char *cfgname) /* convert config-file into linked-list of target-structures */{ enum { C_SPACE, C_WORD, C_COMMENT }; FILE *fp; int ch,lineno=1,literal=0; unsigned pos=0,bufflen=0; unsigned c_state,t_state; char *buff=NULL; cment_t *head=NULL,**cmp=&head,*cment=NULL; fp = fopen(cfgname, "r"); if (fp == NULL) { fprintf(stderr, "failed to open \"%s\"\n", cfgname); goto bail_out; } c_state = C_SPACE; t_state = T_IDENT; cment = alloc_cment(); while (!feof(fp) && t_state != T_ERROR) { ch = fgetc(fp); if (ch == (int)'\n') ++lineno; if (literal && ch == (int)'\n') { /* ignore escaped end-of-line */ literal = 0; continue; } if (!literal && ch == (int)'#') c_state = C_COMMENT; if (!literal && ch == (int)'\\') { /* treat next character literally */ literal = 1; continue; } switch (c_state) { case C_SPACE: if (literal || !isspace(ch)) { pos = 0; append((char)ch, &buff, &pos, &bufflen); c_state = C_WORD; } break; case C_WORD: if (literal || !isspace(ch)) { append((char)ch, &buff, &pos, &bufflen); } else { append('\0', &buff, &pos, &bufflen); read_token(buff, &t_state, cment); c_state = C_SPACE; } break; case C_COMMENT: if (!literal && ch == '\n') c_state = C_SPACE; break; default: break; } literal = 0; if (t_state == T_RBRACE) { *cmp = cment; cmp = &cment->nx; cment = alloc_cment(); t_state = T_IDENT; } } if (t_state == T_ERROR) { fprintf(stderr, _("configuration error near %s:%d\n"), cfgname, lineno); } bail_out: if (cment != NULL) free_cment(cment); if (buff != NULL) free((void*)buff); if (fp != NULL) fclose(fp); return head;}void free_config(cment_t **head) /* free all entries in target-config list */{ cment_t *cmx; if (head == NULL) return; while ((cmx = *head) != NULL) { *head = cmx->nx; free_cment(cmx); }}tgtstat_t *alloc_tgtstatus(const struct cment *ent) /* create new status record for given target */{ tgtstat_t *ts; ts = (tgtstat_t*)malloc(sizeof(tgtstat_t)); ts->ident = NULL; ts->uid = 0; if (ent != NULL) { ts->ident = (char*)malloc((size_t)(strlen(ent->ident) + 1)); strcpy(ts->ident, ent->ident); } return ts;}void free_tgtstatus(tgtstat_t *ts) /* free storage of target-status record */{ if (ts->ident != NULL) free((void*)ts->ident); free((void*)ts);}struct statfile *statfile_open(const char *fname, const char *mode) /* prepare status-file for reading/writing */{ struct statfile *sf=NULL; char buff[256]; FILE *fp; if ((fp = fopen(fname, mode)) != NULL) { sf = (struct statfile*)malloc(sizeof(struct statfile)); sf->fp = fp; if (mode[0] == 'w') { sf->version = 0; /* format-version for new files */ fprintf(fp,"# auto-generated by cryptmount - do not edit\n"); fprintf(fp, "%d\n", sf->version); } else { (void)fgets(buff, (int)sizeof(buff), fp); fscanf(fp, "%d", &sf->version); } } return sf;}tgtstat_t *statfile_read(struct statfile *sf) /* read information about next target from status-file */{ tgtstat_t *ts=NULL; char *ident=NULL; int len; unsigned long uid; if (sf == NULL) goto bail_out; if (fscanf(sf->fp, "%d,", &len) != 1) goto bail_out; ident = (char*)malloc((size_t)(len + 1)); if (fread((void*)ident, (size_t)(len + 1), 1, sf->fp) != 1) { goto bail_out; } ident[len] = '\0'; if (fscanf(sf->fp, "%lu", &uid) != 1) goto bail_out; if (feof(sf->fp)) goto bail_out; ts = alloc_tgtstatus(NULL); ts->ident = ident; ts->uid = uid; ident = NULL; bail_out: if (ident != NULL) free((void*)ident); return ts;}void statfile_write(struct statfile *sf, const tgtstat_t *stat){ fprintf(sf->fp, "%u,", (unsigned)strlen(stat->ident)); fprintf(sf->fp, "%s,", stat->ident); fprintf(sf->fp, "%lu\n", stat->uid);}void statfile_close(struct statfile *sf){ fclose(sf->fp); free((void*)sf);}tgtstat_t *get_tgtstatus(const cment_t *cment){ char *fname=NULL; tgtstat_t *ts=NULL; struct statfile *sf; int badlock; (void)cm_path(&fname, "cmstatus"); badlock = cm_mutex_lock(); sf = statfile_open(fname, "r"); if (sf == NULL) goto bail_out; while ((ts = statfile_read(sf)) != NULL) { if (strcmp(cment->ident, ts->ident) == 0) break; else free_tgtstatus(ts); } statfile_close(sf); bail_out: if (!badlock) cm_mutex_unlock(); if (fname != NULL) free((void*)fname); return ts;}int put_tgtstatus(const cment_t *cment, const tgtstat_t *newstat){ char *newfname=NULL,*oldfname=NULL; struct statfile *sfin,*sfout; tgtstat_t *ts=NULL; struct stat sbuff; int badlock,eflag=0; (void)cm_path(&oldfname,"cmstatus"); (void)cm_path(&newfname,"cmstatus-temp"); badlock = cm_mutex_lock(); sfout = statfile_open(newfname, "w"); if (sfout == NULL) { eflag = 1; goto bail_out; } if (stat(oldfname,&sbuff) == 0) { sfin = statfile_open(oldfname, "r"); if (sfin == NULL) { statfile_close(sfout); unlink(newfname); eflag = 1; goto bail_out; } /* copy most entries from existing status-file: */ while ((ts = statfile_read(sfin)) != NULL) { if (strcmp(cment->ident, ts->ident) != 0) { statfile_write(sfout, ts); } free_tgtstatus(ts); } statfile_close(sfin); } /* add new entry onto end of new status-file: */ if (newstat != NULL) { statfile_write(sfout, newstat); } statfile_close(sfout); /* overwrite old status-file: */ rename(newfname, oldfname); chown(oldfname, (uid_t)0, (gid_t)0); chmod(oldfname, S_IWUSR|S_IRUSR | S_IRGRP | S_IROTH); bail_out: if (!badlock) cm_mutex_unlock(); if (newfname != NULL) free((void*)newfname); if (oldfname != NULL) free((void*)oldfname); return eflag;}/* * tables.c * (C)Copyright 2005-2006, RW Penney */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -