X-Git-Url: http://git.marmaro.de/?p=mmh;a=blobdiff_plain;f=sbr%2Futils.c;h=ef0ee9738676d018b9c191f3d339cf89593b04ff;hp=bc171772c8a9b91b45941aafb370cbcbfa8b76e0;hb=eb650f703c26232c0ccce00c9b3dd3f6b6d51dd4;hpb=81a21a9a97d8633f6d6231e31fdb6e328d0d3ff2 diff --git a/sbr/utils.c b/sbr/utils.c index bc17177..ef0ee97 100644 --- a/sbr/utils.c +++ b/sbr/utils.c @@ -1,29 +1,236 @@ - /* - * utils.c -- various utility routines - * - * $Id$ - * - * This code is Copyright (c) 2006, by the authors of nmh. See the - * COPYRIGHT file in the root directory of the nmh distribution for - * complete copyright information. - */ +** utils.c -- various utility routines +** +** This code is Copyright (c) 2006, by the authors of nmh. See the +** COPYRIGHT file in the root directory of the nmh distribution for +** complete copyright information. +*/ -#include +#include #include #include +#include +#include +#include +#include +#include + +/* +** We allocate space for messages (msgs array) +** this number of elements at a time. +*/ +#define MAXMSGS 256 + +/* +** Safely call realloc +*/ +void * +mh_xrealloc(void *ptr, size_t size) +{ + void *memory; + /* Some non-POSIX realloc()s don't cope with realloc(NULL,sz) */ + if (!ptr) { + return mh_xcalloc(1, size); + } + if (size == 0) { + adios(EX_SOFTWARE, NULL, "Tried to realloc 0 bytes"); + } + + memory = realloc(ptr, size); + if (!memory) { + adios(EX_OSERR, NULL, "Realloc failed"); + } + + return memory; +} + +/* +** Safely call calloc +*/ void * -mh_xmalloc(size_t size) +mh_xcalloc(size_t nmemb, size_t size) +{ + void *memory; + + if (nmemb == 0 || size == 0) { + adios(EX_SOFTWARE, NULL, "Tried to calloc 0 bytes"); + } + + if ((memory = calloc(nmemb, size))) { + return memory; + } else { + adios(EX_OSERR, NULL, "calloc failed"); + } +} + +/* +** Free a pointer and set it to NULL. +*/ +void +mh_free0(void * ptr) +{ + void ** p; + p = ptr; + free(*p); + *p = NULL; +} + +/* +** Return the present working directory, if the current directory does not +** exist, or is too long, make / the pwd. +*/ +char * +pwd(void) +{ + char *cp; + static char curwd[PATH_MAX]; + + if (!getcwd(curwd, PATH_MAX)) { + admonish(NULL, "unable to determine working directory"); + if (!mypath || !*mypath || + (strcpy(curwd, mypath), chdir(curwd)) == -1) { + strcpy(curwd, "/"); + chdir(curwd); + } + return curwd; + } + + if ((cp = curwd + strlen(curwd) - 1) > curwd && *cp == '/') { + /* strip trailing slash */ + *cp = '\0'; + } + + return curwd; +} + +/* +** add -- If "s1" is NULL, this routine just creates a +** -- copy of "s2" into newly malloc'ed memory. +** -- (use mh_xstrdup() instead in this case) +** -- +** -- If "s1" is not NULL, then copy the concatenation +** -- of "s1" and "s2" (note the order) into newly +** -- malloc'ed memory. Then free "s1". +*/ +char * +add(const char *s2, char *s1) { - void *memory; + char *cp; + size_t len1 = 0, len2 = 0; + + if (s1) { + len1 = strlen(s1); + } + if (s2) { + len2 = strlen(s2); + } + + cp = mh_xcalloc(len1 + len2 + 1, sizeof(char)); + + /* Copy s1 and free it */ + if (s1) { + memcpy(cp, s1, len1); + mh_free0(&s1); + } + + /* Copy s2 */ + if (s2) { + memcpy(cp + len1, s2, len2); + } + + /* Now NULL terminate the string */ + cp[len1 + len2] = '\0'; + + return cp; +} - if (size == 0) - adios(NULL, "Tried to malloc 0 bytes"); - memory = malloc(size); - if (!memory) - adios(NULL, "Malloc failed"); +/* +** create_folder +** Check to see if a folder exists, if not, prompt the user to create it. +*/ +void +create_folder(char *folder, int autocreate, void (*done_callback)(int)) +{ + struct stat st; + extern int errno; + char *cp; - return memory; + if (stat(folder, &st) == -1) { + if (errno != ENOENT) { + adios(EX_IOERR, folder, "error on folder"); + } + if (autocreate == 0) { + /* ask before creating folder */ + cp = concat("Create folder \"", folder, "\"? ", NULL); + if (!getanswer(cp)) { + done_callback(EX_CANTCREAT); + } + mh_free0(&cp); + } else if (autocreate == -1) { + /* do not create, so exit */ + done_callback(EX_CANTCREAT); + } + if (!makedir(folder)) { + adios(EX_CANTCREAT, NULL, "unable to create folder %s", folder); + } + } +} + +/* +** num_digits +** Return the number of digits in a nonnegative integer. +*/ +int +num_digits(int n) +{ + int ndigits = 0; + + /* Sanity check */ + if (n < 0) { + adios(EX_SOFTWARE, NULL, "oops, num_digits called with negative value"); + } + + if (n == 0) { + return 1; + } + + while (n) { + n /= 10; + ndigits++; + } + + return ndigits; +} + +/* +** Append a message arg to an array of them, resizing it if necessary. +** The function is written to suit the arg parsing code it was extracted +** from, and will probably be changed when the other code is cleaned up. +*/ +void +app_msgarg(struct msgs_array *msgs, char *cp) +{ + if(msgs->size >= msgs->max) { + msgs->msgs = mh_xrealloc(msgs->msgs, + (msgs->max+=MAXMSGS)*sizeof(*msgs->msgs)); + } + msgs->msgs[msgs->size++] = cp; +} + +/* +** mh_xstrdup() is a wrapper of strdup() to replace getcpy(). It returns +** a copy of its argument if this is nonnull; otherwise, it returns a +** string of length 0. +*/ +char * +mh_xstrdup(char * s) +{ + char * tmp; + tmp = strdup(s ? s : ""); + if (!tmp) { + adios(EX_OSERR, "strdup", "can't copy string"); + } + return tmp; }