/* * Copyright 2001, 2002, 2003 David Mansfield and Cobite, Inc. * See COPYING file for license information */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "util.h" typedef int (*compare_func)(const void *, const void *); static void * string_tree; char *readfile(char const *filename, char *buf, size_t size) { FILE *fp; char *ptr; size_t len; fp = fopen(filename, "r"); if (!fp) return NULL; ptr = fgets(buf, size, fp); fclose(fp); if (!ptr) return NULL; len = strlen(buf); if (buf[len-1] == '\n') buf[len-1] = '\0'; return buf; } char *strrep(char *s, char find, char replace) { char * p = s; while (*p) { if (*p == find) *p = replace; p++; } return s; } char *get_cvsps_dir() { struct stat sbuf; static char prefix[PATH_MAX]; const char * home; if (prefix[0]) return prefix; if (!(home = getenv("HOME"))) { debug(DEBUG_APPERROR, "HOME environment variable not set"); exit(1); } if (snprintf(prefix, PATH_MAX, "%s/%s", home, CVSPS_PREFIX) >= PATH_MAX) { debug(DEBUG_APPERROR, "prefix buffer overflow"); exit(1); } /* Make sure the prefix directory exists */ if (stat(prefix, &sbuf) < 0) { int ret; ret = mkdir(prefix, 0777); if (ret < 0) { debug(DEBUG_SYSERROR, "Cannot create the cvsps directory '%s'", CVSPS_PREFIX); exit(1); } } else { if (!(S_ISDIR(sbuf.st_mode))) debug(DEBUG_APPERROR, "cvsps directory '%s' is not a directory!", CVSPS_PREFIX); } return prefix; } char *xstrdup(char const *str) { char *ret; assert(str); ret = strdup(str); if (!ret) { debug(DEBUG_ERROR, "strdup failed"); exit(1); } return ret; } void strzncpy(char * dst, const char * src, int n) { strncpy(dst, src, n); dst[n - 1] = 0; } char *get_string(char const *str) { char ** res; if (!str) return NULL; res = (char **)tfind(str, &string_tree, (compare_func)strcmp); if (!res) { char *key = xstrdup(str); res = (char **)tsearch(key, &string_tree, (compare_func)strcmp); *res = key; } return *res; } static int get_int_substr(const char * str, const regmatch_t * p) { char buff[256]; memcpy(buff, str + p->rm_so, p->rm_eo - p->rm_so); buff[p->rm_eo - p->rm_so] = 0; return atoi(buff); } static time_t mktime_utc(struct tm * tm) { char * old_tz = getenv("TZ"); time_t ret; setenv("TZ", "UTC", 1); tzset(); ret = mktime(tm); if (old_tz) setenv("TZ", old_tz, 1); else unsetenv("TZ"); tzset(); return ret; } void convert_date(time_t * t, const char * dte) { static regex_t date_re; static int init_re; #define MAX_MATCH 16 size_t nmatch = MAX_MATCH; regmatch_t match[MAX_MATCH]; if (!init_re) { if (regcomp(&date_re, "([0-9]{4})[-/]([0-9]{2})[-/]([0-9]{2}) ([0-9]{2}):([0-9]{2}):([0-9]{2})", REG_EXTENDED)) { fprintf(stderr, "FATAL: date regex compilation error\n"); exit(1); } init_re = 1; } if (regexec(&date_re, dte, nmatch, match, 0) == 0) { regmatch_t * pm = match; struct tm tm = {0}; /* first regmatch_t is match location of entire re */ pm++; tm.tm_year = get_int_substr(dte, pm++); tm.tm_mon = get_int_substr(dte, pm++); tm.tm_mday = get_int_substr(dte, pm++); tm.tm_hour = get_int_substr(dte, pm++); tm.tm_min = get_int_substr(dte, pm++); tm.tm_sec = get_int_substr(dte, pm++); tm.tm_year -= 1900; tm.tm_mon--; *t = mktime_utc(&tm); } else { *t = atoi(dte); } } static struct timeval start_time; void timing_start() { gettimeofday(&start_time, NULL); } void timing_stop(const char * msg) { struct timeval stop_time; gettimeofday(&stop_time, NULL); stop_time.tv_sec -= start_time.tv_sec; stop_time.tv_usec -= start_time.tv_usec; if (stop_time.tv_usec < 0) stop_time.tv_sec--,stop_time.tv_usec += 1000000; printf("Elapsed time for %s: %d.%06d\n", msg, (int)stop_time.tv_sec, (int)stop_time.tv_usec); } extern char ** environ; /* taken from the linux manual page for system */ int my_system (const char *command) { int pid, status; if (command == 0) return 1; pid = fork(); if (pid == -1) return -1; if (pid == 0) { char *argv[4]; argv[0] = "sh"; argv[1] = "-c"; argv[2] = (char*)command; /* discard const */ argv[3] = 0; execve("/bin/sh", argv, environ); exit(127); } do { if (waitpid(pid, &status, 0) == -1) { if (errno != EINTR) return -1; } else return status; } while(1); } int escape_filename(char * dst, int len, const char * src) { static char * naughty_chars = " \\\"'@<>=;|&()#$`?*[!:{"; if (len > 0) { while (len > 1 && *src) { if (strchr(naughty_chars, *src)) { if (len == 2) break; *dst++ = '\\'; len--; } *dst++ = *src++; len--; } *dst = 0; } return (*src == 0) ? 0 : -1; }