/* This file is in the public domain. */ #include #include #include #include #include #include extern const char *__progname; #include "panic.h" #include "config.h" #include "nested.h" #include "stdio-util.h" #include "util.h" char *blk_to_cstr(const void *data, int len) { char *t; t = malloc(len+1); if (t) { if (len) bcopy(data,t,len); t[len] = '\0'; } return(t); } int comma_list(const void *s, int len, int (*fn)(const void *, int)) { int beg; int i; int v; int rv; rv = 0; beg = 0; i = 0; do { if ((i >= len) || (((const unsigned char *)s)[i] == ',')) { v = (*fn)(((const char *)s)+beg,i-beg); if (v < 0) return(v); rv += v; beg = i + 1; } i ++; } while (i <= len); return(rv); } int zstrcmp(const char *a, const char *b) { return( a ? b ? strcmp(a,b) : 1 : b ? -1 : 0 ); } /* * This is pretty gross. There really should be (a) a way to suppress * the leading %s: part in setproctitle and (b) a vsetproctitle * (taking a format string and a va_list). * * We could just steal-and-edit the implementation of setproctitle, but * that would be even less portable than this is. */ void spt_av0(const char *av0, const char *fmt, ...) { char *s; FILE *f; const char *ppn; va_list ap; f = fopen_alloc(&s,0); va_start(ap,fmt); vfprintf(f,fmt,ap); putc('\0',f); va_end(ap); fclose(f); ppn = __progname; __progname = av0; setproctitle("%s",s); __progname = ppn; free(s); } int moussh_fork(void) { pid_t rv; rv = fork(); if (rv == 0) { volatile int n; for (n=config_int("fork-pause");n>0;n--) poll(0,0,1000); } return(rv); } unsigned int parse_time(const char *s, int l, void (*fail)(const char *, ...)) { unsigned int n; int nl; unsigned int nextunit; unsigned int time; int o; NESTED char nget(void) { return((o>=l)?'\0':s[o++]); } while ((l > 0) && isspace((unsigned char)*s)) { s ++; l --; } time = 0; nextunit = 1; while (1) { if ((l < 1) || isspace((unsigned char)*s)) break; o = 0; nl = parse_number(&nget,&n); if (! nl) break; s += nl; l -= nl; if ((l < 1) || isspace((unsigned char)*s)) { time += n * nextunit; break; } switch (*s) { case 'w': time += n * 604800; nextunit = 86400; break; case 'd': time += n * 86400; nextunit = 3600; break; case 'h': time += n * 3600; nextunit = 60; break; case 'm': time += n * 60; nextunit = 1; break; case 's': time += n; nextunit = 1; break; default: (*fail)("Unknown time unit character `%c'",*s); panic("(*fail)() returned"); break; } s ++; l --; } while ((l > 0) && isspace((unsigned char)*s)) { s ++; l --; } if (l > 0) { (*fail)("Junk after time (char %c)",*s); panic("(*fail)() returned"); } return(time); } int parse_number(char (*get)(void), unsigned int *vp) { unsigned int n; char c; int cc; n = 0; cc = 0; while <"digits"> (1) { c = (*get)(); switch (c) { case '0': n = n * 10 ; break; case '1': n = (n * 10) + 1; break; case '2': n = (n * 10) + 2; break; case '3': n = (n * 10) + 3; break; case '4': n = (n * 10) + 4; break; case '5': n = (n * 10) + 5; break; case '6': n = (n * 10) + 6; break; case '7': n = (n * 10) + 7; break; case '8': n = (n * 10) + 8; break; case '9': n = (n * 10) + 9; break; default: break <"digits">; } cc ++; } *vp = n; return(cc); }