📄 tables.c
字号:
/* * config-table and mount-table utilities for cryptmount * $Revision: 117 $, $Date: 2006-07-30 10:20:45 +0100 (Sun, 30 Jul 2006) $ * Copyright 2005-2006, RW Penney *//* This file is part of cryptmount cryptmount is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. As a special exemption, permission is granted to link cryptmount with the OpenSSL project's "OpenSSL" library and distribute the linked code without invoking clause 2(b) of the GNU GPL version 2. cryptmount is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with cryptmount; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */#include <config.h>#include <ctype.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/types.h>#include <sys/stat.h>#include <unistd.h>#include "armour.h"#include "cryptmount.h"#include "delegates.h"#include "tables.h"enum /* config-file tokens */{ T_IDENT, T_LBRACE, T_OPT, T_RBRACE, T_ERROR};struct statfile /* information about status file */{ int version; /* file format version */ FILE *fp; /* file handle */};int cm_path(char **buff, const char *file) /* create full pathname of config file */{ size_t pfxlen, sfxlen; const char *pfx=NULL; if (buff == NULL || file == NULL) return 0;#ifdef TESTING extern char *argconfigdir; pfx = (argconfigdir != NULL ? argconfigdir : "/nowhere");#else pfx = CM_CONFIG_DIR;#endif pfxlen = strlen(pfx); sfxlen = strlen(file); *buff = (char*)realloc((void*)(*buff), (pfxlen + sfxlen + 2)); snprintf(*buff, (pfxlen + sfxlen + 2), "%s/%s", pfx, file); return (int)(pfxlen + sfxlen + 1);}char *cm_strdup(const char *orig) /* make duplicate of existing string, reserving memory */{ char *cpy; if (orig == NULL) return NULL; cpy = (char*)malloc((size_t)(strlen(orig) + 1)); return strcpy(cpy, orig);}cment_t *alloc_cment() /* allocate storage for a target-structure */{ cment_t *cment; cment = (cment_t*)malloc(sizeof(cment_t)); cment->ident = NULL; cment->flags = FLG_DEFAULTS; cment->dev = NULL; cment->start = 0; cment->length = -1; cment->dir = NULL; cment->fstype = NULL; cment->fsoptions = NULL; cment->loopdev = NULL; cment->cipher = cm_strdup(DFLT_CIPHER); cment->ivoffset = 0; cment->key.format = NULL; cment->key.filename = NULL; cment->key.digestalg = NULL; cment->key.cipheralg = NULL; cment->key.maxlen = -1; cment->nx = NULL; return cment;}const cment_t *get_cment(const cment_t *head, const char *ident) /* find info-structure for target of given name */{ const cment_t *itr,*ent=NULL; for (itr=head; itr!=NULL && ent==NULL; itr=itr->nx) { if (strcmp(ident, itr->ident) == 0) { ent = itr; } } return ent;}void free_cment(cment_t *cment) /* relinquish storage for a target-structure */{ if (cment->ident != NULL) free((void*)cment->ident); if (cment->dev != NULL) free((void*)cment->dev); if (cment->dir != NULL) free((void*)cment->dir); if (cment->fstype != NULL) free((void*)cment->fstype); if (cment->fsoptions != NULL) free((void*)cment->fsoptions); if (cment->loopdev != NULL) free((void*)cment->loopdev); if (cment->cipher != NULL) free((void*)cment->cipher); if (cment->key.format != NULL) free((void*)cment->key.format); if (cment->key.filename != NULL) free((void*)cment->key.filename); if (cment->key.digestalg != NULL) free((void*)cment->key.digestalg); if (cment->key.cipheralg != NULL) free((void*)cment->key.cipheralg); free((void*)cment);}static void append(char c, char **buff, unsigned *pos, unsigned *bufflen) /* append character to string, reallocating memory as necessary */{ unsigned newlen; if (*pos >= *bufflen) { newlen = (*bufflen) * 2 + 64; *buff = (char*)realloc(*buff, (size_t)newlen); *bufflen = newlen; } (*buff)[*pos] = c; ++(*pos);}static int proc_string(void *ptr, const char *src) /* process var=val entry in config-table for "string" type */{ char **addr=(char**)ptr; *addr = (char*)realloc(*addr, (size_t)(strlen(src) + 1)); strcpy(*addr, src); return (*addr == NULL);}static int proc_long(void *ptr, const char *src) /* process var=val entry in config-table for "long" type */{ long ql,*addr=(long*)ptr; if (sscanf(src, "%ld", &ql) == 1) { *addr = ql; return 0; } return 1;}int proc_flags(void *ptr, const char *src) /* convert string of configuration-switches into binary flags */{ unsigned *flags=(unsigned*)ptr; struct opt_t { const char *str; unsigned andmask, ormask; }; struct opt_t opts[] = { { "defaults", 0U, FLG_DEFAULTS }, { "user", ~0U, FLG_USER }, { "nouser", ~FLG_USER, 0U }, { "fsck", ~0U, FLG_FSCK }, { "nofsck", ~FLG_FSCK, 0U }, { "mkswap", ~0U, FLG_MKSWAP }, { "nomkswap", ~FLG_MKSWAP, 0U }, { NULL, ~0U, 0U } }; unsigned idx,len; if (src == NULL) return 0; for (;;) { for (len=0; src[len]!='\0' && src[len]!=','; ++len); for (idx=0; opts[idx].str!=NULL; ++idx) { if (strncmp(src, opts[idx].str, (size_t)len) == 0) { *flags = (*flags & opts[idx].andmask) | opts[idx].ormask; break; } } if (opts[idx].str == NULL) { fprintf(stderr, "bad option \"%s\"\n", src); return 1; } if (src[len] == '\0') break; src += len + 1; } return 0;}static void read_token(char *buff, unsigned *t_state, cment_t *cment) /* process token (word) from configuration-file while parsing */{ struct tokinfo_t { const char *name; int varoffset; int (*proc)(void *var, const char *val); } *tok;#define OFFSET(x) (int)((char*)&((cment_t*)NULL)->x - (char*)NULL) struct tokinfo_t toktable[] = { { "flags", OFFSET(flags), proc_flags }, { "dev", OFFSET(dev), proc_string }, { "dir", OFFSET(dir), proc_string }, { "startsector", OFFSET(start), proc_long }, { "numsectors", OFFSET(length), proc_long }, { "fstype", OFFSET(fstype), proc_string }, { "fsoptions", OFFSET(fsoptions), proc_string }, { "loop", OFFSET(loopdev), proc_string }, { "cipher", OFFSET(cipher), proc_string }, { "ivoffset", OFFSET(ivoffset), proc_long }, { "keyformat", OFFSET(key.format), proc_string }, { "keyfile", OFFSET(key.filename), proc_string }, { "keyhash", OFFSET(key.digestalg), proc_string }, { "keycipher", OFFSET(key.cipheralg), proc_string }, { "keymaxlen", OFFSET(key.maxlen), proc_long }, { NULL, 0, NULL } };#undef OFFSET char *eq; switch (*t_state) { case T_IDENT: (void)proc_string((void*)&cment->ident, buff); *t_state = T_LBRACE; break; case T_LBRACE: *t_state = (strcmp(buff, "{") == 0 ? T_OPT : T_ERROR); break; case T_OPT: if (strcmp(buff, "}") == 0) { *t_state = T_RBRACE; break; } if ((eq = strchr(buff,'=')) == NULL) { *t_state = T_ERROR; break; } *eq = '\0'; ++eq; /* delegate processing to specific token-processor from table: */ for (tok=toktable; tok->name!=NULL; ++tok) { if (strcmp(tok->name, buff) == 0) { (*tok->proc)((void*)((char*)cment + tok->varoffset), eq); break; } } if (tok->name == NULL) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -