Mercurial > dillo_port1.3
view dpid/misc_new.c @ 1976:041d4979092f
Made on-the-fly control panel work again
author | Jorge Arellano Cid <jcid@dillo.org> |
---|---|
date | Thu, 21 Apr 2011 13:14:44 -0300 |
parents | 6c8346ed1073 |
children | 16e52ecf20a8 |
line wrap: on
line source
/* * File: misc_new.c * * Copyright 2008 Jorge Arellano Cid <jcid@dillo.org> * * 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 3 of the License, or * (at your option) any later version. */ #include <errno.h> /* errno, err-codes */ #include <unistd.h> #include <time.h> #include <sys/stat.h> /* stat */ #include <stdlib.h> /* rand, srand */ #include "../dlib/dlib.h" #include "dpid_common.h" #include "misc_new.h" /* for function prototypes */ /* * Close a FD handling EINTR. */ int a_Misc_close_fd(int fd) { int st; do { st = close(fd); } while (st < 0 && errno == EINTR); return st; } /*! Reads a dpi tag from a socket * \li Continues after a signal interrupt * \Return * Dstr pointer to tag on success, NULL on failure * \important Caller is responsible for freeing the returned Dstr * */ Dstr *a_Misc_rdtag(int socket) { char c = '\0'; ssize_t rdlen; Dstr *tag; tag = dStr_sized_new(64); errno = 0; do { rdlen = read(socket, &c, 1); if (rdlen == -1 && errno != EINTR) break; dStr_append_c(tag, c); } while (c != '>'); if (rdlen == -1) { perror("a_Misc_rdtag"); dStr_free(tag, TRUE); return (NULL); } return (tag); } /*! * Read a dpi tag from sock * \return * pointer to dynamically allocated request tag */ char *a_Misc_readtag(int sock) { char *tag, c, buf[10]; size_t buflen, i; size_t taglen = 0, tagmem = 10; ssize_t rdln = 1; tag = NULL; buf[0] = '\0'; buflen = sizeof(buf) / sizeof(buf[0]); // new start tag = (char *) dMalloc(tagmem + 1); for (i = 0; (rdln = read(sock, &c, 1)) != 0; i++) { if (i == tagmem) { tagmem += tagmem; tag = (char *) dRealloc(tag, tagmem + 1); } tag[i] = c; taglen += rdln; if (c == '>') { tag[i + 1] = '\0'; break; } } // new end if (rdln == -1) { ERRMSG("a_Misc_readtag", "read", errno); } return (tag); } /*! Reads a dpi tag from a socket without hanging on read. * \li Continues after a signal interrupt * \Return * \li 1 on success * \li 0 if input is not available within timeout microseconds. * \li -1 on failure * \important Caller is responsible for freeing the returned Dstr * */ /* Is this useful? int a_Misc_nohang_rdtag(int socket, int timeout, Dstr **tag) { int n_fd; fd_set sock_set, select_set; struct timeval tout; FD_ZERO(&sock_set); FD_SET(socket, &sock_set); errno = 0; do { select_set = sock_set; tout.tv_sec = 0; tout.tv_usec = timeout; n_fd = select(socket + 1, &select_set, NULL, NULL, &tout); } while (n_fd == -1 && errno == EINTR); if (n_fd == -1) { MSG_ERR("%s:%d: a_Misc_nohang_rdtag: %s\n", __FILE__, __LINE__, dStrerror(errno)); return(-1); } if (n_fd == 0) { return(0); } else { *tag = a_Misc_rdtag(socket); return(1); } } */ /* * Alternative to mkdtemp(). * Not as strong as mkdtemp, but enough for creating a directory. */ char *a_Misc_mkdtemp(char *template) { for (;;) { if (a_Misc_mkfname(template) && mkdir(template, 0700) == 0) break; if (errno == EEXIST) continue; return 0; } return template; } /* * Return a new, nonexistent file name from a template * (adapted from dietlibc; alternative to mkdtemp()) */ char *a_Misc_mkfname(char *template) { char *tmp = template + strlen(template) - 6; int i; uint_t random; struct stat stat_buf; if (tmp < template) goto error; for (i = 0; i < 6; ++i) if (tmp[i] != 'X') { error: errno = EINVAL; return 0; } srand((uint_t)(time(0) ^ getpid())); for (;;) { random = (unsigned) rand(); for (i = 0; i < 6; ++i) { int hexdigit = (random >> (i * 5)) & 0x1f; tmp[i] = hexdigit > 9 ? hexdigit + 'a' - 10 : hexdigit + '0'; } if (stat(template, &stat_buf) == -1 && errno == ENOENT) return template; MSG_ERR("a_Misc_mkfname: another round for %s \n", template); } } /* * Return a new, random hexadecimal string of 'nchar' characters. */ char *a_Misc_mksecret(int nchar) { int i; uint_t random; char *secret = dNew(char, nchar + 1); srand((uint_t)(time(0) ^ getpid())); random = (unsigned) rand(); for (i = 0; i < nchar; ++i) { int hexdigit = (random >> (i * 5)) & 0x0f; secret[i] = hexdigit > 9 ? hexdigit + 'a' - 10 : hexdigit + '0'; } secret[i] = 0; MSG("a_Misc_mksecret: %s\n", secret); return secret; }