diff --git a/Android.mk b/Android.mk index 17c0e690..a0da3e9a 100644 --- a/Android.mk +++ b/Android.mk @@ -43,6 +43,8 @@ LOCAL_SRC_FILES:= \ serval-dna/commandline.c \ serval-dna/dataformats.c \ serval-dna/dna.c \ + serval-dna/log.c \ + serval-dna/mkdir.c \ serval-dna/gateway.c \ serval-dna/overlay.c \ serval-dna/overlay_broadcast.c \ diff --git a/Makefile.in b/Makefile.in index f5204b07..dc74e94e 100644 --- a/Makefile.in +++ b/Makefile.in @@ -4,6 +4,8 @@ SRCS= batman.c \ commandline.c \ dataformats.c \ dna.c \ + log.c \ + mkdir.c \ dna_identity.c \ encode.c \ fifo.c \ diff --git a/client.c b/client.c index 9771a45a..7e8bb575 100644 --- a/client.c +++ b/client.c @@ -19,6 +19,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "serval.h" +int sock = -1; + /* Now that we are using the keyring, we only support a small subset of variables. (VAR_NAME is not properly supported yet) */ diff --git a/commandline.c b/commandline.c index 309aaa35..ea2185b9 100644 --- a/commandline.c +++ b/commandline.c @@ -19,10 +19,12 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #define _GNU_SOURCE // For asprintf() #include -#include #include #include #include +#ifdef HAVE_STRINGS_H +#include +#endif #include #include #include @@ -263,7 +265,7 @@ int parseCommandLine(int argc, const char *const *args) } /* Otherwise, make call */ - setVerbosity(confValueGet("debug","")); + confSetDebugFlags(); int result=command_line_options[cli_call].function(argc, args, &command_line_options[cli_call]); /* clean up after ourselves */ overlay_mdp_client_done(); @@ -396,6 +398,8 @@ int app_echo(int argc, const char *const *argv, struct command_line_option *o) { int i; for (i = 1; i < argc; ++i) { + if (debug & DEBUG_VERBOSE) + DEBUGF("echo:argv[%d]=%s", i, argv[i]); cli_puts(argv[i]); cli_delim(NULL); } @@ -507,15 +511,15 @@ char *confValueGet(char *var,char *defaultValue) char filename[1024]; if (!FORM_SERVAL_INSTANCE_PATH(filename, "serval.conf")) { - WHYF("Using default value of %s: %s", var, defaultValue); + WARNF("Using default value of %s: %s", var, defaultValue); return defaultValue; } FILE *f = fopen(filename,"r"); if (!f) { - WHYF("Cannot open serval.conf, using default value of %s: %s", var, defaultValue); + WARNF("Cannot open serval.conf, using default value of %s: %s", var, defaultValue); return defaultValue; } - + char line[1024]; line[0]=0; fgets(line,1024,f); while(line[0]) { @@ -538,6 +542,64 @@ char *confValueGet(char *var,char *defaultValue) return defaultValue; } +void confSetDebugFlags() +{ + char filename[1024]; + if (FORM_SERVAL_INSTANCE_PATH(filename, "serval.conf")) { + FILE *f = fopen(filename, "r"); + if (!f) { + WARN("Cannot open serval.conf"); + } else { + long long setmask = 0; + long long clearmask = 0; + int setall = 0; + int clearall = 0; + char line[1024]; + line[0] = '\0'; + fgets(line, sizeof line, f); + while (line[0]) { + if (!strncasecmp(line, "debug.", 6)) { + char *flagname = line + 6; + char *p = flagname; + while (*p && *p != '=') + ++p; + int flag; + if (*p) { + char *q = p + 1; + while (*q && *q != '\n') + ++q; + *q = '\0'; + if ((flag = confParseBoolean(p + 1)) != -1) { + *p = '\0'; + long long mask = debugFlagMask(flagname); + if (mask == -1) + if (flag) setall = 1; else clearall = 1; + else + if (flag) setmask |= mask; else clearmask |= mask; + } + } + } + line[0] = '\0'; + fgets(line, sizeof line, f); + } + fclose(f); + if (setall) debug = -1; else if (clearall) debug = 0; + debug &= ~clearmask; + debug |= setmask; + } + } +} + +int confParseBoolean(const char *text) +{ + if (!strcasecmp(text, "on") || !strcasecmp(text, "yes") || !strcasecmp(text, "true") || !strcmp(text, "1")) + return 1; + if (!strcasecmp(text, "off") || !strcasecmp(text, "no") || !strcasecmp(text, "false") || !strcmp(text, "0")) + return 0; + WARNF("Invalid boolean value '%s'", text); + return -1; +} + int cli_absolute_path(const char *arg) { return arg[0] == '/' && arg[1] != '\0'; @@ -906,11 +968,13 @@ int cli_configvarname(const char *arg) { if (arg[0] == '\0') return 0; - const char *s; - for (s = arg; *s; ++s) - if (!(isalnum(*s) || *s == '_')) + if (!(isalnum(arg[0]) || arg[0] == '_')) + return 0; + const char *s = arg + 1; + for (; *s; ++s) + if (!(isalnum(*s) || *s == '_' || (*s == '.' && s[-1] != '.'))) return 0; - return 1; + return s[-1] != '.'; } int app_config_set(int argc, const char *const *argv, struct command_line_option *o) diff --git a/dataformats.c b/dataformats.c index 26bdca4f..d5602856 100644 --- a/dataformats.c +++ b/dataformats.c @@ -19,6 +19,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "serval.h" +int hexdigit[16]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; + int extractDid(unsigned char *packet,int *ofs,char *did) { int d=0; @@ -134,6 +136,14 @@ int stowSid(unsigned char *packet, int ofs, const char *sid) return 0; } +int hexvalue(unsigned char c) +{ + if (c>='0'&&c<='9') return c-'0'; + if (c>='A'&&c<='F') return c-'A'+10; + if (c>='a'&&c<='f') return c-'a'+10; + return setReason("Invalid hex digit in SID"); +} + int packetGetID(unsigned char *packet,int len,char *did,char *sid) { int ofs=HEADERFIELDS_LEN; diff --git a/dna.c b/dna.c index 11971cff..ece7dad8 100644 --- a/dna.c +++ b/dna.c @@ -21,126 +21,15 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "rhizome.h" #include #include -#include -#include char *gatewayspec=NULL; - char *outputtemplate=NULL; char *instrumentation_file=NULL; -char *importFile=NULL; -int debug=0; int timeout=3000; /* 3000ms request timeout */ -int serverMode=0; -int clientMode=0; - int returnMultiVars=0; -int hexdigit[16]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; - -int sock=-1; - -#ifndef HAVE_BZERO -/* OpenWRT doesn't have bzero */ -void bzero(void *m,size_t len) -{ - unsigned char *c=m; - int i; - for(i=0;i=' '&&addr[i+j]<0x7f?addr[i+j]:'.'); - fprintf(stderr,"\n"); - } - return 0; -} - -int dumpResponses(struct response_set *responses) -{ - struct response *r; - if (!responses) {fprintf(stderr,"Response set is NULL\n"); return 0; } - fprintf(stderr,"Response set claims to contain %d entries.\n",responses->response_count); - r=responses->responses; - while(r) - { - fprintf(stderr," response code 0x%02x\n",r->code); - if (r->next) - if (r->next->prev!=r) fprintf(stderr," !! response chain is broken\n"); - r=r->next; - } - return 0; -} - -#ifdef ANDROID -#include -#endif - -void logMessage(int level, char *fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - vlogMessage(level, fmt, ap); -} - -void vlogMessage(int level, char *fmt, va_list ap) -{ - va_list ap2; - char buf[8192]; - va_copy(ap2, ap); - vsnprintf(buf, sizeof buf, fmt, ap2); - va_end(ap); - buf[sizeof buf - 1] = '\0'; -#ifdef ANDROID - int alevel = ANDROID_LOG_UNKNOWN; - switch (level) { - case LOG_LEVEL_FATAL: alevel = ANDROID_LOG_FATAL; break; - case LOG_LEVEL_ERROR: alevel = ANDROID_LOG_ERROR; break; - case LOG_LEVEL_INFO: alevel = ANDROID_LOG_INFO; break; - case LOG_LEVEL_WARN: alevel = ANDROID_LOG_WARN; break; - case LOG_LEVEL_DEBUG: alevel = ANDROID_LOG_DEBUG; break; - } - __android_log_print(alevel, "servald", "%s", buf); -#endif - const char *levelstr = "UNKNOWN"; - switch (level) { - case LOG_LEVEL_FATAL: levelstr = "FATAL"; break; - case LOG_LEVEL_ERROR: levelstr = "ERROR"; break; - case LOG_LEVEL_INFO: levelstr = "INFO"; break; - case LOG_LEVEL_WARN: levelstr = "WARN"; break; - case LOG_LEVEL_DEBUG: levelstr = "DEBUG"; break; - } - fprintf(stderr, "%s: %s\n", levelstr, buf); -} - -int setReason(char *fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - vlogMessage(LOG_LEVEL_ERROR, fmt, ap); - return -1; -} - -int hexvalue(unsigned char c) -{ - if (c>='0'&&c<='9') return c-'0'; - if (c>='A'&&c<='F') return c-'A'+10; - if (c>='a'&&c<='f') return c-'a'+10; - return setReason("Invalid hex digit in SID"); -} - int parseAssignment(unsigned char *text,int *var_id,unsigned char *value,int *value_len) { /* Parse an assignment. @@ -291,98 +180,7 @@ int form_serval_instance_path(char *buf, size_t bufsiz, const char *path) } int create_serval_instance_dir() { - const char *instancepath = serval_instancepath(); - if (mkdir(instancepath, 0700) == -1) { - if (errno == EEXIST) { - DIR *d = opendir(instancepath); - if (!d) { - WHYF("Cannot access %s", instancepath); - return WHY_perror("opendir"); - } - closedir(d); - return 0; - } - WHYF("Cannot mkdir %s", instancepath); - return WHY_perror("mkdir"); - } - return 0; -} - -int mkdirs(const char *path) -{ - return mkdirsn(path, strlen(path)); -} - -int mkdirsn(const char *path, size_t len) -{ - if (len == 0) - return WHY("Bug: empty path"); - char *pathfrag = alloca(len + 1); - strncpy(pathfrag, path, len); - pathfrag[len] = '\0'; - if (mkdir(pathfrag, 0700) != -1) - return 0; - if (errno == EEXIST) { - DIR *d = opendir(pathfrag); - if (!d) { - WHY_perror("opendir"); - return WHYF("cannot access %s", pathfrag); - } - closedir(d); - return 0; - } - if (errno == ENOENT) { - const char *lastsep = path + len - 1; - while (lastsep != path && *--lastsep != '/') - ; - while (lastsep != path && *--lastsep == '/') - ; - if (lastsep != path) { - if (mkdirsn(path, lastsep - path + 1) == -1) - return -1; - if (mkdir(pathfrag, 0700) != -1) - return 0; - } - } - WHY_perror("mkdir"); - return WHYF("cannot mkdir %s", pathfrag); -} - -int setVerbosity(const char *optarg) { - long long old_debug=debug; - debug=strtoll(optarg,NULL,10); - if (strstr(optarg,"interfaces")) debug|=DEBUG_OVERLAYINTERFACES; - if (strstr(optarg,"rx")) debug|=DEBUG_PACKETRX; - if (strstr(optarg,"tx")) debug|=DEBUG_PACKETTX; - if (strstr(optarg,"verbose")) debug|=DEBUG_VERBOSE; - if (strstr(optarg,"verbio")) debug|=DEBUG_VERBOSE_IO; - if (strstr(optarg,"peers")) debug|=DEBUG_PEERS; - if (strstr(optarg,"dnaresponses")) debug|=DEBUG_DNARESPONSES; - if (strstr(optarg,"dnarequests")) debug|=DEBUG_DNAREQUESTS; - if (strstr(optarg,"simulation")) debug|=DEBUG_SIMULATION; - if (strstr(optarg,"dnavars")) debug|=DEBUG_DNAVARS; - if (strstr(optarg,"packetformats")) debug|=DEBUG_PACKETFORMATS; - if (strstr(optarg,"packetconstruction")) debug|=DEBUG_PACKETCONSTRUCTION; - if (strstr(optarg,"gateway")) debug|=DEBUG_GATEWAY; - if (strstr(optarg,"hlr")) debug|=DEBUG_HLR; - if (strstr(optarg,"sockio")) debug|=DEBUG_IO; - if (strstr(optarg,"frames")) debug|=DEBUG_OVERLAYFRAMES; - if (strstr(optarg,"abbreviations")) debug|=DEBUG_OVERLAYABBREVIATIONS; - if (strstr(optarg,"routing")) debug|=DEBUG_OVERLAYROUTING; - if (strstr(optarg,"security")) debug|=DEBUG_SECURITY; - if (strstr(optarg,"rhizome")) debug|=DEBUG_RHIZOME; - if (strstr(optarg,"norhizome")) - { debug|=DEBUG_DISABLERHIZOME; debug&=~DEBUG_RHIZOME; } - if (strstr(optarg,"filesync")) debug|=DEBUG_RHIZOMESYNC; - if (strstr(optarg,"monitorroutes")) debug|=DEBUG_OVERLAYROUTEMONITOR; - if (strstr(optarg,"queues")) debug|=DEBUG_QUEUES; - if (strstr(optarg,"broadcasts")) debug|=DEBUG_BROADCASTS; - - if (old_debug==debug && optarg[0]) { - fprintf(stderr,"WARNING: Option '%s' had no effect on existing debug/verbosity level.\n", - optarg); - } - return 0; + return mkdirs(serval_instancepath(), 0700); } int main(int argc, char **argv) @@ -394,6 +192,7 @@ int main(int argc, char **argv) char *keyring_file=NULL; int instance=-1; int foregroundMode=0; + int clientMode=0; #if defined WIN32 WSADATA wsa_data; @@ -405,19 +204,15 @@ int main(int argc, char **argv) server_save_argv(argc, (const char*const*)argv); - if (argv[1]&&argv[1][0]!='-') { - /* First argument doesn't start with a dash, so assume it is for the new command line - parser. */ - + /* If first argument starts with a dash, we assume it is for the old command line parser. */ + if (!argv[1] || argv[1][0] != '-') { /* Don't include name of program in arguments */ int return_value = parseCommandLine(argc - 1, (const char*const*)&argv[1]); - #if defined WIN32 WSACleanup(); #endif - return return_value; - } + } fprintf(stderr, "WARNING: The use of the old command line structure is being deprecated.\n" @@ -507,7 +302,7 @@ int main(int argc, char **argv) timeout=atoi(optarg); break; case 'v': /* set verbosity */ - setVerbosity(optarg); + debug |= debugFlagMask(optarg); break; case 'A': /* get address (IP or otherwise) of a given peer */ peerAddress(did,sid,3 /* 1 = print list of addresses to stdout, 2 = set peer list to responders */); @@ -571,35 +366,3 @@ int main(int argc, char **argv) return 0; } #endif - -long long parse_quantity(char *q) -{ - int m; - char units[80]; - - if (strlen(q)>=80) return WHY("quantity string >=80 characters"); - - if (sscanf(q,"%d%s",&m,units)==2) - { - if (units[1]) return WHY("Units should be single character"); - switch(units[0]) - { - case 'k': return m*1000LL; - case 'K': return m*1024LL; - case 'm': return m*1000LL*1000LL; - case 'M': return m*1024LL*1024LL; - case 'g': return m*1000LL*1000LL*1000LL; - case 'G': return m*1024LL*1024LL*1024LL; - default: - return WHY("Illegal unit: should be k,K,m,M,g, or G."); - } - } - if (sscanf(q,"%d",&m)==1) - { - return m; - } - else - { - return WHY("Could not parse quantity"); - } -} diff --git a/log.c b/log.c new file mode 100644 index 00000000..e9d295fc --- /dev/null +++ b/log.c @@ -0,0 +1,135 @@ +/* +Serval Distributed Numbering Architecture (DNA) +Copyright (C) 2010 Paul Gardner-Stephen + +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 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include "serval.h" + +int debug = 0; + +#ifdef ANDROID +#include +#endif + +void logMessage(int level, char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + vlogMessage(level, fmt, ap); +} + +void vlogMessage(int level, char *fmt, va_list ap) +{ + va_list ap2; + char buf[8192]; + va_copy(ap2, ap); + vsnprintf(buf, sizeof buf, fmt, ap2); + va_end(ap); + buf[sizeof buf - 1] = '\0'; +#ifdef ANDROID + int alevel = ANDROID_LOG_UNKNOWN; + switch (level) { + case LOG_LEVEL_FATAL: alevel = ANDROID_LOG_FATAL; break; + case LOG_LEVEL_ERROR: alevel = ANDROID_LOG_ERROR; break; + case LOG_LEVEL_INFO: alevel = ANDROID_LOG_INFO; break; + case LOG_LEVEL_WARN: alevel = ANDROID_LOG_WARN; break; + case LOG_LEVEL_DEBUG: alevel = ANDROID_LOG_DEBUG; break; + } + __android_log_print(alevel, "servald", "%s", buf); +#endif + const char *levelstr = "UNKNOWN"; + switch (level) { + case LOG_LEVEL_FATAL: levelstr = "FATAL"; break; + case LOG_LEVEL_ERROR: levelstr = "ERROR"; break; + case LOG_LEVEL_INFO: levelstr = "INFO"; break; + case LOG_LEVEL_WARN: levelstr = "WARN"; break; + case LOG_LEVEL_DEBUG: levelstr = "DEBUG"; break; + } + fprintf(stderr, "%s: %s\n", levelstr, buf); +} + +int setReason(char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + vlogMessage(LOG_LEVEL_ERROR, fmt, ap); + return -1; +} + +int dump(char *name,unsigned char *addr,int len) +{ + int i,j; + fprintf(stderr,"Dump of %s\n",name); + for(i=0;i=' '&&addr[i+j]<0x7f?addr[i+j]:'.'); + fprintf(stderr,"\n"); + } + return 0; +} + +int dumpResponses(struct response_set *responses) +{ + struct response *r; + if (!responses) {fprintf(stderr,"Response set is NULL\n"); return 0; } + fprintf(stderr,"Response set claims to contain %d entries.\n",responses->response_count); + r=responses->responses; + while(r) + { + fprintf(stderr," response code 0x%02x\n",r->code); + if (r->next) + if (r->next->prev!=r) fprintf(stderr," !! response chain is broken\n"); + r=r->next; + } + return 0; +} + +long long debugFlagMask(const char *flagname) { + if (!strcasecmp(flagname,"all")) return -1; + else if (!strcasecmp(flagname,"interfaces")) return DEBUG_OVERLAYINTERFACES; + else if (!strcasecmp(flagname,"rx")) return DEBUG_PACKETRX; + else if (!strcasecmp(flagname,"tx")) return DEBUG_PACKETTX; + else if (!strcasecmp(flagname,"verbose")) return DEBUG_VERBOSE; + else if (!strcasecmp(flagname,"verbio")) return DEBUG_VERBOSE_IO; + else if (!strcasecmp(flagname,"peers")) return DEBUG_PEERS; + else if (!strcasecmp(flagname,"dnaresponses")) return DEBUG_DNARESPONSES; + else if (!strcasecmp(flagname,"dnarequests")) return DEBUG_DNAREQUESTS; + else if (!strcasecmp(flagname,"simulation")) return DEBUG_SIMULATION; + else if (!strcasecmp(flagname,"dnavars")) return DEBUG_DNAVARS; + else if (!strcasecmp(flagname,"packetformats")) return DEBUG_PACKETFORMATS; + else if (!strcasecmp(flagname,"packetconstruction")) return DEBUG_PACKETCONSTRUCTION; + else if (!strcasecmp(flagname,"gateway")) return DEBUG_GATEWAY; + else if (!strcasecmp(flagname,"hlr")) return DEBUG_HLR; + else if (!strcasecmp(flagname,"sockio")) return DEBUG_IO; + else if (!strcasecmp(flagname,"frames")) return DEBUG_OVERLAYFRAMES; + else if (!strcasecmp(flagname,"abbreviations")) return DEBUG_OVERLAYABBREVIATIONS; + else if (!strcasecmp(flagname,"routing")) return DEBUG_OVERLAYROUTING; + else if (!strcasecmp(flagname,"security")) return DEBUG_SECURITY; + else if (!strcasecmp(flagname,"rhizome")) return DEBUG_RHIZOME; + else if (!strcasecmp(flagname,"norhizome")) return DEBUG_DISABLERHIZOME; + else if (!strcasecmp(flagname,"filesync")) return DEBUG_RHIZOMESYNC; + else if (!strcasecmp(flagname,"monitorroutes")) return DEBUG_OVERLAYROUTEMONITOR; + else if (!strcasecmp(flagname,"queues")) return DEBUG_QUEUES; + else if (!strcasecmp(flagname,"broadcasts")) return DEBUG_BROADCASTS; + WARNF("Unsupported debug flag '%s'", flagname); + return 0; +} + diff --git a/mkdir.c b/mkdir.c new file mode 100644 index 00000000..64cea36f --- /dev/null +++ b/mkdir.c @@ -0,0 +1,64 @@ +/* +Serval Distributed Numbering Architecture (DNA) +Copyright (C) 2010 Paul Gardner-Stephen + +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 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include +#include +#include +#include "serval.h" + +int mkdirs(const char *path, mode_t mode) +{ + return mkdirsn(path, strlen(path), mode); +} + +int mkdirsn(const char *path, size_t len, mode_t mode) +{ + if (len == 0) + return WHY("Bug: empty path"); + char *pathfrag = alloca(len + 1); + strncpy(pathfrag, path, len); + pathfrag[len] = '\0'; + if (mkdir(pathfrag, mode) != -1) + return 0; + if (errno == EEXIST) { + DIR *d = opendir(pathfrag); + if (!d) { + WHY_perror("opendir"); + return WHYF("cannot access %s", pathfrag); + } + closedir(d); + return 0; + } + if (errno == ENOENT) { + const char *lastsep = path + len - 1; + while (lastsep != path && *--lastsep != '/') + ; + while (lastsep != path && *--lastsep == '/') + ; + if (lastsep != path) { + if (mkdirsn(path, lastsep - path + 1, mode) == -1) + return -1; + if (mkdir(pathfrag, mode) != -1) + return 0; + } + } + WHY_perror("mkdir"); + return WHYF("cannot mkdir %s", pathfrag); +} + diff --git a/overlay_interface.c b/overlay_interface.c index ae485304..a43499a8 100644 --- a/overlay_interface.c +++ b/overlay_interface.c @@ -975,3 +975,35 @@ long long overlay_time_until_next_tick() return nexttick; } + +long long parse_quantity(char *q) +{ + int m; + char units[80]; + + if (strlen(q)>=80) return WHY("quantity string >=80 characters"); + + if (sscanf(q,"%d%s",&m,units)==2) + { + if (units[1]) return WHY("Units should be single character"); + switch(units[0]) + { + case 'k': return m*1000LL; + case 'K': return m*1024LL; + case 'm': return m*1000LL*1000LL; + case 'M': return m*1024LL*1024LL; + case 'g': return m*1000LL*1000LL*1000LL; + case 'G': return m*1024LL*1024LL*1024LL; + default: + return WHY("Illegal unit: should be k,K,m,M,g, or G."); + } + } + if (sscanf(q,"%d",&m)==1) + { + return m; + } + else + { + return WHY("Could not parse quantity"); + } +} diff --git a/rhizome_database.c b/rhizome_database.c index b46434fd..ce633047 100644 --- a/rhizome_database.c +++ b/rhizome_database.c @@ -56,7 +56,7 @@ int create_rhizome_datastore_dir() WHY("Cannot create rhizome database -- no path specified"); return 0; } - return mkdirs(rhizome_datastore_path); + return mkdirs(rhizome_datastore_path, 0700); } sqlite3 *rhizome_db=NULL; diff --git a/serval.h b/serval.h index 993c7134..14741fd0 100755 --- a/serval.h +++ b/serval.h @@ -28,6 +28,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #endif #include #include +#include #ifdef WIN32 #include "win32/win32.h" @@ -106,6 +107,9 @@ struct in_addr { #define DEFAULT_INSTANCE_PATH "/var/serval-node" #endif +/* bzero(3) is deprecated in favour of memset(3). */ +#define bzero(addr,len) memset((addr), 0, (len)) + /* UDP Port numbers for various Serval services. The overlay mesh works over DNA */ #define PORT_DNA 4110 @@ -384,6 +388,8 @@ extern int hexdigit[16]; extern int sock; char *confValueGet(char *var,char *defaultValue); +void confSetDebugFlags(); +int confParseBoolean(const const char *text); int recvwithttl(int sock,unsigned char *buffer,int bufferlen,int *ttl, struct sockaddr *recvaddr,unsigned int *recvaddrlen); int validateSid(const char *sid); @@ -410,9 +416,7 @@ void serverCleanUp(); int isTransactionInCache(unsigned char *transaction_id); void insertTransactionInCache(unsigned char *transaction_id); -int setReason(char *fmt, ...); int hexvalue(unsigned char c); -int dump(char *name,unsigned char *addr,int len); int packetOk(int interface,unsigned char *packet,int len, unsigned char *transaction_id, int recvttl, struct sockaddr *recvaddr,int recvaddrlen,int parseP); @@ -749,19 +753,25 @@ extern overlay_txqueue overlay_tx[OQ_MAX]; int setReason(char *fmt, ...); void logMessage(int level, char *fmt, ...); void vlogMessage(int level, char *fmt, va_list); +long long debugFlagMask(const char *flagname); +int dump(char *name,unsigned char *addr,int len); #define FATALF(F,...) do { logMessage(LOG_LEVEL_FATAL, "%s:%d:%s() " F, __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__); exit(-1); } while(1) #define FATAL(X) FATALF("%s", (X)) #define FATAL_perror(X) FATALF("%s: %s [errno=%d]", (X), strerror(errno), errno) -#define WHY(X) setReason("%s:%d:%s() %s",__FILE__,__LINE__,__FUNCTION__,X) -#define WHYNULL(X) (setReason("%s:%d:%s() %s",__FILE__,__LINE__,__FUNCTION__,X), NULL) -#define WHYF(F,...) setReason("%s:%d:%s() " F, __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__) -#define WHY_perror(X) setReason("%s:%d:%s() %s: %s [errno=%d]", __FILE__, __LINE__, __FUNCTION__, X, strerror(errno), errno) +#define WHY(X) setReason("%s:%d:%s() %s",__FILE__,__LINE__,__FUNCTION__,X) +#define WHYNULL(X) (setReason("%s:%d:%s() %s",__FILE__,__LINE__,__FUNCTION__,X), NULL) +#define WHYF(F,...) setReason("%s:%d:%s() " F, __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__) +#define WHY_perror(X) setReason("%s:%d:%s() %s: %s [errno=%d]", __FILE__, __LINE__, __FUNCTION__, X, strerror(errno), errno) -#define DEBUGF(F,...) logMessage(LOG_LEVEL_DEBUG, "%s:%d:%s() " F, __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__) -#define DEBUG(X) DEBUGF("%s", (X)) -#define DEBUG_perror(X) DEBUGF("%s: %s [errno=%d]", (X), strerror(errno), errno) +#define WARNF(F,...) logMessage(LOG_LEVEL_WARN, "%s:%d:%s() " F, __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__) +#define WARN(X) WARNF("%s", (X)) +#define WARN_perror(X) WARNF("%s: %s [errno=%d]", (X), strerror(errno), errno) + +#define DEBUGF(F,...) logMessage(LOG_LEVEL_DEBUG, "%s:%d:%s() " F, __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__) +#define DEBUG(X) DEBUGF("%s", (X)) +#define DEBUG_perror(X) DEBUGF("%s: %s [errno=%d]", (X), strerror(errno), errno) #define D DEBUG("D") overlay_buffer *ob_new(int size); @@ -1023,32 +1033,31 @@ int overlay_saw_mdp_containing_frame(int interface,overlay_frame *f,long long no #include "nacl.h" - -#define DEBUG_OVERLAYINTERFACES 2 -#define DEBUG_PACKETRX 1 -#define DEBUG_VERBOSE 4 -#define DEBUG_VERBOSE_IO 8 -#define DEBUG_PEERS 16 -#define DEBUG_DNARESPONSES 32 -#define DEBUG_DNAREQUESTS 64 -#define DEBUG_SIMULATION 128 -#define DEBUG_DNAVARS 256 -#define DEBUG_PACKETFORMATS 512 -#define DEBUG_GATEWAY 1024 -#define DEBUG_HLR 2048 -#define DEBUG_IO 4096 -#define DEBUG_OVERLAYFRAMES 8192 -#define DEBUG_OVERLAYABBREVIATIONS 16384 -#define DEBUG_OVERLAYROUTING 32768 -#define DEBUG_SECURITY 65536 -#define DEBUG_RHIZOME (1<<17) -#define DEBUG_OVERLAYROUTEMONITOR (1<<18) -#define DEBUG_QUEUES (1<<19) -#define DEBUG_BROADCASTS (1<<20) -#define DEBUG_RHIZOMESYNC (1<<21) -#define DEBUG_DISABLERHIZOME (1<<22) -#define DEBUG_PACKETTX (1<<23) -#define DEBUG_PACKETCONSTRUCTION (1<<24) +#define DEBUG_PACKETRX (1 << 0) +#define DEBUG_OVERLAYINTERFACES (1 << 1) +#define DEBUG_VERBOSE (1 << 2) +#define DEBUG_VERBOSE_IO (1 << 3) +#define DEBUG_PEERS (1 << 4) +#define DEBUG_DNARESPONSES (1 << 5) +#define DEBUG_DNAREQUESTS (1 << 6) +#define DEBUG_SIMULATION (1 << 7) +#define DEBUG_DNAVARS (1 << 8) +#define DEBUG_PACKETFORMATS (1 << 9) +#define DEBUG_GATEWAY (1 << 10) +#define DEBUG_HLR (1 << 11) +#define DEBUG_IO (1 << 12) +#define DEBUG_OVERLAYFRAMES (1 << 13) +#define DEBUG_OVERLAYABBREVIATIONS (1 << 14) +#define DEBUG_OVERLAYROUTING (1 << 15) +#define DEBUG_SECURITY (1 << 16) +#define DEBUG_RHIZOME (1 << 17) +#define DEBUG_OVERLAYROUTEMONITOR (1 << 18) +#define DEBUG_QUEUES (1 << 19) +#define DEBUG_BROADCASTS (1 << 20) +#define DEBUG_RHIZOMESYNC (1 << 21) +#define DEBUG_DISABLERHIZOME (1 << 22) +#define DEBUG_PACKETTX (1 << 23) +#define DEBUG_PACKETCONSTRUCTION (1 << 24) int serval_packetvisualise(FILE *f,char *message,unsigned char *packet,int plen); @@ -1109,8 +1118,8 @@ const char *serval_instancepath(); int form_serval_instance_path(char * buf, size_t bufsiz, const char *path); int create_serval_instance_dir(); -int mkdirs(const char *path); -int mkdirsn(const char *path, size_t len); +int mkdirs(const char *path, mode_t mode); +int mkdirsn(const char *path, size_t len, mode_t mode); /* Handy statement for forming a path to an instance file in a char buffer whose declaration * is in scope (so that sizeof(buf) will work). Evaluates to true if the pathname fitted into @@ -1265,8 +1274,6 @@ typedef struct overlay_mdp_frame { int keyring_mapping_request(keyring_file *k,overlay_mdp_frame *req); -int setVerbosity(const char *optarg); - /* Client-side MDP function */ extern int mdp_client_socket; int overlay_mdp_client_init(); diff --git a/server.c b/server.c index 358ae750..659a9e94 100644 --- a/server.c +++ b/server.c @@ -31,6 +31,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. char *exec_args[128]; int exec_argc = 0; +int serverMode=0; int servalShutdown = 0; static int server_getpid = 0; @@ -157,6 +158,8 @@ void server_save_argv(int argc, const char *const *argv) int server(char *backing_file) { + serverMode = 1; + /* Catch sigsegv and other crash signals so that we can relaunch ourselves */ signal(SIGSEGV, signal_handler); signal(SIGFPE, signal_handler); diff --git a/tests/dna_config b/tests/dna_config index d5b8f78f..558ca026 100755 --- a/tests/dna_config +++ b/tests/dna_config @@ -115,4 +115,34 @@ test_CaseInsensitive() { assertStdoutGrep --stdout --stderr --matches=1 '^FOO=wah$' } +doc_DotsInNames="Config item names can have internal dots" +test_DotsInNames() { + executeOk $dna config set foo.bar yes + executeOk $dna config get foo.bar + assertStdoutLineCount '==' 1 + assertStdoutGrep --stdout --stderr --matches=1 '^foo\.bar=yes$' + execute $dna config set foo. yes + assertExitStatus '!=' 0 + execute $dna config set .foo yes + assertExitStatus '!=' 0 + execute $dna config set foo..bar yes + assertExitStatus '!=' 0 + executeOk $dna config set foo.x.bar yes + executeOk $dna config get foo.x.bar + assertStdoutLineCount '==' 1 + assertStdoutGrep --stdout --stderr --matches=1 '^foo\.x\.bar=yes$' +} + +doc_DebugFlags="Debug flags affect verbosity" +test_DebugFlags() { + executeOk $dna echo one two three + assertStderrGrep --matches=0 '\