/*
* Dolda Connect - Modular multiuser Direct Connect-style client
- * Copyright (C) 2004 Fredrik Tolf (fredrik@dolda2000.com)
+ * Copyright (C) 2004 Fredrik Tolf <fredrik@dolda2000.com>
*
* 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
#include <stdarg.h>
#include <stdlib.h>
-#include <malloc.h>
-#include <assert.h>
#ifdef DAEMON
#include "log.h"
#endif
wchar_t *val;
};
+struct strpair {
+ struct strpair *next;
+ char *key;
+ char *val;
+};
/* "Safe" functions */
#ifdef DAEMON
-#define LOGOOM(size) flog(LOG_CRIT, "%s (%s:%i): out of memory (alloc %i)", __FUNCTION__, __FILE__, __LINE__, (size))
-#define smalloc(size) ({void *__result__; ((__result__ = malloc(size)) == NULL)?({LOGOOM(size); abort(); (void *)0;}):__result__;})
-#define srealloc(ptr, size) ({void *__result__; ((__result__ = realloc((ptr), (size))) == NULL)?({LOGOOM(size); abort(); (void *)0;}):__result__;})
-#define swcsdup(wcs) ((wchar_t *)wcscpy(smalloc(sizeof(wchar_t) * (wcslen(wcs) + 1)), (wcs)))
+#define LOGOOM(size) flog(LOG_CRIT, "%s (%s:%i): out of memory (alloc %zi)", __FUNCTION__, __FILE__, __LINE__, (size))
+#define smalloc(size) ({void *__result__; ((__result__ = malloc(size)) == NULL)?({LOGOOM((ssize_t)(size)); abort(); (void *)0;}):__result__;})
+#define srealloc(ptr, size) ({void *__result__; ((__result__ = realloc((ptr), (size))) == NULL)?({LOGOOM((ssize_t)(size)); abort(); (void *)0;}):__result__;})
+#define swcsdup(wcs) ({wchar_t *__eval__; __eval__ = (wcs); (wchar_t *)wcscpy(smalloc(sizeof(wchar_t) * (wcslen(__eval__) + 1)), __eval__);})
#define sstrdup(str) ((char *)strcpy(smalloc(strlen(str) + 1), (str)))
#else
#define LOGOOM(size)
int (*func)(args, void *data); \
void (*destroy)(void *data); \
void *data; \
- int running, free; \
} * name
#define GCBCHAIN(name, args...) \
char *vsprintf2(char *format, va_list al);
char *sprintf2(char *format, ...)
-#if defined(__GNUC__) && 0
+#if defined(__GNUC__)
__attribute__ ((format (printf, 1, 2)))
#endif
;
char *base32decode(char *data, size_t *datalen);
void _freeparr(void **arr);
int _parrlen(void **arr);
-char *findfile(char *gname, char *uname, char *homedir, int filldef);
+char *findfile(char *name, char *homedir, int filldef);
+struct strpair *newstrpair(char *key, char *val, struct strpair **list);
+void freestrpair(struct strpair *pair, struct strpair **list);
+char *spfind(struct strpair *list, char *key);
struct wcspair *newwcspair(wchar_t *key, wchar_t *val, struct wcspair **list);
void freewcspair(struct wcspair *pair, struct wcspair **list);
wchar_t *wpfind(struct wcspair *list, wchar_t *key);
memcpy((d) + (d ## data), (s), sizeof(*(d)) * __bufcat_size__); \
(d ## data) += __bufcat_size__; \
} while (0)
+#define bprintf(b, fmt...) \
+ do { \
+ char *__bprintf_dest__; \
+ __bprintf_dest__ = sprintf2(fmt); \
+ bufcat(b, __bprintf_dest__, strlen(__bprintf_dest__)); \
+ free(__bprintf_dest__); \
+ } while(0)
#define freeparr(parr) _freeparr((void **)(parr))
#define parrlen(parr) _parrlen((void **)(parr))
do { \
struct cbchain_ ## name *__new_cb__; \
__new_cb__ = smalloc(sizeof(*__new_cb__)); \
- __new_cb__->running = __new_cb__->free = 0; \
__new_cb__->func = funca; \
__new_cb__->destroy = destroya; \
__new_cb__->data = dataa; \
(obj)->name = __new_cb__; \
} while(0)
-#define CBUNREG(obj, name, funca, dataa) \
-({ \
+#define CBUNREG(obj, name, dataa) \
+do { \
struct cbchain_ ## name *__cur__; \
- int __found__ = 0; \
for(__cur__ = (obj)->name; __cur__ != NULL; __cur__ = __cur__->next) { \
- if(((void *)(__cur__->func) == (void *)(funca)) && (__cur__->data == (void *)(dataa))) { \
+ if(__cur__->data == (dataa)) { \
if(__cur__->destroy != NULL) \
__cur__->destroy(__cur__->data); \
if(__cur__->prev != NULL) \
if(__cur__ == (obj)->name) \
(obj)->name = __cur__->next; \
free(__cur__); \
- __found__ = 1; \
break; \
} \
} \
-__found__;})
+} while(0)
#define GCBREG(name, funca, dataa) \
do { \
struct cbchain_ ## name *__cur__; \
while((__cur__ = (obj)->name) != NULL) { \
(obj)->name = __cur__->next; \
- if(__cur__->running) { \
- __cur__->free = 1; \
- } else { \
- if(__cur__->destroy != NULL) \
- __cur__->destroy(__cur__->data); \
- free(__cur__); \
- } \
+ if(__cur__->destroy != NULL) \
+ __cur__->destroy(__cur__->data); \
+ free(__cur__); \
} \
} while(0)
#define CBCHAINDOCB(obj, name, args...) \
do { \
struct cbchain_ ## name *__cur__, *__next__; \
- int __res__; \
for(__cur__ = (obj)->name; __cur__ != NULL; __cur__ = __next__) { \
__next__ = __cur__->next; \
- __cur__->running = 1; \
- __res__ = __cur__->func(args, __cur__->data); \
- __cur__->running = 0; \
- if(__cur__->free) { \
- free(__cur__); \
- break; \
- } \
- if(__res__) { \
+ if(__cur__->func(args, __cur__->data)) { \
if(__cur__->next != NULL) \
__cur__->next->prev = __cur__->prev; \
if(__cur__->prev != NULL) \