X-Git-Url: http://dolda2000.com/gitweb/?a=blobdiff_plain;f=common%2Futils.c;h=49fb11bdc42b72e2219d2d446775dd12b76a5e0e;hb=refs%2Fheads%2Fjava;hp=cdf2bc6de0bf3405a2925e6dbdb562e7fdbfbea0;hpb=8b17e919cee63400e6de2c5f699c0a88d226b7e6;p=doldaconnect.git diff --git a/common/utils.c b/common/utils.c index cdf2bc6..49fb11b 100644 --- a/common/utils.c +++ b/common/utils.c @@ -1,6 +1,6 @@ /* * Dolda Connect - Modular multiuser Direct Connect-style client - * Copyright (C) 2004 Fredrik Tolf (fredrik@dolda2000.com) + * Copyright (C) 2004 Fredrik Tolf * * 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 @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include +#include #include #include #include @@ -29,6 +29,7 @@ #include #include #include +#include #ifdef HAVE_CONFIG_H #include @@ -79,14 +80,19 @@ char *vsprintf2(char *format, va_list al) { int ret; char *buf; + va_list al2; - ret = vsnprintf(NULL, 0, format, al); + va_copy(al2, al); + ret = vsnprintf(NULL, 0, format, al2); + va_end(al2); if((buf = malloc(ret + 1)) == NULL) { LOGOOM(ret + 1); return(NULL); } - vsnprintf(buf, ret + 1, format, al); + va_copy(al2, al); + vsnprintf(buf, ret + 1, format, al2); + va_end(al2); return(buf); } @@ -106,10 +112,18 @@ wchar_t *vswprintf2(wchar_t *format, va_list al) int ret; wchar_t *buf; size_t bufsize; + va_list al2; buf = smalloc(sizeof(wchar_t) * (bufsize = 1024)); - while((ret = vswprintf(buf, bufsize, format, al)) < 0) + while(1) + { + va_copy(al2, al); + ret = vswprintf(buf, bufsize, format, al2); + va_end(al2); + if(ret >= 0) + break; buf = srealloc(buf, sizeof(wchar_t) * (bufsize *= 2)); + } if(bufsize > ret + 1) buf = srealloc(buf, sizeof(wchar_t) * (ret + 1)); return(buf); @@ -428,11 +442,7 @@ int wcsexists(wchar_t *h, wchar_t *n) #ifndef HAVE_WCSCASECMP int wcscasecmp(const wchar_t *s1, const wchar_t *s2) { - while(towlower(*s1) == towlower(*s2)) - { - if(*s1 == L'\0') - return(0); - } + for(; (towlower(*s1) == towlower(*s2)) && (*s1 != L'\0'); s1++, s2++); return(towlower(*s1) - towlower(*s2)); } #endif @@ -466,41 +476,39 @@ char *hexencode(char *data, size_t datalen) char *hexdecode(char *data, size_t *len) { - char *buf, this; + char *buf, this, bit; size_t bufsize, bufdata; buf = NULL; bufsize = bufdata = 0; - for(; *data; data++) + for(bit = 4, this = 0; *data; data++) { if((*data >= 'A') && (*data <= 'F')) { - this = (this & 0x0F) | ((*data - 'A' + 10) << 4); + this |= (this & 0x0F) | ((*data - 'A' + 10) << bit); + } else if((*data >= 'a') && (*data <= 'f')) { + this |= (this & 0x0F) | ((*data - 'a' + 10) << bit); } else if((*data >= '0') && (*data <= '9')) { - this = (this & 0x0F) | ((*data - '0') << 4); + this |= (this & 0x0F) | ((*data - '0') << bit); + } else if(*data == '\n') { + continue; } else { if(buf != NULL) free(buf); return(NULL); } - data++; - if(!*data) - { - if(buf != NULL) - free(buf); - return(NULL); - } - if((*data >= 'A') && (*data <= 'F')) - { - this = (this & 0xF0) | (*data - 'A' + 10); - } else if((*data >= '0') && (*data <= '9')) { - this = (this & 0xF0) | (*data - '0'); + if(bit == 4) { + bit = 0; } else { - if(buf != NULL) - free(buf); - return(NULL); + bit = 4; + addtobuf(buf, this); + this = 0; } - addtobuf(buf, this); + } + if(bit != 4) { + if(buf != NULL) + free(buf); + return(NULL); } addtobuf(buf, 0); if(len != NULL) @@ -732,31 +740,38 @@ char *getetcpath(char *binpath) return(etcpath); } -char *findfile(char *gname, char *uname, char *homedir, int filldef) +char *findfile(char *name, char *homedir, int filldef) { char *path, *binpath, *etcpath, *p; struct passwd *pw; - int mode; + int mode, homeonly; + if(name == NULL) + return(NULL); + mode = R_OK | (filldef ? W_OK : 0); - if(uname != NULL) { + homeonly = homedir != NULL; + + if(!strchr(name, '/')) + { if(homedir == NULL) homedir = getenv("HOME"); if((homedir == NULL) && ((pw = getpwuid(getuid())) != NULL)) homedir = pw->pw_dir; - if((homedir != NULL) && ((path = sprintf2("%s/.%s", homedir, uname)) != NULL)) + if((homedir != NULL) && ((path = sprintf2("%s/.%s", homedir, name)) != NULL)) { if(!access(path, mode)) return(path); free(path); } } - if(gname != NULL) + + if(!homeonly) { - if(strchr(gname, '/') != NULL) + if(strchr(name, '/') != NULL) { - if(!access(gname, mode)) - return(sstrdup(gname)); + if(!access(name, mode)) + return(sstrdup(name)); } else { if((binpath = getenv("PATH")) == NULL) etcpath = sstrdup("/usr/local/etc:/etc:/usr/etc"); @@ -764,7 +779,7 @@ char *findfile(char *gname, char *uname, char *homedir, int filldef) etcpath = getetcpath(binpath); for(p = strtok(etcpath, ":"); p != NULL; p = strtok(NULL, ":")) { - if((path = sprintf2("%s/%s", p, gname)) != NULL) + if((path = sprintf2("%s/%s", p, name)) != NULL) { if(!access(path, mode)) { @@ -777,15 +792,61 @@ char *findfile(char *gname, char *uname, char *homedir, int filldef) free(etcpath); } } + if(filldef) { - if(uname && homedir) - return(sprintf2("%s/.%s", homedir, uname)); - return(sprintf2("/etc/%s", gname)); + if(homedir) + return(sprintf2("%s/.%s", homedir, name)); + return(sprintf2("/etc/%s", name)); } else { return(NULL); } } +struct strpair *newstrpair(char *key, char *val, struct strpair **list) +{ + struct strpair *pair; + + pair = smalloc(sizeof(*pair)); + memset(pair, 0, sizeof(*pair)); + if(key != NULL) + pair->key = sstrdup(key); + if(val != NULL) + pair->val = sstrdup(val); + if(list != NULL) + { + pair->next = *list; + *list = pair; + } + return(pair); +} + +void freestrpair(struct strpair *pair, struct strpair **list) +{ + struct strpair *cur; + + for(cur = *list; cur != NULL; list = &(cur->next), cur = cur->next) + { + if(cur == pair) + { + *list = cur->next; + break; + } + } + free(pair->key); + free(pair->val); + free(pair); +} + +char *spfind(struct strpair *list, char *key) +{ + for(; list != NULL; list = list->next) + { + if(!strcmp(list->key, key)) + return(list->val); + } + return(NULL); +} + struct wcspair *newwcspair(wchar_t *key, wchar_t *val, struct wcspair **list) { struct wcspair *pair; @@ -796,10 +857,8 @@ struct wcspair *newwcspair(wchar_t *key, wchar_t *val, struct wcspair **list) pair->key = swcsdup(key); if(val != NULL) pair->val = swcsdup(val); - if(list == NULL) + if(list != NULL) { - pair->next = NULL; - } else { pair->next = *list; *list = pair; }