Пример #1
0
struct task*
create_task(downloader *dler, const char *url, const char *fullname)
{
	struct task *task = (struct task*)malloc(sizeof(struct task));
	
	task->dler          = dler;
	task->next          = dler->tasks;
	dler->tasks         = task;

	task->head_request  = http_request_new(task);

	task->name          = strdup(fullname);
	task->cur_size      = 0;

	task->blocks        = NULL;

	task->start_time    = uv_now(dler->mainloop);
	task->consumed_time = 0;

	task->last_step_time = task->start_time;
	task->last_step_size = task->cur_size;

	if (strncmp(url, "http://", 7) == 0) {
		task->url = http_parse_url(url);
	} else {
		int   len     = strlen(url);
		char *new_url = (char*)calloc(1, len + 7 + 1);
		memcpy(new_url, "http://", 7);
		memcpy(new_url + 7, url, len);

		task->url = http_parse_url(new_url);

		free(new_url);
	}

	if (task->url == NULL) {
		printf("parse url failed\n");
		exit(-1);
	}

	/* change host to a zero-terminated string for uv_getaddrinfo() */
	uv_buf_t buf = http_url_get_field(task->url, UF_HOST);
	char *host = (char*)calloc(1, buf.len + 1);
	memcpy(host, buf.base, buf.len);

	struct addrinfo hints;
	hints.ai_family   = PF_INET;
	hints.ai_socktype = SOCK_STREAM;
	hints.ai_protocol = IPPROTO_TCP;
	hints.ai_flags    = 0;

	uv_getaddrinfo_t *getaddrinfo = (uv_getaddrinfo_t*)malloc(sizeof(uv_getaddrinfo_t));
	getaddrinfo->data = task;

	uv_getaddrinfo(dler->mainloop, getaddrinfo, on_resolved, host, NULL, &hints);

	free(host);

	return task;
}
Пример #2
0
static int ICACHE_FLASH_ATTR on_url(http_parser *parser, const char *url, size_t length)
{	
	NODE_DBG("\nhttp_parser url: ");
    #ifdef DEVELOP_VERSION
	nprintf(url,length);
    #endif

	NODE_DBG("http_parser method: %d",parser->method);
		

	//grab the connection
	http_connection * conn = (http_connection *)parser->data;

	conn->state=HTTPD_STATE_ON_URL; //set state

	os_memcpy(conn->url,url,length); //copy url to connection info
	conn->url[length]=0; //null terminate string

	http_parse_url(conn);

	//execute cgi
	http_execute_cgi(conn);

	return 0;
}
Пример #3
0
int update_mirror_list(void) {
	int i = 0, x = 0, furl = 0;
	char *url = NULL;
	char mirror[255];
	memset(mirror, '\0', 255);

	if(settings_find_string("update-mirror", &url) != 0) {
		url = malloc(strlen(UPDATE_MIRROR)+1);
		if(!url) {
			logprintf(LOG_ERR, "out of memory");
			exit(EXIT_FAILURE);
		}
		strcpy(url, UPDATE_MIRROR);
		furl = 1;
	}

	http_parse_url(url, &update_filename);
	update_ret = http_get(update_filename, &update_data, &update_lg, update_typebuf);

	if(update_ret == 200 && strcmp(update_typebuf, "text/plain") == 0) {
		char *tmp = update_data;
		while(*tmp != '\0') {
			if(*tmp == '\n' || *tmp == '\0') {
				if(strlen(mirror) > 2) {
					update_mirrors = realloc(update_mirrors, (size_t)((i+1)*(int)sizeof(char *)));
					if(!update_mirrors) {
						logprintf(LOG_ERR, "out of memory");
						exit(EXIT_FAILURE);
					}
					mirror[x-1] = '\0';
					update_mirrors[i] = malloc(strlen(mirror)+1);
					if(!update_mirrors[i]) {
						logprintf(LOG_ERR, "out of memory");
						exit(EXIT_FAILURE);
					}
					strcpy(update_mirrors[i], mirror);
					i++;
				}
				memset(mirror, '\0', 255);
				x=0;
			}
			mirror[x] = *tmp;
			tmp++;
			x++;
		}
	}
	if(update_filename) sfree((void *)&update_filename);
	if(update_data) sfree((void *)&update_data);
	if(furl) sfree((void *)&url);

	return i;
}
Пример #4
0
char * http_get(const char *url,int timeout)  
{  

	char post[BUFFER_SIZE] = {'\0'};  
	int socket_fd = -1;  
	char lpbuf[BUFFER_SIZE*4] = {'\0'};  
	char *ptmp;  
	char host_addr[BUFFER_SIZE] = {'\0'};  
	char file[BUFFER_SIZE] = {'\0'};  
	int port = 0;  
	int len=0;  

	if(!url){  
		printf(NET_LIB_TAG"      failed!\n");  
		return NULL;  
	}  

	if(http_parse_url(url,host_addr,file,&port)){  
		printf(NET_LIB_TAG"http_parse_url failed!\n");  
		return NULL;  
	}  
	//printf(NET_LIB_TAG"host_addr : %s\tfile:%s\t,%d\n",host_addr,file,port);  

	socket_fd =  http_tcpclient_create(host_addr,port,timeout);  
	if(socket_fd < 0){  
		printf(NET_LIB_TAG"http_tcpclient_create failed\n");  
		return NULL;  
	}  

	sprintf(lpbuf,HTTP_GET,file,host_addr,port);  

	if(http_tcpclient_send(socket_fd,lpbuf,strlen(lpbuf),timeout) < 0){  
		printf(NET_LIB_TAG"http_tcpclient_send failed..\n");  
		return NULL;  
	}  
	//printf(NET_LIB_TAG"GET Sent:\n%s\n",lpbuf);  
	memset(lpbuf,0,BUFFER_SIZE*4);
	if((len=http_tcpclient_recv(socket_fd,lpbuf,timeout)) <= 0){  
		printf(NET_LIB_TAG"http_tcpclient_recv failed\n");  
		return NULL;  
	}
	else
	{
		http_tcpclient_recv(socket_fd,lpbuf+len,3);
	}
	http_tcpclient_close(socket_fd);  

	return http_parse_result(lpbuf);  
}  
Пример #5
0
char * http_post(const char *url,const char *post_str,int timeout){  

	char post[BUFFER_SIZE] = {'\0'};  
	int socket_fd = -1;  
	char lpbuf[BUFFER_SIZE*4] = {'\0'};  
	char *ptmp;  
	char host_addr[BUFFER_SIZE] = {'\0'};  
	char file[BUFFER_SIZE] = {'\0'};  
	int port = 0;  
	int len=0;  
	char *response = NULL;  

	if(!url || !post_str){  
		printf(NET_LIB_TAG"      failed!\n");  
		return NULL;  
	}  

	if(http_parse_url(url,host_addr,file,&port)){  
		printf(NET_LIB_TAG"http_parse_url failed!\n");  
		return NULL;  
	}  
	//printf(NET_LIB_TAG"host_addr : %s\tfile:%s\t,%d\n",host_addr,file,port);  

	socket_fd = http_tcpclient_create(host_addr,port,timeout);  
	if(socket_fd < 0){  
		printf(NET_LIB_TAG"http_tcpclient_create failed\n");  
		return NULL;  
	}  

	sprintf(lpbuf,HTTP_POST,file,host_addr,port,(int)strlen(post_str),post_str);  

	if(http_tcpclient_send(socket_fd,lpbuf,strlen(lpbuf),timeout) < 0){  
		printf(NET_LIB_TAG"http_tcpclient_send failed..\n");  
		return NULL;  
	}  
	//printf(NET_LIB_TAG"POST Sent:\n%s\n",lpbuf);  
	memset(lpbuf,0,BUFFER_SIZE*4);
	/*it's time to recv from server*/  
	if((len=http_tcpclient_recv(socket_fd,lpbuf,timeout)) <= 0){  
		printf(NET_LIB_TAG"http_tcpclient_recv failed\n");  
		return NULL;  
	}
	
//	http_tcpclient_recv(socket_fd,lpbuf+len,timeout);
	
	http_tcpclient_close(socket_fd);  

	return http_parse_result(lpbuf);  
}  
Пример #6
0
//Simple static url rewriter, allows us to process the request as another url without redirecting the user
//Used to serve index files on root / requests for example
int cgi_url_rewrite(http_connection *connData)
{
	if (connData->state==HTTPD_STATE_HEADERS_END)
	{
      HTTP_CGI_DBG("Rewrite %s to %s\n",connData->url,(char*)connData->cgi.argument);

		int urlSize = strlen((char*)connData->cgi.argument);
		if (urlSize < URL_MAX_SIZE)
		{
			strcpy(connData->url,(char*)connData->cgi.argument);
			//re-parse url
			http_parse_url(connData);
		}
	}
	return HTTPD_CGI_NEXT_RULE;
}
Пример #7
0
int handle_connect(int varNum)
{
	char *pResult = NULL;
	char host_addr[BUFFER_SIZE] = {'\0'};
	char file[BUFFER_SIZE] = {'\0'};
	// char lpbuf[BUFFER_SIZE * 4] = {'\0'};

	char *lpbuf = calloc(1024, sizeof(char));

	char lpbuf1[BUFFER_SIZE * 4] = {'\0'};
	char lpbuf2[BUFFER_SIZE * 4] = {'\0'};
	char lpbuf3[BUFFER_SIZE * 4] = {'\0'};
	//char *pUrl = "http://wap.dev.epet.com/group/v226/detail.html?do=Login";
	char *pUrl = "http://wap.dev.epet.com/main.html";


	char *pHttpContent = NULL;
	key_value *vals_message_type = NULL;
	int port = 0;
	int socket_fd = -1;
	int flag = -1;
	int cookesNum = 0;
	//char *urlTemplet = "http://wap.dev.epet.com/group/v226/detail.html?do=Login&uid=";

	char *urlTemplet = "http://wap.dev.epet.com/main.html";
	char numCtr[10] = {'\0'};
	sprintf(numCtr, "%d", varNum);
	char *urlStr = NULL;
	urlStr = (char *)calloc((strlen(urlTemplet)), sizeof(char));
	strcat(urlStr, urlTemplet);
	flag = http_parse_url(pUrl, host_addr, file, &port);
	socket_fd = http_tcpclient_create(host_addr, port);
	flag = http_get_send_content(&pResult, urlStr, vals_message_type, cookesNum);


	flag = http_tcpclient_send(socket_fd, pResult);
	free(pResult);
	pResult = NULL;	
	flag = http_tcpclient_recv(socket_fd, &lpbuf);
	printf("lbuff=%s\n", lpbuf);
	free(lpbuf);
	lpbuf = NULL;
	close(socket_fd);
	
	return 1;
}
Пример #8
0
gboolean
test_case(gint id, gchar *url_str, gboolean unicode, gboolean invalid_escape, gboolean expected_valid, gchar *scheme, gchar *user, gchar *passwd, gchar *host, guint port, gchar *file, gchar *query, gchar *fragment)
{
  HttpURL url;
  gchar *fail_reason = NULL;
  const gchar *error_reason = NULL;
  gboolean ok = TRUE, valid;

  http_init_url(&url);
  valid = http_parse_url(&url, unicode, invalid_escape, FALSE, url_str, &error_reason);

  if (ok && valid != expected_valid)
    {
      fail_reason = g_strdup_printf("Parse result different than expected: %s", !valid ? error_reason : "No error");
      ok = FALSE;
    }
  if (valid)
    {
      TEST_STR(scheme);
      TEST_STR(user);
      TEST_STR(passwd);
      TEST_STR(host);
      if (ok && port && port != url.port)
        {
          fail_reason = g_strdup("Return and expected value for port mismatch");
          ok = FALSE;
        }
      TEST_STR(file);
      TEST_STR(query);
      TEST_STR(fragment);
    }

  if (ok)
    {
      printf("test success, id=%d, url=%s\n", id, url_str);
      return TRUE;
    }
  else
    {
      printf("test failure, id=%d, url=%s, reason=%s\n", id, url_str, fail_reason);
      g_free(fail_reason);
      return FALSE;
    }
}
Пример #9
0
int main(int argc, char *argv[])
{
	char *data = NULL;
	char *filename = NULL;
	char typebuf[100];
	int length;
	int http_retcode;

	if (argc < 2) {
		fprintf(stderr, "No url!\n");
		exit(EXIT_FAILURE);
	}

	http_parse_url(argv[1], &filename);
	http_retcode = http_get(filename, &data, &length, typebuf);

	printf ("http_retcode = %d, typebuf = '%s', length = %d\n", http_retcode, typebuf, length);

	switch(http_retcode) {
		case ERRHOST:
			fprintf(stderr, "No such host.\n");
			break;
		case ERRSOCK:
			fprintf(stderr, "Can't create socket.\n");
			break;
		case ERRCONN:
			fprintf(stderr, "Can't connect to host.\n");
			break;
		case ERRWRHD:
			fprintf(stderr, "Write error on socket while writing header.\n");
			break;
		case ERRWRDT:
			fprintf(stderr, "Write error on socket while writing data.\n");
			break;
		case ERRRDHD:
			fprintf(stderr, "Read error on socket while reading result.\n");
			break;
		case ERRPAHD:
			fprintf(stderr, "Invalid answer from data server.\n");
			break;
		case ERRNULL:
			fprintf(stderr, "Null data pointer.\n");
			break;
		case ERRNOLG:
			fprintf(stderr, "No/Bad length in header.\n");
			break;
		case ERRMEM:
			fprintf(stderr, "Can't allocate memory.\n");
			break;
		case ERR400:
			fprintf(stderr, "400: Invalid query.\n");
			break;
		case ERR403:
			fprintf(stderr, "403: Forbidden.\n");
			break;
		case ERR408:
			fprintf(stderr, "408: Request timeout.\n");
			break;
		case ERR500:
			fprintf(stderr, "500: Server error.\n");
			break;
		case ERR501:
			fprintf(stderr, "501: Not implemented.\n");
			break;
		case ERR503:
			fprintf(stderr, "Service overloaded.\n");
			break;
		case OK0:
			fprintf(stderr, "Successfull parse.\n");
			break;
		case OK201:
			fprintf(stderr, "Ressource succesfully created.\n");
			break;
		case OK200:
			fprintf(stderr, "Ressource succesfully read.\n");
			break;
	}

	printf("data: %s\n", data);

/*
	if ((yyin = fopen(argv[1], "r")) == NULL) {
		perror("fopen");
		exit(EXIT_FAILURE);
	}

	yyparse();

	fclose(yyin);
*/

	return 0;

}
Пример #10
0
char *update_package_version(char *mirror) {
	int x = 0;
	size_t l = 0;
	char stable[] = "stable";
	char development[] = "development";
	char *nurl = NULL, *output = NULL, *pch = NULL, line[255], *version = malloc(4);
	int devel = 0;
	memset(line, '\0', 255);
	if(!version) {
		logprintf(LOG_ERR, "out of memory");
		exit(EXIT_FAILURE);
	}

	settings_find_number("update-development", &devel);

	if(devel) {
		nurl = malloc(strlen(mirror)+strlen(development)+41);
		if(!nurl) {
			logprintf(LOG_ERR, "out of memory");
			exit(EXIT_FAILURE);
		}
		sprintf(nurl, "%sdists/%s/main/binary-armhf/Packages.gz", mirror, development);
	} else {
		nurl = malloc(strlen(mirror)+strlen(stable)+41);
		if(!nurl) {
			logprintf(LOG_ERR, "out of memory");
			exit(EXIT_FAILURE);
		}
		sprintf(nurl, "%sdists/%s/main/binary-armhf/Packages.gz", mirror, stable);
	}
	http_parse_url(nurl, &update_filename);
	update_ret = http_get(update_filename, &update_data, &update_lg, update_typebuf);

	strcpy(version, "0.0");

	if(update_ret == 200 && strcmp(update_typebuf, "application/x-gzip") == 0) {
		z_stream strm = {0};
		unsigned char out[0x4000];
		memset(out, '\0', 0x4000);

		strm.zalloc = Z_NULL;
		strm.zfree = Z_NULL;
		strm.opaque = Z_NULL;
		strm.next_in = (unsigned char *)update_data;
		strm.avail_in = (uInt)update_lg;
		strm.next_out = out;
		inflateInit2(&strm, 15 | 32);

		do {
			strm.avail_out = 0x4000;
			inflate(&strm, Z_NO_FLUSH);
			l += strlen((char *)out);
			output = realloc(output, l+1);
			if(!output) {
				logprintf(LOG_ERR, "out of memory");
				exit(EXIT_FAILURE);
			}
			strcpy(&output[l-strlen((char *)out)], (char *)out);
		} while(strm.avail_out == 0);
		inflateEnd(&strm);

		if(output) {
			char *tmp = output;
			x = 0;
			while(*tmp != '\0') {
				if(*tmp == '\n' || *tmp == '\0') {
					if((pch = strstr(line, "Version: ")) > 0) {
						rmsubstr(line, "Version: ");
						rmsubstr(line, "\n");
						if(update_vercmp(line, version) >= 0) {
							version = realloc(version, strlen(line)+1);
							if(!version) {
								logprintf(LOG_ERR, "out of memory");
								exit(EXIT_FAILURE);
							}
							strcpy(version, line);
						}
					}
					memset(line, '\0', 255);
					x=0;
				}
				line[x] = *tmp;
				tmp++;
				x++;
			}
			sfree((void *)&output);
		}
	}
	sfree((void *)&nurl);
	if(update_filename) sfree((void *)&update_filename);
	if(update_data) sfree((void *)&update_data);
	return version;
}
Пример #11
0
int main(int argc,char* argv[]) 
{
	int  ret,lg,blocksize,r,i;
	char typebuf[70];
	char *data=NULL,*filename=NULL,*proxy=NULL;
	int data_len = 0;
	char *type = NULL;
	enum {
		ERR,
		DOPUT,
		DOGET,
		DODEL,
		DOHEA,
		DOPOST
	} todo=ERR;
	
	if (argc!=3) {
		fprintf(stderr,"usage: http <cmd> <url>\n\tby <*****@*****.**>\n");
		return 1;
	}

	i=1;
	 
	if (!strcasecmp(argv[i],"put")) {
		todo=DOPUT;
	} else if (!strcasecmp(argv[i],"get")) {
		todo=DOGET;
	} else if (!strcasecmp(argv[i],"delete")) {
		todo=DODEL;
	} else if (!strcasecmp(argv[i],"head")) {
		todo=DOHEA;
	} else if (!strcasecmp(argv[i],"post")) {
		todo=DOPOST;
	}

	if (todo==ERR) {
		fprintf(stderr,
			"Invalid <cmd> '%s',\nmust be "
			"'put', 'get', 'post', 'delete', or 'head'\n",
			argv[i]
		);
		return 2;
	}

	i++;
	
	if ((proxy=getenv("http_proxy"))) {
		ret=http_proxy_url(proxy);
		if (ret<0) { 
			return ret;
		}
	}
	
	ret=http_parse_url(argv[i],&filename);
	if (ret<0) {
		return ret;
	}
	
	switch (todo) {
	/* *** PUT  *** */
	case DOPUT:
		fprintf(stderr,"reading stdin...\n");
		/* read stdin into memory */
		blocksize=16384;
		lg=0;  

		if (!(data=malloc(blocksize))) {
			return 3;
		}

		while (1) {
			r=read(0,data+lg,blocksize-lg);
			if (r<=0) break; 
			lg+=r;
			if ((3*lg/2)>blocksize) {
				blocksize *= 4;
				fprintf(stderr,
				"read to date: %9d bytes, reallocating buffer to %9d\n",
				lg,blocksize);	
				if (!(data=realloc(data,blocksize))) {
					return 4;
				}
			}
		}

		fprintf(stderr,"read %d bytes\n",lg);
		ret=http_put(filename,data,lg,0,NULL);
		fprintf(stderr,"res=%d\n",ret);
		break;
	/* *** GET  *** */
	case DOGET:
		ret=http_get(filename,&data,&lg,typebuf);
		fprintf(stderr,"res=%d,type='%s',lg=%d\n",ret,typebuf,lg);
		fwrite(data,lg,1,stdout);
		fprintf(stderr, "%s\n", data);
		break;
	/* *** HEAD  *** */
	case DOHEA:
		ret=http_head(filename,&lg,typebuf);
		fprintf(stderr,"res=%d,type='%s',lg=%d\n",ret,typebuf,lg);
		break;
	/* *** DELETE  *** */
	case DODEL:
		ret=http_delete(filename);
		fprintf(stderr,"res=%d\n",ret);
		break;
	case DOPOST:
		ret = http_post(filename, "your_name=1", 11, NULL, &data, &data_len, &type);
		fprintf(stderr,"res=%d\n",ret);
		fprintf(stderr,"%s\n", type);
		fprintf(stderr,"data: %s\n", data);
		break;
	/* impossible... */
	default:
		fprintf(stderr,"impossible todo value=%d\n",todo);
		return 5;
	}
	
	if (type) {
		free(type);
	}

	if (data) {
		 free(data);
	}

	free(filename);
	 
	return ( (ret==201) || (ret==200) ) ? 0 : ret;
}
Пример #12
0
int settings_parse(JsonNode *root) {
    int have_error = 0;

#ifdef WEBSERVER
    int web_port = 0;
    int own_port = 0;

    char *webgui_tpl = malloc(strlen(WEBGUI_TEMPLATE)+1);
    if(!webgui_tpl) {
        logprintf(LOG_ERR, "out of memory");
        exit(EXIT_FAILURE);
    }
    strcpy(webgui_tpl, WEBGUI_TEMPLATE);
    char *webgui_root = malloc(strlen(WEBSERVER_ROOT)+1);
    if(!webgui_root) {
        logprintf(LOG_ERR, "out of memory");
        exit(EXIT_FAILURE);
    }
    strcpy(webgui_root, WEBSERVER_ROOT);
#endif

#ifndef __FreeBSD__
    regex_t regex;
    int reti;
#endif

    JsonNode *jsettings = json_first_child(root);

    while(jsettings) {
        if(strcmp(jsettings->key, "port") == 0
                || strcmp(jsettings->key, "send-repeats") == 0
                || strcmp(jsettings->key, "receive-repeats") == 0) {
            if((int)jsettings->number_ == 0) {
                logprintf(LOG_ERR, "setting \"%s\" must contain a number larger than 0", jsettings->key);
                have_error = 1;
                goto clear;
            } else {
#ifdef WEBSERVER
                if(strcmp(jsettings->key, "port") == 0) {
                    own_port = (int)jsettings->number_;
                }
#endif
                settings_add_number(jsettings->key, (int)jsettings->number_);
            }
        } else if(strcmp(jsettings->key, "standalone") == 0) {
            if(jsettings->number_ < 0 || jsettings->number_ > 1) {
                logprintf(LOG_ERR, "setting \"%s\" must be either 0 or 1", jsettings->key);
                have_error = 1;
                goto clear;
            } else {
                settings_add_number(jsettings->key, (int)jsettings->number_);
            }
        }  else if(strcmp(jsettings->key, "firmware-update") == 0) {
            if(jsettings->number_ < 0 || jsettings->number_ > 1) {
                logprintf(LOG_ERR, "setting \"%s\" must be either 0 or 1", jsettings->key);
                have_error = 1;
                goto clear;
            } else {
                settings_add_number(jsettings->key, (int)jsettings->number_);
            }
        } else if(strcmp(jsettings->key, "log-level") == 0) {
            if((int)jsettings->number_ < 0 || (int)jsettings->number_ > 5) {
                logprintf(LOG_ERR, "setting \"%s\" must contain a number from 0 till 5", jsettings->key);
                have_error = 1;
                goto clear;
            } else {
                settings_add_number(jsettings->key, (int)jsettings->number_);
            }
        } else if(strcmp(jsettings->key, "pid-file") == 0 || strcmp(jsettings->key, "log-file") == 0) {
            if(!jsettings->string_) {
                logprintf(LOG_ERR, "setting \"%s\" must contain an existing file path", jsettings->key);
                have_error = 1;
                goto clear;
            } else {
                if(path_exists(jsettings->string_) != EXIT_SUCCESS) {
                    logprintf(LOG_ERR, "setting \"%s\" must point to an existing folder", jsettings->key);
                    have_error = 1;
                    goto clear;
                } else {
                    settings_add_string(jsettings->key, jsettings->string_);
                }
            }
        } else if(strcmp(jsettings->key, "config-file") == 0 || strcmp(jsettings->key, "hardware-file") == 0) {
            if(!jsettings->string_) {
                logprintf(LOG_ERR, "setting \"%s\" must contain an existing file path", jsettings->key);
                have_error = 1;
                goto clear;
            } else if(strlen(jsettings->string_) > 0) {
                if(settings_file_exists(jsettings->string_) == EXIT_SUCCESS) {
                    settings_add_string(jsettings->key, jsettings->string_);
                } else {
                    logprintf(LOG_ERR, "setting \"%s\" must point to an existing file", jsettings->key);
                    have_error = 1;
                    goto clear;
                }
            }
        } else if(strcmp(jsettings->key, "whitelist") == 0) {
            if(!jsettings->string_) {
                logprintf(LOG_ERR, "setting \"%s\" must contain valid ip addresses", jsettings->key);
                have_error = 1;
                goto clear;
            } else if(strlen(jsettings->string_) > 0) {
#ifndef __FreeBSD__
                char validate[] = "^((\\*|[0-9]|[1-9][0-9]|1[0-9][0-9]|2([0-4][0-9]|5[0-5]))\\.(\\*|[0-9]|[1-9][0-9]|1[0-9][0-9]|2([0-4][0-9]|5[0-5]))\\.(\\*|[0-9]|[1-9][0-9]|1[0-9][0-9]|2([0-4][0-9]|5[0-5]))\\.(\\*|[0-9]|[1-9][0-9]|1[0-9][0-9]|2([0-4][0-9]|5[0-5]))(,[\\ ]|,|$))+$";
                reti = regcomp(&regex, validate, REG_EXTENDED);
                if(reti) {
                    logprintf(LOG_ERR, "could not compile regex");
                    have_error = 1;
                    goto clear;
                }
                reti = regexec(&regex, jsettings->string_, 0, NULL, 0);
                if(reti == REG_NOMATCH || reti != 0) {
                    logprintf(LOG_ERR, "setting \"%s\" must contain valid ip addresses", jsettings->key);
                    have_error = 1;
                    regfree(&regex);
                    goto clear;
                }
                regfree(&regex);
#endif
                int l = (int)strlen(jsettings->string_)-1;
                if(jsettings->string_[l] == ' ' || jsettings->string_[l] == ',') {
                    logprintf(LOG_ERR, "setting \"%s\" must contain valid ip addresses", jsettings->key);
                    have_error = 1;
                    goto clear;
                }
                settings_add_string(jsettings->key, jsettings->string_);
            }
#ifdef WEBSERVER
        } else if(strcmp(jsettings->key, "webserver-port") == 0) {
            if(jsettings->number_ < 0) {
                logprintf(LOG_ERR, "setting \"%s\" must contain a number larger than 0", jsettings->key);
                have_error = 1;
                goto clear;
            } else {
                web_port = (int)jsettings->number_;
                settings_add_number(jsettings->key, (int)jsettings->number_);
            }
        } else if(strcmp(jsettings->key, "webserver-root") == 0) {
            if(!jsettings->string_ || path_exists(jsettings->string_) != 0) {
                logprintf(LOG_ERR, "setting \"%s\" must contain a valid path", jsettings->key);
                have_error = 1;
                goto clear;
            } else {
                webgui_root = realloc(webgui_root, strlen(jsettings->string_)+1);
                if(!webgui_root) {
                    logprintf(LOG_ERR, "out of memory");
                    exit(EXIT_FAILURE);
                }
                strcpy(webgui_root, jsettings->string_);
                settings_add_string(jsettings->key, jsettings->string_);
            }
        } else if(strcmp(jsettings->key, "webserver-enable") == 0) {
            if(jsettings->number_ < 0 || jsettings->number_ > 1) {
                logprintf(LOG_ERR, "setting \"%s\" must be either 0 or 1", jsettings->key);
                have_error = 1;
                goto clear;
            } else {
                settings_add_number(jsettings->key, (int)jsettings->number_);
            }
        } else if(strcmp(jsettings->key, "webserver-cache") == 0) {
            if(jsettings->number_ < 0 || jsettings->number_ > 1) {
                logprintf(LOG_ERR, "setting \"%s\" must be either 0 or 1", jsettings->key);
                have_error = 1;
                goto clear;
            } else {
                settings_add_number(jsettings->key, (int)jsettings->number_);
            }
        } else if(strcmp(jsettings->key, "webserver-user") == 0) {
            if(jsettings->string_ || strlen(jsettings->string_) > 0) {
                if(name2uid(jsettings->string_) == -1) {
                    logprintf(LOG_ERR, "setting \"%s\" must contain a valid system user", jsettings->key);
                    have_error = 1;
                    goto clear;
                } else {
                    settings_add_string(jsettings->key, jsettings->string_);
                }
            }
        } else if(strcmp(jsettings->key, "webserver-authentication") == 0 && jsettings->tag == JSON_ARRAY) {
            JsonNode *jtmp = json_first_child(jsettings);
            unsigned short i = 0;
            while(jtmp) {
                i++;
                if(jtmp->tag == JSON_STRING) {
                    if(i == 1) {
                        settings_add_string("webserver-authentication-username", jtmp->string_);
                    } else if(i == 2) {
                        settings_add_string("webserver-authentication-password", jtmp->string_);
                    }
                } else {
                    have_error = 1;
                    break;
                }
                if(i > 2) {
                    have_error = 1;
                    break;
                }
                jtmp = jtmp->next;
            }
            if(i != 2 || have_error == 1) {
                logprintf(LOG_ERR, "setting \"%s\" must be in the format of [ \"username\", \"password\" ]", jsettings->key);
                have_error = 1;
                goto clear;
            }
        }  else if(strcmp(jsettings->key, "webgui-template") == 0) {
            if(!jsettings->string_) {
                logprintf(LOG_ERR, "setting \"%s\" must be a valid template", jsettings->key);
                have_error = 1;
                goto clear;
            } else {
                webgui_tpl = realloc(webgui_tpl, strlen(jsettings->string_)+1);
                if(!webgui_tpl) {
                    logprintf(LOG_ERR, "out of memory");
                    exit(EXIT_FAILURE);
                }
                strcpy(webgui_tpl, jsettings->string_);
                settings_add_string(jsettings->key, jsettings->string_);
            }
#endif
#ifdef UPDATE
        } else if(strcmp(jsettings->key, "update-check") == 0) {
            if(jsettings->number_ < 0 || jsettings->number_ > 1) {
                logprintf(LOG_ERR, "setting \"%s\" must be either 0 or 1", jsettings->key);
                have_error = 1;
                goto clear;
            } else {
                settings_add_number(jsettings->key, (int)jsettings->number_);
            }
        } else if(strcmp(jsettings->key, "update-development") == 0) {
            if(jsettings->number_ < 0 || jsettings->number_ > 1) {
                logprintf(LOG_ERR, "setting \"%s\" must be either 0 or 1", jsettings->key);
                have_error = 1;
                goto clear;
            } else {
                settings_add_number(jsettings->key, (int)jsettings->number_);
            }
        } else if(strcmp(jsettings->key, "update-mirror") == 0) {
            char *filename = NULL;
            char *url = NULL;
            char *data = NULL;
            int lg = 0;
            char typebuf[70];

            if(jsettings->string_) {
                url = malloc(strlen(jsettings->string_)+1);
                if(!url) {
                    logprintf(LOG_ERR, "out of memory");
                    exit(EXIT_FAILURE);
                }
                strcpy(url, jsettings->string_);
                http_parse_url(url, &filename);
            }
            if(!jsettings->string_ || http_get(filename, &data, &lg, typebuf) != 200) {
                logprintf(LOG_ERR, "setting \"%s\" must be point to a valid (online) file", jsettings->key);
                /* clean-up http_lib global */
                if(http_server) sfree((void *)&http_server);
                if(filename) sfree((void *)&filename);
                if(url) sfree((void *)&url);
                if(data) sfree((void *)&data);
                have_error = 1;
                goto clear;
            } else {
                settings_add_string(jsettings->key, jsettings->string_);
                /* clean-up http_lib global */
                if(http_server) sfree((void *)&http_server);
                if(filename) sfree((void *)&filename);
                if(url) sfree((void *)&url);
                if(data) sfree((void *)&data);
            }
#endif
        } else {
            logprintf(LOG_ERR, "setting \"%s\" is invalid", jsettings->key);
            have_error = 1;
            goto clear;
        }
        jsettings = jsettings->next;
    }
    json_delete(jsettings);
#ifdef WEBSERVER
    if(webgui_tpl) {
        char *tmp = malloc(strlen(webgui_root)+strlen(webgui_tpl)+13);
        if(!tmp) {
            logprintf(LOG_ERR, "out of memory");
            exit(EXIT_FAILURE);
        }
        sprintf(tmp, "%s/%s/index.html", webgui_root, webgui_tpl);
        if(path_exists(tmp) != EXIT_SUCCESS) {
            logprintf(LOG_ERR, "setting \"webgui-template\", template does not exists");
            have_error = 1;
            sfree((void *)&tmp);
            goto clear;
        }
        sfree((void *)&tmp);
    }

    if(web_port == own_port) {
        logprintf(LOG_ERR, "setting \"port\" and \"webserver-port\" cannot be the same");
        have_error = 1;
        goto clear;
    }
#endif
clear:
#ifdef WEBSERVER
    if(webgui_tpl) {
        sfree((void *)&webgui_tpl);
    }
    if(webgui_root) {
        sfree((void *)&webgui_root);
    }
#endif
    return have_error;
}