Difference between revisions of "Peerd.c"
(#include <regex.h>) |
(oops, crashes if no args supplied) |
||
Line 1: | Line 1: | ||
// [[[[http://www.organicdesign.co.nz/peerd|peerd]]]] - nodal p2p wiki daemon | // [[[[http://www.organicdesign.co.nz/peerd|peerd]]]] - nodal p2p wiki daemon | ||
− | + | // This article and all its includes are licenced under LGPL | |
− | // This article and all its includes are licenced under [[[[http://www.gnu.org/copyleft/lesser.html | + | // GPL: [[[[http://www.gnu.org/copyleft/lesser.html]]]] |
− | // SRC: [[[[http://www.organicdesign.co.nz/ | + | // SRC: [[[[http://www.organicdesign.co.nz/util.c]]]] |
− | // | + | // included in [[[[http://www.organicdesign.co.nz/category:peerd/files/C|peerd]]]][[[[http://www.organicdesign.co.nz/peerd.c|/peerd.c]]]] |
− | |||
− | // | ||
− | |||
− | // | ||
− | |||
− | |||
− | + | // Output a log entry with timestamp | |
− | + | // - Message can contain format like printf but only %s and %d | |
− | + | // - todo: Should use [[[[io.c]]]] to send multiplexly | |
− | + | char *laMsg = NULL; | |
− | + | void logAdd(char *format, ... ) { | |
− | + | if (laMsg == NULL) laMsg = malloc(1000); | |
− | + | char *msg = laMsg; | |
− | + | va_list args; | |
− | + | va_start(args,format); | |
− | + | time_t now = time(NULL); | |
+ | char *nowtext = ctime(&now); | ||
+ | if (nowtext) while (*msg++ = *nowtext++); | ||
+ | *(msg-2) = ':'; | ||
+ | *(msg-1) = ' '; | ||
+ | while (*format) { | ||
+ | if (strncmp(format,"%d",2)==0) { | ||
+ | msg += sprintf(msg,"%d",va_arg(args,int)); | ||
+ | format += 2; | ||
+ | } | ||
+ | else if (strncmp(format,"%s",2)==0) { | ||
+ | char *arg = va_arg(args,char*); | ||
+ | while (*arg) *msg++ = *arg++; | ||
+ | format += 2; | ||
+ | } | ||
+ | else *msg++ = *format++; | ||
+ | } | ||
+ | va_end(args); | ||
+ | *msg++ = '\n'; | ||
+ | *msg++ = '\0'; | ||
+ | printf(laMsg); | ||
+ | } | ||
− | |||
− | |||
− | |||
− | |||
− | // | + | // Return an array of strings resulting from splitting passed text at passed character |
− | + | // - the array is terminated by a NULL pointer | |
− | + | char **split(char c,char *text) { | |
− | + | int len = strlen(text), items = 0, size = 10; | |
− | + | char **list = malloc(size); | |
+ | char *i = malloc(len+1), *j = i, *k = i, *item = i; | ||
+ | while(*j++ = *text++); | ||
+ | while(i <= k+len) { | ||
+ | if (*i == c) *i = '\0'; | ||
+ | if ((*i++ == '\0')&&strlen(item)) { | ||
+ | if (items>size-2) realloc(list,size+=10); | ||
+ | list[items++] = item; | ||
+ | list[items] = NULL; | ||
+ | item = i; | ||
+ | } | ||
+ | } | ||
+ | return list; | ||
+ | } | ||
− | // | + | // Replaces missing itoa() and is specialised for binary return a string of \1 and \2 characters |
− | + | char *itob(int value, char *buf) { | |
− | + | int i; | |
− | + | char *j = buf; | |
− | + | for (i=1; i<=value>>1; i<<=1) *j++ = value&i ? '\1' : '\2'; | |
− | + | *j = '\0'; | |
− | + | return buf; | |
− | + | } | |
− | // | + | // ----------------------------------------------------------------------------------------- // |
− | + | // Global Pointer List | |
− | + | // - use insertPointer() and removePointer() to access the dynamically allocating pointer-array | |
− | + | // - internally uses freePush() and freePop() to maintain a linked-list of free array slots | |
− | + | int psize = 100, pitem = 0; | |
− | + | void **plist = NULL; | |
− | + | typedef struct fi { | |
− | + | int index; | |
− | + | struct fi *next; | |
− | + | } fitem; | |
− | + | fitem *flist = NULL; | |
− | int | + | // add a new pointer to the list, try using slots from the free-list before extending array |
+ | int insertPointer(void *ptr) { | ||
+ | int index; | ||
+ | if (plist == NULL) plist = malloc(psize*sizeof(void*)); | ||
+ | if (flist) { | ||
+ | fitem *kill = flist; | ||
+ | flist = (fitem*)kill->next; | ||
+ | index = kill->index; | ||
+ | free(kill); | ||
+ | } | ||
+ | else if ((index = ++pitem) > psize) realloc(plist,psize += 100); | ||
+ | plist[index] = ptr; | ||
+ | return index; | ||
+ | } | ||
− | + | // push the index onto the free-list, returning the pointer at that index | |
− | + | void *removePointer(int index) { | |
+ | fitem *newfree = (fitem*)malloc(sizeof(fitem)); | ||
+ | newfree->next = flist ? flist : NULL; | ||
+ | flist = newfree; | ||
+ | return plist[newfree->index = index]; | ||
+ | } | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | // Store the command-line args in the listSpace hash, eg char *name = *hash("name") | |
− | + | void **hash(unsigned char*); | |
− | + | void args(int argc, char **argv) { | |
+ | if (argc>1) { | ||
+ | int l = strlen(argv[1]); | ||
+ | peer = strncpy(malloc(l+1),argv[1],l); | ||
+ | while(argc-->2) { | ||
+ | char **arg = split('=',argv[argc]); | ||
+ | *hash(*arg) = arg[1]?strncpy(malloc(l=strlen(arg[1])+1),arg[1],l):"1"; | ||
+ | free(arg); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | // Make a global peer name and port number | ||
+ | char *p = *hash("port"); | ||
+ | if (p) port = atoi(p); | ||
+ | |||
+ | #if __unix__ | ||
+ | // Set name as seen in ps list if ux | ||
+ | char *tmp = *argv; | ||
+ | for (l=40;l--;) *tmp++ = '\0'; | ||
+ | sprintf(*argv,"peerd: %s (http%d)",peer,port); | ||
+ | #endif | ||
} | } |
Revision as of 05:59, 21 August 2006
// [[[[1]]]] - nodal p2p wiki daemon // This article and all its includes are licenced under LGPL // GPL: [[[[2]]]] // SRC: [[[[3]]]] // included in [[[[4]]]][[[[5]]]]
// Output a log entry with timestamp
// - Message can contain format like printf but only %s and %d
// - todo: Should use [[io.c]] to send multiplexly
char *laMsg = NULL;
void logAdd(char *format, ... ) {
if (laMsg == NULL) laMsg = malloc(1000);
char *msg = laMsg;
va_list args;
va_start(args,format);
time_t now = time(NULL);
char *nowtext = ctime(&now);
if (nowtext) while (*msg++ = *nowtext++);
*(msg-2) = ':';
*(msg-1) = ' ';
while (*format) {
if (strncmp(format,"%d",2)==0) {
msg += sprintf(msg,"%d",va_arg(args,int));
format += 2;
}
else if (strncmp(format,"%s",2)==0) {
char *arg = va_arg(args,char*);
while (*arg) *msg++ = *arg++;
format += 2;
}
else *msg++ = *format++;
}
va_end(args);
*msg++ = '\n';
*msg++ = '\0';
printf(laMsg);
}
// Return an array of strings resulting from splitting passed text at passed character
// - the array is terminated by a NULL pointer
char **split(char c,char *text) {
int len = strlen(text), items = 0, size = 10;
char **list = malloc(size);
char *i = malloc(len+1), *j = i, *k = i, *item = i;
while(*j++ = *text++);
while(i <= k+len) {
if (*i == c) *i = '\0';
if ((*i++ == '\0')&&strlen(item)) {
if (items>size-2) realloc(list,size+=10);
list[items++] = item;
list[items] = NULL;
item = i;
}
}
return list;
}
// Replaces missing itoa() and is specialised for binary return a string of \1 and \2 characters char *itob(int value, char *buf) { int i; char *j = buf; for (i=1; i<=value>>1; i<<=1) *j++ = value&i ? '\1' : '\2'; *j = '\0'; return buf; }
// ----------------------------------------------------------------------------------------- // // Global Pointer List // - use insertPointer() and removePointer() to access the dynamically allocating pointer-array // - internally uses freePush() and freePop() to maintain a linked-list of free array slots int psize = 100, pitem = 0; void **plist = NULL; typedef struct fi { int index; struct fi *next; } fitem; fitem *flist = NULL;
// add a new pointer to the list, try using slots from the free-list before extending array int insertPointer(void *ptr) { int index; if (plist == NULL) plist = malloc(psize*sizeof(void*)); if (flist) { fitem *kill = flist; flist = (fitem*)kill->next; index = kill->index; free(kill); } else if ((index = ++pitem) > psize) realloc(plist,psize += 100); plist[index] = ptr; return index; }
// push the index onto the free-list, returning the pointer at that index void *removePointer(int index) { fitem *newfree = (fitem*)malloc(sizeof(fitem)); newfree->next = flist ? flist : NULL; flist = newfree; return plist[newfree->index = index]; }
// Store the command-line args in the listSpace hash, eg char *name = *hash("name")
void **hash(unsigned char*);
void args(int argc, char **argv) {
if (argc>1) { int l = strlen(argv[1]); peer = strncpy(malloc(l+1),argv[1],l); while(argc-->2) { char **arg = split('=',argv[argc]); *hash(*arg) = arg[1]?strncpy(malloc(l=strlen(arg[1])+1),arg[1],l):"1"; free(arg); } }
// Make a global peer name and port number char *p = *hash("port"); if (p) port = atoi(p);
#if __unix__ // Set name as seen in ps list if ux char *tmp = *argv; for (l=40;l--;) *tmp++ = '\0'; sprintf(*argv,"peerd: %s (http%d)",peer,port); #endif }