#include #include #include #include #include #include #include #include #include #include #include "dpid_common.h" #include "misc_new.h" /* for function prototypes */ /* define to 1 when checking for memory leaks * \todo * Eliminate need for a_Misc_get_home and a_Misc_get_user when testing for * memory leaks by using ld --wrap option to replace g_get_home_dir and * g_get_user_name with wrapper functions. */ #ifndef TEST #define TEST 0 #endif /* * Close a FD handling EINTR. */ gint a_Misc_close_fd(gint fd) { gint st; do { st = close(fd); } while (st < 0 && errno == EINTR); return st; } /* * Return the user's home directory. * Don't free the returned string! */ gchar *a_Misc_get_home(void) { gchar *ret; ret = (TEST) ? getenv("HOME") : g_get_home_dir(); return ret; } /* * Return the user. * Don't free the returned string! */ gchar *a_Misc_get_user(void) { gchar *ret; ret = (TEST) ? getenv("USER") : g_get_user_name(); return ret; } /* * Prepend the users home-dir to 'file' string i.e, * pass in .dillo/bookmarks.html and it will return * /home/imain/.dillo/bookmarks.html * * Remember to g_free() returned value! * copied from misc.c */ gchar *a_Misc_prepend_user_home(const char *file) { return (g_strconcat(a_Misc_get_home(), "/", file, NULL)); } /* * Read a line of text up to the newline character, store it into a newly * allocated string and return it. * (copied from dpi/bm_srv12.c) */ char *a_Misc_get_line(FILE *stream) { guint i, size = 64; int ch; char *buf; buf = g_new(char, size); for (i = 0; (ch = fgetc(stream)) != EOF; ++i) { if (i + 1 == size) { size *= 2; buf = g_realloc(buf, size); } if ((buf[i] = ch) == '\n' && ++i) break; } buf[i] = 0; if (i > 0) { buf = g_realloc(buf, i + 1); } else { g_free(buf); buf = NULL; } return buf; } /*! Reads a dpi tag from a socket * \li Continues after a signal interrupt * \Return * Gstring pointer to tag on success, NULL on failure * \important Caller is responsible for freeing the returned GString * */ GString *a_Misc_rdtag(int socket) { char c = '\0'; ssize_t rdlen; GString *tag; tag = g_string_new(NULL); errno = 0; do { rdlen = read(socket, &c, 1); if (rdlen == -1 && errno != EINTR) break; g_string_append_c(tag, c); } while (c != '>'); if (rdlen == -1) { perror("a_Misc_rdtag"); g_string_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 *) g_malloc(tagmem + 1); for (i = 0; (rdln = read(sock, &c, 1)) != 0; i++) { if (i == tagmem) { tagmem += tagmem; tag = (char *) g_realloc(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 GString * */ /* Is this useful? int a_Misc_nohang_rdtag(int socket, int timeout, GString **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) { fprintf(stderr, "%s:%d: a_Misc_nohang_rdtag: %s\n", __FILE__, __LINE__, g_strerror(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. * (adapted from dietlibc) */ char *a_Misc_mkdtemp(char *template) { char *tmp = template + strlen(template) - 6; int i; unsigned int random; if (tmp < template) goto error; for (i = 0; i < 6; ++i) if (tmp[i] != 'X') { error: errno = EINVAL; return 0; } srand((guint)(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 (mkdir(template, 0700) == 0) break; if (errno == EEXIST) continue; return 0; } return template; }