X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?p=secnet.git;a=blobdiff_plain;f=util.c;h=48814c1890f8fcd7ea39e8c24ae3254c0d7d9057;hp=19293834dc635c91c1a9db21d640090aab1a8af8;hb=042a8da9053c205ea74ec1785c93ca4bcf4ea5e0;hpb=4efd681a66c15bc6f81eefc69396669e165e5e0f diff --git a/util.c b/util.c index 1929383..48814c1 100644 --- a/util.c +++ b/util.c @@ -1,26 +1,43 @@ -/* $Log: util.c,v $ - * Revision 1.2 1996/04/14 16:34:36 sde1000 - * Added syslog support - * mpbin/mpstring functions moved from dh.c - * - * Revision 1.1 1996/03/14 17:05:03 sde1000 - * Initial revision +/* + * util.c + * - output and logging support + * - program lifetime support + * - IP address and subnet munging routines + * - MPI convenience functions + */ +/* + * This file is + * Copyright (C) 1995--2001 Stephen Early * + * It is part of secnet, which is + * Copyright (C) 1995--2001 Stephen Early + * Copyright (C) 1998 Ross Anderson, Eli Biham, Lars Knudsen + * + * This program 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, or (at your option) + * any later version. + * + * This program 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 this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include "config.h" +#include "secnet.h" #include -#include #include #include -#include #include -#include +#include #include -#include #include #include "util.h" -#include "secnet.h" +#include "unaligned.h" #define MIN_BUFFER_SIZE 64 #define DEFAULT_BUFFER_SIZE 4096 @@ -28,9 +45,7 @@ static char *hexdigits="0123456789abcdef"; -uint32_t message_level=M_WARNING|M_ERROR|M_FATAL; -uint32_t syslog_level=M_WARNING|M_ERROR|M_FATAL; -static uint32_t current_phase=0; +uint32_t current_phase=0; struct phase_hook { hook_fn *fn; @@ -40,108 +55,6 @@ struct phase_hook { static struct phase_hook *hooks[NR_PHASES]={NULL,}; -static void vMessage(uint32_t class, char *message, va_list args) -{ - FILE *dest=stdout; - if (class & message_level) { - if (class&M_FATAL || class&M_ERROR || class&M_WARNING) { - dest=stderr; - } - vfprintf(dest,message,args); - } -/* XXX do something about syslog output here */ -#if 0 - /* Maybe send message to syslog */ - vsprintf(buff, message, args); - /* XXX Send each line as a separate log entry */ - log(syslog_prio[level], buff); -#endif /* 0 */ -} - -void Message(uint32_t class, char *message, ...) -{ - va_list ap; - - va_start(ap,message); - - vMessage(class,message,ap); - - va_end(ap); -} - -static void vfatal(int status, bool_t perror, char *message, va_list args) -{ - int err; - - err=errno; - - enter_phase(PHASE_SHUTDOWN); - if (perror) { - Message(M_FATAL, "secnet fatal error: "); - vMessage(M_FATAL, message, args); - Message(M_FATAL, ": %s\n",strerror(err)); - } - else { - Message(M_FATAL, "secnet fatal error: "); - vMessage(M_FATAL,message,args); - } - exit(status); -} - -void fatal(char *message, ...) -{ - va_list args; - va_start(args,message); - vfatal(current_phase,False,message,args); - va_end(args); -} - -void fatal_status(int status, char *message, ...) -{ - va_list args; - va_start(args,message); - vfatal(status,False,message,args); - va_end(args); -} - -void fatal_perror(char *message, ...) -{ - va_list args; - va_start(args,message); - vfatal(current_phase,True,message,args); - va_end(args); -} - -void fatal_perror_status(int status, char *message, ...) -{ - va_list args; - va_start(args,message); - vfatal(status,True,message,args); - va_end(args); -} - -void cfgfatal(struct cloc loc, string_t facility, char *message, ...) -{ - va_list args; - - va_start(args,message); - - enter_phase(PHASE_SHUTDOWN); - - if (loc.file && loc.line) { - Message(M_FATAL, "config error (%s, %s:%d): ",facility,loc.file, - loc.line); - } else if (!loc.file && loc.line) { - Message(M_FATAL, "config error (%s, line %d): ",facility,loc.line); - } else { - Message(M_FATAL, "config error (%s): ",facility); - } - - vMessage(M_FATAL,message,args); - va_end(args); - exit(current_phase); -} - char *safe_strdup(char *s, char *message) { char *d; @@ -242,182 +155,12 @@ uint32_t write_mpbin(MP_INT *a, uint8_t *buffer, uint32_t buflen) return i; } -bool_t subnet_match(struct subnet_list *list, uint32_t address) -{ - uint32_t i; - for (i=0; ientries; i++) { - if (list->list[i].prefix == (address&list->list[i].mask)) return True; - } - return False; -} - -/* The string buffer must be at least 16 bytes long */ -string_t ipaddr_to_string(uint32_t addr) -{ - uint8_t a,b,c,d; - string_t s; - - s=safe_malloc(16,"ipaddr_to_string"); - a=addr>>24; - b=addr>>16; - c=addr>>8; - d=addr; - snprintf(s, 16, "%d.%d.%d.%d", a, b, c, d); - return s; -} - -string_t subnet_to_string(struct subnet *sn) -{ - uint32_t mask=sn->mask, addr=sn->prefix; - uint8_t a,b,c,d; - string_t s; - int i; - - s=safe_malloc(19,"subnet_to_string"); - a=addr>>24; - b=addr>>16; - c=addr>>8; - d=addr; - for (i=0; mask; i++) { - mask=(mask<<1); - } - snprintf(s, 19, "%d.%d.%d.%d/%d", a, b, c, d, i); - return s; -} - -int sys_cmd(const char *path, char *arg, ...) -{ - va_list ap; - int rv; - pid_t c; - - va_start(ap,arg); - c=fork(); - if (c) { - /* Parent -> wait for child */ - waitpid(c,&rv,0); - } else if (c==0) { - char *args[100]; - int i; - /* Child -> exec command */ - args[0]=arg; - i=1; - while ((args[i++]=va_arg(ap,char *))); - execvp(path,args); - exit(1); - } else { - /* Error */ - fatal_perror("sys_cmd(%s,%s,...)"); - } - - va_end(ap); - return rv; -} - -/* Take a list of log closures and merge them */ -struct loglist { - struct log_if *l; - struct loglist *next; -}; - -static void log_vmulti(void *state, int priority, char *message, va_list args) -{ - struct loglist *st=state, *i; - - for (i=st; i; i=i->next) { - i->l->vlog(i->l->st,priority,message,args); - } -} - -static void log_multi(void *st, int priority, char *message, ...) -{ - va_list ap; - - va_start(ap,message); - - log_vmulti(st,priority,message,ap); - - va_end(ap); -} - -struct log_if *init_log(list_t *ll) -{ - int i=0; - item_t *item; - closure_t *cl; - struct loglist *l=NULL, *n; - struct log_if *r; - - while ((item=list_elem(ll,i++))) { - if (item->type!=t_closure) { - cfgfatal(item->loc,"init_log","item is not a closure"); - } - cl=item->data.closure; - if (cl->type!=CL_LOG) { - cfgfatal(item->loc,"init_log","closure is not a logger"); - } - n=safe_malloc(sizeof(*n),"init_log"); - n->l=cl->interface; - n->next=l; - l=n; - } - if (!l) { - fatal("init_log: none of the items in the list are loggers"); - } - r=safe_malloc(sizeof(*r), "init_log"); - r->st=l; - r->log=log_multi; - r->vlog=log_vmulti; - return r; -} - -struct logfile { - closure_t cl; - struct log_if ops; - FILE *f; -}; - -static void logfile_vlog(void *state, int priority, char *message, - va_list args) -{ - struct logfile *st=state; - - vfprintf(st->f,message,args); - fprintf(st->f,"\n"); -} - -static void logfile_log(void *state, int priority, char *message, ...) -{ - va_list ap; - - va_start(ap,message); - logfile_vlog(state,priority,message,ap); - va_end(ap); -} - -static list_t *logfile_apply(closure_t *self, struct cloc loc, dict_t *context, - list_t *data) -{ - struct logfile *st; - - st=safe_malloc(sizeof(*st),"logfile_apply"); - st->cl.description="logfile"; - st->cl.type=CL_LOG; - st->cl.apply=NULL; - st->cl.interface=&st->ops; - st->ops.st=st; - st->ops.log=logfile_log; - st->ops.vlog=logfile_vlog; - st->f=stderr; /* XXX ignore args */ - - return new_closure(&st->cl); -} - static char *phases[NR_PHASES]={ "PHASE_INIT", "PHASE_GETOPTS", "PHASE_READCONFIG", "PHASE_SETUP", + "PHASE_GETRESOURCES", "PHASE_DROPPRIV", "PHASE_RUN", "PHASE_SHUTDOWN" @@ -427,12 +170,13 @@ void enter_phase(uint32_t new_phase) { struct phase_hook *i; - Message(M_DEBUG_PHASE,"entering %s... ", phases[new_phase]); + if (hooks[new_phase]) + Message(M_DEBUG_PHASE,"Running hooks for %s...\n", phases[new_phase]); current_phase=new_phase; for (i=hooks[new_phase]; i; i=i->next) i->fn(i->state, new_phase); - Message(M_DEBUG_PHASE,"now in %s\n",phases[new_phase]); + Message(M_DEBUG_PHASE,"Now in %s\n",phases[new_phase]); } bool_t add_hook(uint32_t phase, hook_fn *fn, void *state) @@ -522,7 +266,7 @@ void buf_append_string(struct buffer_if *buf, string_t s) uint16_t len; len=strlen(s); - *(uint16_t *)buf_append(buf,2)=htons(len); + buf_append_uint16(buf,len); memcpy(buf_append(buf,len),s,len); } @@ -583,7 +327,7 @@ static list_t *buffer_apply(closure_t *self, struct cloc loc, dict_t *context, buffer_new(&st->ops,len); if (lockdown) { - Message(M_WARNING,"buffer: XXX lockdown\n"); + /* XXX mlock the buffer if possible */ } return new_closure(&st->cl); @@ -592,6 +336,5 @@ static list_t *buffer_apply(closure_t *self, struct cloc loc, dict_t *context, init_module util_module; void util_module(dict_t *dict) { - add_closure(dict,"logfile",logfile_apply); add_closure(dict,"sysbuffer",buffer_apply); }