"Fossies" - the Fresh Open Source Software Archive

Member "rgdbm-2.1.42/sup.c" (18 Jun 2007, 7290 Bytes) of package /linux/privat/old/rgdbm-2.1.42.tgz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "sup.c" see the Fossies "Dox" file reference documentation.

    1 
    2 /* 
    3  * RGDBM auxilary functions (C) Peter T. Breuer 2007 for those portions
    4  * that aren't a straight lift out of gnu glibc6. I wrote all but
    5  * "realpath" without looking there, however, but then the
    6  * "obvious to one skilled in the art" criteria probably protects one
    7  * against patent violations and I didn't look at anything except the
    8  * man page specifications for anythng apart from realpath.
    9  *
   10  * This code is releasd under the GNU General Public Licence (GPL)
   11  * version 2 or such later version as the FSF may release in the
   12  * fullness of time (when this licence automatically becomes THAT
   13  * licence). See GPL_V2 file in the code archive for details.
   14  */
   15 
   16 #include "config.h"
   17 
   18 #include "sup.h"
   19 
   20 #ifndef HAVE_STRNDUP
   21 # warning substituting own strndup() function
   22 char *
   23 strndup(const char *str, size_t n) 
   24 {
   25     char *p;
   26 
   27     if (!str)
   28         return NULL;
   29     if (n < 0)
   30         return NULL;
   31 
   32     for (p = (char *)str; *p && p < str + n; p++)
   33         /* nada */ ;
   34 
   35     if (*p) {
   36         // overlength
   37         p = malloc(n + 1);
   38         if (!p)
   39             return NULL;
   40         strncpy(p, str, n);
   41         p[n] = 0;
   42         return p;
   43     }
   44     // underlength
   45     n = p - str;
   46     p = malloc(n + 1);
   47     if (!p)
   48         return NULL;
   49     strncpy(p, str, n);
   50     p[n] = 0;
   51     return p;
   52 }
   53 #endif          /* !defined(HAVE_STRNDUP) */
   54 
   55 #ifndef HAVE_STRDUP
   56 # warning substituting own strdup() function
   57 char *
   58 strdup(const char *str) 
   59 {
   60     int n;
   61     char *p;
   62 
   63     if (!str)
   64         return NULL;
   65     n = strlen(str);
   66     p = malloc(n + 1);
   67     if (!p)
   68         return NULL;
   69     strcpy(p, str);
   70     return p;
   71 }
   72 #endif          /* !defined(HAVE_STRDUP) */
   73 
   74 #ifndef HAVE_DAEMON
   75 # warning substituting own daemon() function
   76 int
   77 daemon(int nochdir, int noclose) 
   78 {
   79     int err;
   80 
   81     err = fork();
   82     if (err < 0)
   83         return err;
   84     if (err > 0)
   85         _exit(0);  // old superstition
   86 
   87     err = setsid();
   88     if (err < 0)
   89         return err;
   90 
   91     if (!nochdir) {
   92         err = chdir("/");
   93         if (err < 0)
   94             return err;
   95     }
   96 
   97     if (!noclose) {
   98         if (!freopen("/dev/null", "r", stdin))
   99             return -1;
  100         if (!freopen("/dev/null", "w", stdout))
  101             return -1;
  102         if (!freopen("/dev/null", "w", stderr))
  103             return -1;
  104     }
  105 
  106     return 0;
  107 }
  108 #endif          /* !defined(HAVE_DAEMON) */
  109 
  110 #ifndef HAVE_REALPATH
  111 # warning substituting own realpath() function
  112 /*
  113  * This is mostly from glibc, with minor symplifications and max links
  114  * set at 20 if it's not defined in sys/param.h
  115  */
  116 char *
  117 realpath (const char *name, char *resolved)
  118 {
  119     char *rpath, *dest, *extra_buf = NULL;
  120     const char *start, *end, *rpath_limit;
  121     static const long int path_max = PATH_MAX;
  122     int num_links = 0;
  123 
  124     if (!name)
  125         return NULL;
  126 
  127     if (!*name)
  128         return NULL;
  129 
  130     if (!resolved) {
  131         rpath = malloc (path_max);
  132         if (!rpath)
  133             return NULL;
  134     }
  135     else
  136         rpath = resolved;
  137 
  138     rpath_limit = rpath + path_max;
  139 
  140     if (*name != '/') {
  141         if (!getcwd (rpath, path_max)) {
  142             *rpath = 0;
  143             goto error;
  144         }
  145         dest = strchr (rpath, '\0');
  146     }
  147     else {
  148         *rpath = '/';
  149         dest = rpath + 1;
  150     }
  151 
  152     for (start = end = name; *start; start = end) {
  153 
  154         struct stat st;
  155         int n;
  156 
  157         while (*start == '/')
  158             ++start;
  159 
  160         for (end = start; *end && *end != '/'; ++end)
  161             /* Nada  */ ;
  162 
  163         if (end - start == 0)
  164             break;
  165         else if (end - start == 1 && *start == '.')
  166             /* Nada */ ;
  167         else if (end - start == 2 && *start == '.' && start[1] == '.') {
  168             if (dest > rpath + 1)
  169                 while ((--dest)[-1] != '/') ;
  170         }
  171         else {
  172             size_t new_size;
  173 
  174             if (dest[-1] != '/')
  175                 *dest++ = '/';
  176 
  177             if (dest + (end - start) >= rpath_limit) {
  178 
  179                 ptrdiff_t dest_offset = dest - rpath;
  180                 char *new_rpath;
  181 
  182                 if (resolved) {
  183                     if (dest > rpath + 1)
  184                         dest--;
  185                     *dest = 0;
  186                     goto error;
  187                 }
  188                 new_size = rpath_limit - rpath;
  189                 if (end - start + 1 > path_max)
  190                     new_size += end - start + 1;
  191                 else
  192                     new_size += path_max;
  193                 new_rpath = (char *) realloc (rpath, new_size);
  194                 if (!new_rpath)
  195                     goto error;
  196                 rpath = new_rpath;
  197                 rpath_limit = rpath + new_size;
  198 
  199                 dest = rpath + dest_offset;
  200             }
  201 
  202             dest = memcpy (dest, start, end - start);
  203             *dest = 0;
  204 
  205             if (stat (rpath, &st) < 0)
  206                 goto error;
  207 
  208             if (S_ISLNK (st.st_mode)) {
  209 
  210                 char *buf = alloca (path_max);
  211                 size_t len;
  212                 static const int maxsymlinks =
  213 #ifdef MAXSYMLINKS
  214                     MAXSYMLINKS
  215 #else
  216                     20
  217                 ;
  218 #endif /* MAXSYMLINKS */
  219 
  220                 if (++num_links > maxsymlinks)
  221                     goto error;
  222 
  223                 n = readlink (rpath, buf, path_max);
  224                 if (n < 0)
  225                     goto error;
  226                 buf[n] = 0;
  227 
  228                 if (!extra_buf)
  229                     extra_buf = alloca (path_max);
  230 
  231                 len = strlen (end);
  232                 if ((long int) (n + len) >= path_max) {
  233                     goto error;
  234                 }
  235 
  236                 memmove (&extra_buf[n], end, len + 1);
  237                 name = end = memcpy (extra_buf, buf, n);
  238 
  239                 if (buf[0] == '/')
  240                     dest = rpath + 1;   /* It's an absolute symlink */
  241                 else if (dest > rpath + 1)       /// DANGER FIXME
  242                     while ((--dest)[-1] != '/') ;
  243             }
  244         }
  245     }
  246     if (dest > rpath + 1 && dest[-1] == '/')
  247         --dest;
  248     *dest = 0;
  249 
  250     return resolved ? memcpy (resolved, rpath, dest - rpath + 1) : rpath;
  251 
  252   error:
  253     if (resolved)
  254         strcpy (resolved, rpath);
  255     else
  256         free (rpath);
  257     return NULL;
  258 }
  259 #endif          /* !defined(HAVE_REALPATH) */
  260 
  261 /*
  262  * convert an integer in the range 0-63 inclusive
  263  * into a character a-zA-Z./
  264  */
  265 int 
  266 num2alpha64(unsigned int x)
  267 {
  268     x %= 64;
  269 
  270     if (x < 26)
  271         x += 'a';
  272     else if (x < 52)
  273         x += 'A' - 26;
  274     else if (x < 62)
  275         x += '0' - 52;
  276     else if (x < 63)
  277         x = '.';
  278     else if (x < 64)
  279         x = '/';
  280     else
  281         x = -1;
  282     return x;
  283 }
  284 
  285 /*
  286  * convert a char in the range a-zA-Z./ to a number 0-63.
  287  */
  288 int
  289 alpha2num64(int x) {
  290 
  291     if (x >= 'a' && x <= 'z') {
  292         x -= 'a';
  293     } else if (x >= 'A' && x <= 'Z') {
  294         x -= 'A' - 26;
  295     } else if (x >= '0' && x <= '9') {
  296         x -= '0' - 52;
  297     } else if (x == '.') {
  298         x = 62;
  299     } else if (x == '/') {
  300         x = 63;
  301     } else 
  302         x = -1;
  303     return x;
  304 }
  305 
  306 /*
  307  * find the last bit set in @x. If @x is 0, the output is -1. If @x is,
  308  * say, 5, the output is 2. In general it is @n, where the most
  309  * signiificant bit set in @x is the @nth.
  310  */
  311 int
  312 fls (unsigned int x)
  313 {
  314     int n = 0;
  315 
  316     while ((x >> n) != 0)
  317         n++;
  318     return n - 1;
  319 }
  320