Beispiel #1
0
static int func_http_repl_send_start(clientHttpRequest *http)
{
	assert(http);
    if (0 == http->request->flags.redirected)
        return -1;

    HttpHeader *hdr = &http->reply->header;
    HttpHeaderEntry e;
    stringInit(&e.name,"Content-Disposition");
    stringInit(&e.value,"attachment; filename=\"");

    char *filename = strrchr(http->uri, '/');
    if (NULL == filename)
        return -1;
    filename++;
    stringAppend(&e.value, filename, strlen(filename));
    stringAppend(&e.value, "\"", 1);

    e.id = HDR_CONTENT_DISPOSITION;
    httpHeaderDelById(hdr, e.id);  
    httpHeaderAddEntry(hdr, httpHeaderEntryClone(&e));
    stringClean(&e.name);
    stringClean(&e.value);
	return 0;
}
Beispiel #2
0
char *keyBindingToString(CompDisplay * d, CompKeyBinding * key)
{
	char *binding;

	binding = modifiersToString(d, key->modifiers);

	if (key->keycode != 0) {
		KeySym *keysym;
		char *keyname;
		int keysymsPerKeycode = 0;

		/* convert keycode to keysym */
		keysym = XGetKeyboardMapping(d->display,
					     key->keycode, 1,
					     &keysymsPerKeycode);

		keyname = XKeysymToString(keysym[0]);

		XFree(keysym);

		if (keyname) {
			binding = stringAppend(binding, keyname);
		} else {
			char keyCodeStr[256];

			snprintf(keyCodeStr, 256, "0x%x", key->keycode);
			binding = stringAppend(binding, keyCodeStr);
		}
	}

	return binding;
}
Beispiel #3
0
/* generates a "unique" boundary string for multipart responses
 * the caller is responsible for cleaning the string */
String
httpHdrRangeBoundaryStr(clientHttpRequest * http)
{
    const char *key;
    String b = StringNull;
    assert(http);
    stringAppend(&b, full_appname_string, strlen(full_appname_string));
    stringAppend(&b, ":", 1);
    key = storeKeyText(http->entry->key);
    stringAppend(&b, key, strlen(key));
    return b;
}
int parseLockUrl(char *lockURL, VersionUpdateConfig *config){
	
	char *paramURL = NULL;
	char reqStr[256];
	char portStr[16];
	int  ipLen;
	int  portLen;
	int  reqLen;
	
	memset(reqStr, 0, 256);
	memset(portStr, 0, 16);

	//Trim the http://
	char *pStart = strstr(lockURL, "http://");
	if(NULL == pStart){
		return 0;
	}
	
	lockURL  = lockURL + strlen("http://");
	paramURL = strchr(lockURL, '/');
	if(NULL == paramURL){
		return 0;
	}
		
	//Get port number
	char *port = strchr(lockURL, ':');
	if(NULL != port){
		portLen = paramURL - port -1;
		strncpy(portStr, port +1, portLen);
		PORT_NUM = atoi(portStr);
		ipLen = port - lockURL;
	}else{
		ipLen = paramURL - lockURL;
	}
	
	IP_ADDRESS = buffer_init_size(ipLen + 1);
	stringAppend(IP_ADDRESS, lockURL, ipLen);
	
	strcat(reqStr, "GET ");
	strcat(reqStr, paramURL);
	strcat(reqStr, " HTTP/1.1\r\n");
	strcat(reqStr, "Host: ");
	strcat(reqStr, IP_ADDRESS->ptr);
	strcat(reqStr, "\r\nConnection: Close\r\n\r\n");
		
	reqLen = strlen(reqStr);
	buffer *lockRequestURL = buffer_init_size(reqLen + 1);
	stringAppend(lockRequestURL, reqStr, reqLen);
	config->lockRequestURL = lockRequestURL;
	
	return 1;
}
/* appends an item to the list */
void
strListAdd(String * str, const char *item, char del)
{
    assert(str && item);
    if (strLen(*str)) {
	char buf[3];
	buf[0] = del;
	buf[1] = ' ';
	buf[2] = '\0';
	stringAppend(str, buf, 2);
    }
    stringAppend(str, item, strlen(item));
}
Beispiel #6
0
/* Append a new token onto the end of the string */
static void stringAppendTerm(String *p, const char *z){
  int i;
  if( p->n ) stringAppend(p, " ", 1);
  if( z==0 ){
    stringAppend(p, "nil", 3);
    return;
  }
  for(i=0; z[i] && !isspace(z[i]); i++){}
  if( i>0 && z[i]==0 ){
    stringAppend(p, z, i);
    return;
  }
  stringAppend(p, "'", 1);
  while( z[0] ){
    for(i=0; z[i] && z[i]!='\''; i++){}
    if( z[i] ){
      stringAppend(p, z, i+1);
      stringAppend(p, "'", 1);
      z += i+1;
    }else{
      stringAppend(p, z, i);
      break;
    }
  }
  stringAppend(p, "'", 1);
}
/**
 * Parses a quoted-string field (RFC 2616 section 2.2), complains if
 * something went wrong, returns non-zero on success.
 * start should point at the first double-quote.
 * RC TODO: This is too looose. We should honour the BNF and exclude CTL's
 */
int
httpHeaderParseQuotedString(const char *start, String * val)
{
    const char *end, *pos;
    stringClean(val);
    if (*start != '"') {
	debug(66, 2) ("failed to parse a quoted-string header field near '%s'\n", start);
	return 0;
    }
    pos = start + 1;

    while (*pos != '"') {
	int quoted = (*pos == '\\');
	if (quoted)
	    pos++;
	if (!*pos) {
	    debug(66, 2) ("failed to parse a quoted-string header field near '%s'\n", start);
	    stringClean(val);
	    return 0;
	}
	end = pos + strcspn(pos + quoted, "\"\\") + quoted;
	stringAppend(val, pos, end - pos);
	pos = end;
    }
    /* Make sure it's defined even if empty "" */
    if (!val->buf)
	stringLimitInit(val, "", 0);
    return 1;
}
Beispiel #8
0
void
derelativizeURL (char* tok, char* url, RDFFile f)
{
  if ((tok[0] == '/') && (endsWith(".mco", tok))) {
	void stringAppendBase (char* dest, const char* addition) ;
    stringAppendBase(url, f->url); 
    stringAppend(url, "#");
    stringAppend(url, tok);
  } else if  ((endsWith(".mco", tok)) && (charSearch('#', tok) == -1)) {
    void stringAppendBase (char* dest, const char* addition) ;
    stringAppendBase(url, f->url);
    stringAppend(url, "#");
    stringAppend(url, tok);
  } else {
    memcpy(url, tok, strlen(tok));
  }
}
Beispiel #9
0
char *edgeMaskToString(unsigned int edgeMask)
{
	char *edge = NULL;
	int i;

	for (i = 0; i < SCREEN_EDGE_NUM; i++) {
		if (edgeMask & (1 << i)) {
			if (edge)
				edge = stringAppend(edge, " | ");

			edge = stringAppend(edge, edgeToString(i));
		}
	}

	if (!edge)
		return strdup("");

	return edge;
}
Beispiel #10
0
static inline int url_replace(clientHttpRequest* http, struct mod_conf_param* param)
{
	char tmpUrl[BUFSIZ];
	int ret = 0;
	ret = regexec(&param->reg, http->uri, REPLACE_REGEX_SUBSTR_NUMBER+1, g_pmatch, 0);
	if(0 != ret) 
	{
		debug(120, 3)("url_replace: donot match regex, uri=[%s]\n", http->uri);
		return 0;
	}       
	String url = StringNull;
	stringAppend(&url, param->replace[0], strlen(param->replace[0]));
	int i = 1;
	while(0 != (ret=(long int)param->replace[i]))
	{       
		stringAppend(&url, http->uri+g_pmatch[ret].rm_so, g_pmatch[ret].rm_eo-g_pmatch[ret].rm_so);
		debug(120,3)("rm_so=%d, rm_eo=%d\n", g_pmatch[ret].rm_so, g_pmatch[ret].rm_eo);
		i++;    
		if(param->replace[i])
		{       
			stringAppend(&url, param->replace[i], strlen(param->replace[i]));
			i++;    
		}               
		else            
		{       
			break;
		}       
	}                       
	xfree(http->uri);       
	if (param->ingoreCase)
	{
		if (changeCase(url.buf, tmpUrl))
			http->uri = xstrdup(tmpUrl);
		else
			http->uri = xstrdup(url.buf);
	}
	else
		http->uri = xstrdup(url.buf);
	stringClean(&url);
	debug(120, 3)("url_replace: uri modified, uri=[%s]\n", http->uri);
	return 1;
}
Beispiel #11
0
static char *edgeMaskToBindingString(CompDisplay * d, unsigned int edgeMask)
{
	char *binding = NULL;
	int i;

	for (i = 0; i < SCREEN_EDGE_NUM; i++)
		if (edgeMask & (1 << i))
			binding = stringAppend(binding, edges[i].modifierName);

	return binding;
}
Beispiel #12
0
char *buttonActionToString(CompDisplay * d, CompAction * action)
{
	char *binding, *edge;
	char buttonStr[256];

	binding = modifiersToString(d, action->button.modifiers);
	edge = edgeMaskToBindingString(d, action->edgeMask);

	if (edge) {
		binding = stringAppend(binding, edge);
		free(edge);
	}

	snprintf(buttonStr, 256, "Button%d", action->button.button);
	binding = stringAppend(binding, buttonStr);

	if (!binding)
		return strdup("Disabled");

	return binding;
}
Beispiel #13
0
char *buttonBindingToString(CompDisplay * d, CompButtonBinding * button)
{
	char *binding;
	char buttonStr[256];

	binding = modifiersToString(d, button->modifiers);

	snprintf(buttonStr, 256, "Button%d", button->button);
	binding = stringAppend(binding, buttonStr);

	return binding;
}
Beispiel #14
0
static char *modifiersToString(CompDisplay * d, unsigned int modMask)
{
	char *binding = NULL;
	int i;

	for (i = 0; i < N_MODIFIERS; i++) {
		if (modMask & modifiers[i].modifier)
			binding = stringAppend(binding, modifiers[i].name);
	}

	return binding;
}
void checkAndGzip(buffer *tmpFilePath, buffer *targetFilePath, buffer *expectFilePath, buffer *responsePath){
	char *responseCnt = readResponse(responsePath->ptr);
	int httpStatus = getHttpStatus(responseCnt);
	if(200 == httpStatus) {
		if(-1 != rename(tmpFilePath->ptr, targetFilePath->ptr)) {
			//system invoke unzip
			buffer *unzipCmd = buffer_init_size(20 + targetFilePath->used + expectFilePath->used);
			stringAppend(unzipCmd, GZIP_CMD, GZIP_CMD_LEN);
			stringAppend(unzipCmd, targetFilePath->ptr, targetFilePath->used);
			stringAppend(unzipCmd, " > ", 3);
			stringAppend(unzipCmd, expectFilePath->ptr, expectFilePath->used);

			debug_buffer(unzipCmd, "unzipCmd");
			if(-1 == system(unzipCmd->ptr)) {
				fprintf(stderr, "system(gzip....) error:%s\n", unzipCmd->ptr);
				exit(5);
			}
			buffer_free(unzipCmd);
		}
	}
	free(responseCnt);
}
/*
 * returns a pointer to a specified entry if any 
 * note that we return one entry so it does not make much sense to ask for
 * "list" headers
 */
String
httpHeaderGetByNameListMember(const HttpHeader * hdr, const char *name, const char *member, const char separator)
{
    String result = StringNull;
    String header;
    const char *pos = NULL;
    const char *item;
    int ilen;
    int mlen = strlen(member);

    assert(hdr);
    assert(name);

    header = httpHeaderGetByName(hdr, name);

    while (strListGetItem(&header, separator, &item, &ilen, &pos)) {
	if (strncmp(item, member, mlen) == 0 && item[mlen] == '=') {
	    stringAppend(&result, item + mlen + 1, ilen - mlen - 1);
	    break;
	}
    }
    return result;
}
/*
 * returns a the value of the specified list member, if any.
 */
String
httpHeaderGetListMember(const HttpHeader * hdr, http_hdr_type id, const char *member, const char separator)
{
    String result = StringNull;
    String header;
    const char *pos = NULL;
    const char *item;
    int ilen;
    int mlen = strlen(member);

    assert(hdr);
    assert_eid(id);

    header = httpHeaderGetStrOrList(hdr, id);

    while (strListGetItem(&header, separator, &item, &ilen, &pos)) {
	if (strncmp(item, member, mlen) == 0 && item[mlen] == '=') {
	    stringAppend(&result, item + mlen + 1, ilen - mlen - 1);
	    break;
	}
    }
    stringClean(&header);
    return result;
}
static void func_sys_after_parse_param()
{
	int i;
	for(i = 0 ; i < mod->mod_params.count; i++)
	{
		cc_mod_param *mod_param = mod->mod_params.items[i];
		mod_config *cfg = mod_param->param;

        // add by xueye.zhao
        // 2013-4-18

        if (is_http_move_status(cfg->ResponseStatus))
        {
            continue;
        }

        // end add

        if(is_url(cfg->location))
		{

			struct stat sb;
			if (stat("/data/proclog/log/squid/customized_error_page", &sb) != 0){
				mkdir("/data/proclog/log/squid/customized_error_page", S_IRWXU);
			}
			FILE *fp = popen("/usr/local/squid/bin/get_file_from_url.pl", "r");
			assert(fp);
			while(1)
			{
				char perloutput[512];
				if(!fgets(perloutput, 512, fp))
				{
					break;
				}

				debug(115, 1)("mod_customized_server_side_error_page get_file_from_url.pl said: %s\n", perloutput);
			}
			pclose(fp);


			/*
			   if (stat("/data/proclog/log/squid/customized_error_page", &sb) != 0){
			   mkdir("/data/proclog/log/squid/customized_error_page", S_IRWXU);
			   }
			   */
			if(stringConvert((cfg->location)))
			{
				debug(115,0) ( "mod_customized_server_side_error_page: cfg->location url error\n");
				continue;
			}

			debug(115,4) ( "mod_customized_server_side_error_page: cfg->location is: %s\n", cfg->location);

			//char* tmp = NULL;
			String tmp = StringNull;
			stringInit(&tmp, "/data/proclog/log/squid/customized_error_page/");
			stringAppend(&tmp, cfg->location+7, strlen(cfg->location)-7);
			memset(cfg->location,0,sizeof(cfg->location));
			strncpy(cfg->location,strBuf(tmp),strLen(tmp));
			errorTryLoadText(&cfg->customized_error_text, cfg->location);
			stringClean(&tmp);
		}
		else
		{
			//cfg->is_url = 0;
			errorTryLoadText(&cfg->customized_error_text, cfg->location);
		}
	}
}
Beispiel #19
0
// confige line example:
// mod_header [direction add|del|modify header_name [header_value]]{1,..n} allow|deny acl
// ??????ͷ??ʼ?????? allow|deny ??ֹ
// ????????????
static int func_sys_parse_param(char *cfg_line)
{
	assert(cfg_line);

	struct mod_conf_param* data = NULL;
	char* token = NULL;
	int ret = 0;
	int i;
	
	// add by xueye.zhao
	// 2013/6/19
	
# if 0
	//?ҵ?allow????deny?? Ȼ????֮???Ľ?ȥ
	//zhoudshu add for bug mantis 0002002

	char* tmptoken = NULL;
	char* tmp_line = xstrdup(cfg_line);
	if ((tmptoken = strtok(tmp_line, w_space)) == NULL)
	{	
		debug(98, 3)("(mod_header) ->  parse line error\n");
		safe_free(tmp_line);
		return -1;
	
	}

	int haskey = 0;
	while(NULL != (tmptoken = strtok(NULL, w_space)))
	{
		if(strcmp("allow",tmptoken) == 0 || strcmp("deny",tmptoken) == 0){
			haskey = 1;
		}
	}

	safe_free(tmp_line);
	
	if(haskey != 1){
		debug(98, 3)("(mod_header) ->  has not key of allow or deny in config line \n");
		return -1;
	}	

#endif
	

	if (NULL == strstr(cfg_line, " allow "))
	{
		debug(98, 3)("(mod_header) ->  has not key of allow or deny in config line \n");
		return -1;
	}
	
	//end add

	//开始截取	
	if ((token = strtok(cfg_line, w_space)) != NULL)
	{
		if(strcmp(token, "mod_header"))
			goto errA;	
	}
	else
	{
		debug(98, 3)("(mod_header) ->  parse line error\n");
		goto errA;	
	}

	data = mod_config_pool_alloc();
	data->count = 0;
	//?????↑ʼѭ??ȡ??????..???Dz???+header+value?ķ?ʽ, ????,ѭ????????
	while(NULL != (token = strtok(NULL, w_space)))
	{
		if(strcmp("allow",token) == 0 || strcmp("deny",token) == 0 || strcmp("reply_check",token) == 0) {
			break;
		}	

		struct action_part* part;
		struct header_info* info;
		part = action_part_pool_alloc();
		info = header_info_pool_alloc();
		data->acp[data->count] = part;
		data->acp[data->count]->hdr = info;
		data->count++;
		
		part->direct = atoi(token); //fetch the direction

		if(part->direct > 3 || part->direct < 0)
		{
			debug(98, 3)("(mod_header) ->  parse direction error, cant be %d\n", part->direct);
			goto err;
		}

		//???↑ʼ?ǽ???????????
		if (NULL == (token = strtok(NULL, w_space)))
		{
			debug(98, 3)("(mod_header) ->  parse line data does not existed\n");
			goto err;
		}
		ret = parse_operation(part, token);//??????????, ???????????ṹ
		if(-1 == ret)
		{
			debug(98, 3)("(mod_header) ->  parse line operation error, cant be %s\n", token);
			goto err;
		}

		//?????и?header, ?????϶??е?
		if (NULL == (token = strtok(NULL, w_space)))
		{
			debug(98, 3)("(mod_header) ->  parse line data does not existed\n");
			goto err;
		}
		stringInit(&info->header, token);	

		//?и???header, value?Ͳ?һ??????. ????Ҫ??????��?ж???. ??????Ҫ?и?value, ?͸???
		if (1 != part->action)
		{
			if (NULL == (token = strtok(NULL, w_space))) {
				debug(98, 3)("(mod_header) ->  parse line data does not existed\n");
				goto err;
			}

			//??Ȼ??value, ?ͱ???????. ?? header һ???????ŵ?????.
			stringInit(&info->value, token);	

			/* case http://sis.ssr.chinacache.com/rms/view.php?id=4124 */
			if (*token == '\"') {
				stringClean(&info->value);
				stringInit(&info->value, token+1);	
				int len = 0;
				while (NULL !=(token = strtok(NULL,w_space))){
					len = strlen(token);
					if (token[len-1] == '\"'){
						stringAppend(&info->value, " ", 1);
						stringAppend(&info->value, token, len-1);
						break;
					}
					else if (strcmp("allow",token) == 0 || strcmp("deny",token) == 0) 
						goto err;
					else {
						stringAppend(&info->value, " ", 1);
						stringAppend(&info->value, token, len);
					}
				}
			}
		}
	}
	//һ??û???κ????ݣ? ֱ?ӱ???
	if(data->count == 0)
		goto err;
	else
		cc_register_mod_param(mod, data, free_callback);
	return 0;

err:
	debug(98,1)("mod_header: parse error\n");
	for(i=0; i<data->count; i++)
	{
		if(data->acp[i]->hdr)
		{
			if(strLen(data->acp[i]->hdr->header))
				stringClean(&data->acp[i]->hdr->header);
			if(strLen(data->acp[i]->hdr->value))
				stringClean(&data->acp[i]->hdr->value);
			memPoolFree(header_info_pool, data->acp[i]->hdr);
			data->acp[i]->hdr = NULL;
		}
		if(data->acp[i])
		{
			memPoolFree(action_part_pool, data->acp[i]);
			data->acp[i] = NULL;
		}
	}
errA:
	if (data)
	{
		memPoolFree(mod_config_pool, data);
		data = NULL;
	}
	return -1;
}
static void parseCommand(uint8_t* line)
{
/* ======================== Action commands ========================  */
/**
<b>Action Commands</b> */
    if (line[0] == 'a')
    {
/**
<ul>
<li> <b>Snm</b> Manually set Switch. Follow by battery n (1-3, 0 = none) and
load m (0-1)/panel (2). Each two-bit field represents a load or panel, and the
setting is the battery to be connected (no two batteries can be connected to a
load/panel). */
        switch (line[1])
        {
        case 'S':
            {
                uint8_t battery = line[2]-'0';
                uint8_t setting = line[3]-'0'-1;
                if ((battery < 4) && (setting < 4)) setSwitch(battery, setting);
                if (setting == 2) setPanelSwitchSetting(battery);
                break;
            }
/**
<li> <b>Rn</b> Reset a tripped overcurrent circuit breaker.
Set a FreeRTOS timer to expire after 250ms at which time the reset line is
released. The command is followed by an interface number n=0-5 being batteries
1-3, loads 1-2 and module. */
        case 'R':
            {
                portTickType resetTime = 250;
                intf = line[2]-'0';
                if (intf > NUM_IFS-1) break;
                xTimerHandle resetHandle
                    = xTimerCreate("Reset",resetTime,pdFALSE,(void *)intf,resetCallback);
                if(resetHandle == NULL) break;
                if (xTimerStart(resetHandle,0) != pdPASS) break;
                overCurrentReset(intf);
                break;
            }
/**
<li> <b>W</b> Write the current configuration block to FLASH */
        case 'W':
            {
                writeConfigBlock();
                break;
            }
/**
<li> <b>E</b> Send an ident response */
        case 'E':
            {
                char ident[35] = "Battery Management System,";
                stringAppend(ident,FIRMWARE_VERSION);
                stringAppend(ident,",");
                char version[3];
                intToAscii(VERSION,version);
                stringAppend(ident,version);
                sendStringLowPriority("dE",ident);
                break;
            }
/**
<li> <b>B</b> Set the battery SoC from the measured OCV */
        case 'B':
            {
                uint8_t battery = line[2]-'1';
                setBatterySoC(battery,computeSoC(getBatteryVoltage(battery),
                           getTemperature(),getBatteryType(battery)));
                break;
            }
        }
    }
/**
</ul> */
/* ======================== Data request commands ================  */
/**
<b>Data Request Commands</b> */
    else if (line[0] == 'd')
    {
        switch (line[1])
        {
/**
<ul>
<li> <b>S</b> Ask for all switch settings to be sent as well as control
settings. */
        case 'S':
            {
                sendResponse("dS",(int)getSwitchControlBits());
                uint8_t controlByte = getControls();
                sendResponse("dD",controlByte);
                break;
            }
/**
<li> <b>Bn</b> Ask for battery n=1-3 parameters to be sent */
        case 'B':
            {
                char id[] = "pR0";
                id[2] = line[2];
                uint8_t battery = line[2] - '1';
                dataMessageSend(id,getBatteryResistanceAv(battery),0);
                id[1] = 'T';
                dataMessageSend(id,(int32_t)configData.config.batteryType[battery],
                                   (int32_t)configData.config.batteryCapacity[battery]);
                id[1] = 'F';
                dataMessageSend(id,(int32_t)configData.config.
                                            floatStageCurrentScale[battery],
                                   (int32_t)configData.config.floatVoltage[battery]);
                id[1] = 'A';
                dataMessageSend(id,(int32_t)configData.config.
                                            bulkCurrentLimitScale[battery],
                                   (int32_t)configData.config.absorptionVoltage[battery]);
                break;
            }
/**
<li> <b>T</b> Ask for monitor strategy parameters to be sent. */
        case 'T':
            {
                char id[] = "pts";
                dataMessageSend(id,(int32_t)configData.config.monitorStrategy,0);
                id[2] = 'V';
                dataMessageSend(id,(int32_t)configData.config.lowVoltage,
                                   (int32_t)configData.config.criticalVoltage);
                id[2] = 'S';
                dataMessageSend(id,(int32_t)configData.config.lowSoC,
                                   (int32_t)configData.config.criticalSoC);
                id[2] = 'F';
                dataMessageSend(id,(int32_t)configData.config.floatBulkSoC,0);
                break;
            }
/**
<li> <b>C</b> Ask for charger strategy parameters to be sent. */
        case 'C':
            {
                char id[] = "pcs";
                dataMessageSend(id,(int32_t)configData.config.chargerStrategy,0);
                id[2] = 'R';
                dataMessageSend(id,(int32_t)configData.config.restTime,
                                   (int32_t)configData.config.absorptionTime);
                id[2] = 'D';
                dataMessageSend(id,(int32_t)configData.config.minDutyCycle,0);
                id[2] = 'F';
                dataMessageSend(id,(int32_t)configData.config.floatTime,
                                   (int32_t)configData.config.floatBulkSoC);
                break;
            }
        }
    }
/**
</ul> */
/* ================ Parameter Setting commands ================  */
/**
<b>Parameter Setting Commands</b> */
    else if (line[0] == 'p')
    {
        uint8_t battery = line[2]-'1';
        switch (line[1])
        {
/**
<ul>
<li> <b>a-, a+</b> Turn autoTracking on or off */
        case 'a':
            {
                if (line[2] == '-') configData.config.autoTrack = false;
                else if (line[2] == '+') configData.config.autoTrack = true;
                break;
            }
/**
<li> <b>c-, c+</b> Turn communications sending on or off */
        case 'c':
            {
                if (line[2] == '-') configData.config.enableSend = false;
                else if (line[2] == '+') configData.config.enableSend = true;
                break;
            }
/**
<li> <b>C</b> Start a calibration sequence */
        case 'C':
            {
                startCalibration();
                break;
            }
/**
<li> <b>d-, d+</b> Turn on debug messages */
        case 'd':
            {
                if (line[2] == '+') configData.config.debugMessageSend = true;
                if (line[2] == '-') configData.config.debugMessageSend = false;
                break;
            }
/**
<li> <b>Hxxxx</b> Set time from an ISO 8601 formatted string. */
        case 'H':
            {
                setTimeFromString((char*)line+2);
                break;
            }
/**
<li> <b>M-, M+</b> Turn on/off data messaging (mainly for debug) */
        case 'M':
            {
                if (line[2] == '-') configData.config.measurementSend = false;
                else if (line[2] == '+') configData.config.measurementSend = true;
                break;
            }
/**
<li> <b>r-, r+</b> Turn recording on or off */
        case 'r':
            {
                if (line[2] == '-') configData.config.recording = false;
                else if ((line[2] == '+') && (writeFileHandle < 0x0FF))
                    configData.config.recording = true;
                break;
            }
/*--------------------*/
/* BATTERY parameters */
/**
<li> <b>Tntxx</b> Set battery type and capacity, n is battery, t is type,
xx is capacity */
        case 'T':
            {
                if (battery < 3)
                {
                    uint8_t type = line[3]-'0';
                    if (type < 3)
                    {
                        configData.config.batteryType[battery] =
                            (battery_Type)type;
                        configData.config.batteryCapacity[battery] =
                            asciiToInt((char*)line+4);
                        setBatteryChargeParameters(battery);
                    }
                }
                break;
            }
/**
<li> <b>m-, m+</b> Turn on/off battery missing */
        case 'm':
            {
                if (line[3] == '-') setBatteryMissing(battery,false);
                else if (line[3] == '+') setBatteryMissing(battery,true);
                break;
            }
/**
<li> <b>Inxx</b> Set bulk current limit, n is battery, xx is limit */
        case 'I':
            {
                if (battery < 3)
                    configData.config.bulkCurrentLimitScale[battery] =
                        asciiToInt((char*)line+3);
                break;
            }
/**
<li> <b>Anxx</b> Set battery gassing voltage limit, n is battery, xx is limit */
        case 'A':
            {
                if (battery < 3)
                    configData.config.absorptionVoltage[battery] =
                        asciiToInt((char*)line+3);
                break;
            }
/**
<li> <b>fnxx</b> Set battery float current trigger, n is battery, xx is trigger */
        case 'f':
            {
                if (battery < 3)
                    configData.config.floatStageCurrentScale[battery] =
                        asciiToInt((char*)line+3);
                break;
            }
/**
<li> <b>Fnxx</b> Set battery float voltage limit, n is battery, xx is limit */
        case 'F':
            {
                if (battery < 3)
                    configData.config.floatVoltage[battery] =
                        asciiToInt((char*)line+3);
                break;
            }
/**
<li> <b>zn</b> zero current calibration by forcing current offset, n is battery */
        case 'z':
            {
                if (battery < 3)
                    setCurrentOffset(battery,getCurrent(battery));
                break;
            }
/*--------------------*/
/* MONITOR parameters */
/**
<li> <b>sm</b> Set monitor strategy byte m for keeping isolation or avoiding
loading the battery under charge. */
        case 's':
            {
                uint8_t monitorStrategy = line[2]-'0';
                if (monitorStrategy <= 3)
                    configData.config.monitorStrategy = monitorStrategy;
                break;
            }
/**
<li> <b>vx</b> set low voltage threshold, x is voltage times 256. */
        case 'v':
            {
                configData.config.lowVoltage = asciiToInt((char*)line+2);
                break;
            }
/**
<li> <b>Vx</b> set critical voltage threshold, x is voltage times 256. */
        case 'V':
            {
                configData.config.criticalVoltage = asciiToInt((char*)line+2);
                break;
            }
/**
<li> <b>xx</b> set low SoC threshold, x is voltage times 256. */
        case 'x':
            {
                configData.config.lowSoC = asciiToInt((char*)line+2);
                break;
            }
/**
<li> <b>Xx</b> set critical SoC threshold, x is voltage times 256. */
        case 'X':
            {
                configData.config.criticalSoC = asciiToInt((char*)line+2);
                break;
            }
/*--------------------*/
/* CHARGER parameters */
/**
<li> <b>Sm</b> set charger strategy byte m. */
        case 'S':
            {
                uint8_t chargerStrategy = line[2]-'0';
                if (chargerStrategy < 2)
                    configData.config.chargerStrategy = chargerStrategy;
                break;
            }
/**
<li> <b>Rx</b> set charger algorithm minimum rest time x in seconds. */
        case 'R':
            {
                configData.config.restTime = asciiToInt((char*)line+2);
                break;
            }
/**
<li> <b>Ax</b> set charger algorithm minimum gassing phase time x in seconds. */
        case 'G':
            {
                configData.config.absorptionTime = asciiToInt((char*)line+2);
                break;
            }
/**
<li> <b>Dx</b> set charger minimum duty cycle x in seconds. */
        case 'D':
            {
                configData.config.minDutyCycle = asciiToInt((char*)line+2);
                break;
            }
/**
<li> <b>Fx</b> set charger time to float x in seconds. */
        case 'e':
            {
                configData.config.floatTime = asciiToInt((char*)line+2);
                break;
            }
/**
<li> <b>Bx</b> set charger SoC x to change from float to bulk phase. */
        case 'B':
            {
                configData.config.floatBulkSoC = asciiToInt((char*)line+2);
                break;
            }
        }
    }
/**
</ul> */

/* ======================== File commands ================ */
/*
F           - get free clusters
Wfilename   - Open file for read/write. Filename is 8.3 string style. Returns handle.
Rfilename   - Open file read only. Filename is 8.3 string style. Returns handle.
Xfilename   - Delete the file. Filename is 8.3 string style.
Cxx         - Close file. x is the file handle.
Gxx         - Read a record from read or write file.
Ddirname    - Get a directory listing. Directory name is 8.3 string style.
d[dirname]  - Get the first (if dirname present) or next entry in directory.
s           - Get status of open files and configData.config.recording flag
M           - Mount the SD card.
All commands return an error status byte at the end.
Only one file for writing and a second for reading is possible.
Data is not written to the file externally. */
/**
<b>File Commands</b> */
    else if (line[0] == 'f')
    {
        switch (line[1])
        {
/**
<ul>
<li> <b>F</b> Return number of free clusters followed by the cluster size in bytes. */
            case 'F':
            {
                uint8_t wordBuf;
                uint32_t freeClusters = 0;
                uint32_t sectorCluster = 0;
                uint8_t fileStatus = FR_INT_ERR;
                if (xSemaphoreTake(fileSendSemaphore,COMMS_FILE_TIMEOUT))
                {
                    sendFileCommand('F',0,line+2);
                    uint8_t i;
                    for (i=0; i<4; i++)
                    {
                        wordBuf = 0;
                        xQueueReceive(fileReceiveQueue,&wordBuf,portMAX_DELAY);
                        freeClusters |= (wordBuf << 8*i);
                    }
                    for (i=0; i<4; i++)
                    {
                        wordBuf = 0;
                        xQueueReceive(fileReceiveQueue,&wordBuf,portMAX_DELAY);
                        sectorCluster |= (wordBuf << 8*i);
                    }
                    dataMessageSend("fF",freeClusters,sectorCluster);
                    xQueueReceive(fileReceiveQueue,&fileStatus,portMAX_DELAY);
                    xSemaphoreGive(fileSendSemaphore);
                }
                sendResponse("fE",(uint8_t)fileStatus);
                break;
            }
/**
<li> <b>Wf</b> Open a file f=filename for writing */
            case 'W':
            {
                if (stringLength((char*)line+2) < 12)
                {
                    uint8_t fileStatus = FR_INT_ERR;
                    if (xSemaphoreTake(fileSendSemaphore,COMMS_FILE_TIMEOUT))
                    {
                        stringCopy(writeFileName,(char*)line+2);
                        sendFileCommand('W',13,line+2);
                        xQueueReceive(fileReceiveQueue,&writeFileHandle,portMAX_DELAY);
                        sendResponse("fW",writeFileHandle);
                        xQueueReceive(fileReceiveQueue,&fileStatus,portMAX_DELAY);
                        xSemaphoreGive(fileSendSemaphore);
                    }
                    sendResponse("fE",(uint8_t)fileStatus);
                }
                break;
            }
/**
<li> <b>Rf</b> Open a file f=filename for Reading */
            case 'R':
            {
                if (stringLength((char*)line+2) < 12)
                {
                    uint8_t fileStatus = FR_INT_ERR;
                    if (xSemaphoreTake(fileSendSemaphore,COMMS_FILE_TIMEOUT))
                    {
                        stringCopy(readFileName,(char*)line+2);
                        sendFileCommand('R',13,line+2);
                        xQueueReceive(fileReceiveQueue,&readFileHandle,portMAX_DELAY);
                        sendResponse("fR",readFileHandle);
                        xQueueReceive(fileReceiveQueue,&fileStatus,portMAX_DELAY);
                        xSemaphoreGive(fileSendSemaphore);
                    }
                    sendResponse("fE",(uint8_t)fileStatus);
                }
                break;
            }
/**
<li> <b>Ghh</b> hh is the file handle. Close file for write or read file. The
file handle is a two character integer. */
            case 'C':
            {
                uint8_t fileStatus = FR_INT_ERR;
                if (xSemaphoreTake(fileSendSemaphore,COMMS_FILE_TIMEOUT))
                {
                    uint8_t fileHandle = asciiToInt((char*)line+2);
                    sendFileCommand('C',1,&fileHandle);
                    xQueueReceive(fileReceiveQueue,&fileStatus,portMAX_DELAY);
                    if (fileStatus == FR_OK)
                    {
                        if (writeFileHandle == fileHandle)
                        {
                            writeFileHandle = 0xFF;
                            writeFileName[0] = 0;
                        }
                        else if (readFileHandle == fileHandle)
                        {
                            readFileHandle = 0xFF;
                            readFileName[0] = 0;
                        }
                    }
                    xSemaphoreGive(fileSendSemaphore);
                }
                sendResponse("fE",(uint8_t)fileStatus);
                break;
            }
/**
<li> <b>Ghh</b> hh is the file handle. Read a record of data from the read or
write file. The data starts from the end of the previous block that was read
(or the file start if just opened). The file handle is a two character integer.
A block of bytes is read from the file and stored in a circular buffer. A record
is taken from this block and sent, the rest remains in the buffer until the next
request. */
#define GET_RECORD_SIZE 80
            case 'G':
            {
                uint8_t fileStatus = FR_INT_ERR;
                if (xSemaphoreTake(fileSendSemaphore,COMMS_FILE_TIMEOUT))
                {
                    int numberRecords = asciiToInt((char*)line+2);
                    if (numberRecords < 1) numberRecords = 1;
                    static FRESULT fileStatus = FR_OK;
                    static uint8_t buffer[GET_RECORD_SIZE];
                    static uint8_t readPointer = 0;
                    static uint8_t writePointer = 0;
                    char sendData[GET_RECORD_SIZE];
                    uint8_t sendPointer = 0;
                    uint8_t fileHandle = asciiToInt((char*)line+2);
                    uint8_t blockLength = GET_RECORD_SIZE-1;
                    uint8_t numRead;
                    uint8_t parameters[2] = {fileHandle, blockLength};
                    while (numberRecords > 0)
                    {
/* The buffer is empty, so fill up. */
                        if (readPointer == writePointer)
                        {
                            sendFileCommand('G',2,parameters);
                            numRead = 0;
                            xQueueReceive(fileReceiveQueue,&numRead,portMAX_DELAY);
/* As records are written in entirety, premature EOF should not happen. */
                            if (numRead != blockLength)
                            {
                                fileStatus = FR_DENIED;
                                break;
                            }
                            uint8_t i;
/* Read the entire block to the local buffer. */
                            for (i=0; i<numRead; i++)
                            {
                                uint8_t nextWritePointer = (writePointer+1)
                                                % GET_RECORD_SIZE;
                                xQueueReceive(fileReceiveQueue,
                                    buffer+writePointer,portMAX_DELAY);
                                writePointer = nextWritePointer;
                            }
/* Get status byte. */
                            xQueueReceive(fileReceiveQueue,&fileStatus,portMAX_DELAY);
                        }
/* Assemble the data message until EOL encountered, or block exhausted. */
                        while (sendPointer < GET_RECORD_SIZE-1)
                        {
                            sendData[sendPointer] = buffer[readPointer];
                            readPointer = (readPointer+1) % GET_RECORD_SIZE;
                            if (sendData[sendPointer] == '\n')
                            {
                                sendData[sendPointer+1] = 0;
                                sendString("fG",sendData);
                                sendPointer = 0;
                                numberRecords--;
                                break;
                            }
/* If the current block is exhausted, go get some more. */
                            if (readPointer == writePointer) break;
                            sendPointer++;
                        }
                    }
                    xSemaphoreGive(fileSendSemaphore);
                }
/* Status sent is from the last time the file was read. */
                sendResponse("fE",(uint8_t)fileStatus);
                break;
            }
/**
<li> <b>Dd</b> Get a directory listing d=dirname. Directory name is 8.3 string
style. Gets all items in the directory and sends the type,size and name, each
group preceded by a comma. The file command requests each entry in turn,
terminated by a null filename when the directory listing is exhausted. */
            case 'D':
            {
                if (! xSemaphoreTake(commsSendSemaphore,COMMS_SEND_TIMEOUT))
                    break;
                uint8_t fileStatus = FR_INT_ERR;
                if (xSemaphoreTake(fileSendSemaphore,COMMS_FILE_TIMEOUT))
                {
                    char firstCharacter;
                    sendFileCommand('D',13,line+2);
                    commsPrintString("fD");
                    do
                    {
                        char type = 0;
/* Single character entry type */
                        xQueueReceive(fileReceiveQueue,&type,portMAX_DELAY);
                        char character;
/* Four bytes of file size */
                        uint32_t fileSize = 0;
                        uint8_t i;
                        for (i=0; i<4; i++)
                        {
                            character = 0;
                            xQueueReceive(fileReceiveQueue,&character,portMAX_DELAY);
                            fileSize = (fileSize << 8) + character;
                        }
/* Filename. If the first character of name is zero then the listing is ended */
                        character = 0;
                        xQueueReceive(fileReceiveQueue,&character,portMAX_DELAY);
                        firstCharacter = character;
                        if (firstCharacter > 0)
                        {
                            commsPrintString(",");
                            commsPrintChar(&type);
                            commsPrintHex(fileSize >> 16);
                            commsPrintHex(fileSize & 0xFFFF);
                            while (character > 0)
                            {
                                commsPrintChar(&character);
                                character = 0;
                                xQueueReceive(fileReceiveQueue,&character,portMAX_DELAY);
                            }
/* End of directory entry. Discard the status byte */
                            xQueueReceive(fileReceiveQueue,&fileStatus,portMAX_DELAY);
                            uint8_t eol = 0;
/* Send a zero parameter to ask for the next entry */
                            sendFileCommand('D',1,&eol);
                        }
                    }
                    while (firstCharacter > 0);
                    commsPrintString("\r\n");
                    xQueueReceive(fileReceiveQueue,&fileStatus,portMAX_DELAY);
                    xSemaphoreGive(fileSendSemaphore);
                }
                xSemaphoreGive(commsSendSemaphore);
                sendResponse("fE",(uint8_t)fileStatus);
                break;
            }
/**
<li> <b>d[d]</b> d is the d=directory name. Get the first (if d present) or next
entry in the directory. If the name has a zero in the first position, return the
next entry in the directory listing. Returns the type, size and name preceded by
a comma for compatibility with the full directory listing request. If there are
no further entries found in the directory, then an empty string is sent back. */
            case 'd':
            {
                if (! xSemaphoreTake(commsSendSemaphore,COMMS_SEND_TIMEOUT))
                    break;
                uint8_t fileStatus = FR_INT_ERR;
                if (xSemaphoreTake(fileSendSemaphore,COMMS_FILE_TIMEOUT))
                {
                    sendFileCommand('D',13,line+2);
                    commsPrintString("fd");
                    char type = 0;
/* Single character entry type */
                    xQueueReceive(fileReceiveQueue,&type,portMAX_DELAY);
                    char character;
/* Four bytes of file size */
                    uint32_t fileSize = 0;
                    uint8_t i;
                    for (i=0; i<4; i++)
                    {
                        character = 0;
                        xQueueReceive(fileReceiveQueue,&character,portMAX_DELAY);
                        fileSize = (fileSize << 8) + character;
                    }
/* Filename. If the first character of name is zero then the listing is ended */
                    character = 0;
                    xQueueReceive(fileReceiveQueue,&character,portMAX_DELAY);
                    if (character > 0)  /* Pull in remaining characters of name */
                    {
                        commsPrintString(",");
                        commsPrintChar(&type);
                        commsPrintHex(fileSize >> 16);
                        commsPrintHex(fileSize & 0xFFFF);
                        while (character > 0)
                        {
                            commsPrintChar(&character);
                            character = 0;
                            xQueueReceive(fileReceiveQueue,&character,portMAX_DELAY);
                        }
                    }
                    commsPrintString("\r\n");
                    xQueueReceive(fileReceiveQueue,&fileStatus,portMAX_DELAY);
                    xSemaphoreGive(fileSendSemaphore);
                }
                xSemaphoreGive(commsSendSemaphore);
                sendResponse("fE",(uint8_t)fileStatus);
                break;
            }
/**
<li> <b>M</b> Register (mount or remount) the SD card. */
            case 'M':
            {
                uint8_t fileStatus = FR_INT_ERR;
                if (xSemaphoreTake(fileSendSemaphore,COMMS_FILE_TIMEOUT))
                {
                    sendFileCommand('M',0,line+2);
                    xQueueReceive(fileReceiveQueue,&fileStatus,portMAX_DELAY);
                    xSemaphoreGive(fileSendSemaphore);
                }
                sendResponse("fE",(uint8_t)fileStatus);
                break;
            }
/**
<li> <b>s</b> Send a status message containing: software switches
(configData.config.recording), names of open files, with open write filename
first followed by read filename, or blank if files are not open. */
            case 's':
            {
                if (! xSemaphoreTake(commsSendSemaphore,COMMS_SEND_TIMEOUT))
                    break;;
                commsPrintString("fs,");
                commsPrintInt((int)getControls());
                commsPrintString(",");
                uint8_t writeStatus;
                commsPrintInt(writeFileHandle);
                commsPrintString(",");
                if (writeFileHandle < 0xFF)
                {
                    commsPrintString(writeFileName);
                    commsPrintString(",");
                }
                commsPrintInt(readFileHandle);
                if (readFileHandle < 0xFF)
                {
                    commsPrintString(",");
                    commsPrintString(readFileName);
                }
                commsPrintString("\r\n");
                xSemaphoreGive(commsSendSemaphore);
                break;
            }
/**
<li> <b>Xf</b> Delete a designated file f=filename. The file must not be open at
the time. A status is returned to signal a directory refresh. */
            case 'X':
            {
                uint8_t fileStatus = FR_INT_ERR;
                if (xSemaphoreTake(fileSendSemaphore,COMMS_FILE_TIMEOUT))
                {
                    sendFileCommand('X',13,line+2);
                    xQueueReceive(fileReceiveQueue,&fileStatus,portMAX_DELAY);
                    xSemaphoreGive(fileSendSemaphore);
                }
                sendResponse("fE",(uint8_t)fileStatus);
                break;
            }
/**
</ul> */
        }
    }
void parseArgs(VersionUpdateConfig *config, int argc, char *args[]) {

	if(argc < 4) {
		fprintf(stderr, "USAGE:%s\n", USAGE);
		exit(3);
	}

	if(debug) {
		int i = 0;
		for(i = 0; i < argc; i++) {
			fprintf(stdout, "param $%d == %s\n", i, args[i]);
		}
	}

	char *URL = args[1];
	char *path = args[2];
	int   intervalSecond = atoi(args[3]);
	char *lockURL = args[4];

	if(argc > 5) {
		debug = atoi(args[5]);
	}
	//global var
	size_t URLLen = strlen(URL);
	size_t pathLen = strlen(path);
	
	if(!parseLockUrl(lockURL, config)){
		exit(1);
	}
	
	//interval time
	config->intervalSecond = intervalSecond;
	//url
	buffer *URLDomain = buffer_init_size(URLLen + 1);
	stringAppend(URLDomain, URL, URLLen);
	config->URLDomain = URLDomain;
	debug_buffer(URLDomain, "URLDomain");
	
	//dir
	buffer *versionFileDir = buffer_init_size(pathLen + 1);
	char *lastChar = strrchr(path, '/');
	if(NULL == lastChar) {
		fprintf(stderr, "USAGE:%s\n", USAGE);
		exit(5);
	}
	stringAppend(versionFileDir, path, pathLen - strlen(lastChar));
	config->versionFileDir = versionFileDir;
	struct stat st;
	if (-1 == stat(versionFileDir->ptr, &st)) {
		//mkdir
		mkdir_recursive(versionFileDir->ptr);
		debug_buffer(versionFileDir, "mkdir_recursive make done....");
	}
	debug_buffer(versionFileDir, "versionFileDir");
	//source
	buffer *versionFilePath = buffer_init_size(pathLen + 1);
	stringAppend(versionFilePath, path, pathLen);
	config->versionFilePath = versionFilePath;
	debug_buffer(versionFilePath, "versionFilePath");
	//expect
	buffer *expectVersionFilePath = buffer_init_size(versionFilePath->size);
	stringAppend(expectVersionFilePath, path, pathLen - 3); //--clean .gz
	config->expectVersionFilePath = expectVersionFilePath;
	debug_buffer(expectVersionFilePath, "expectVersionFilePath");
	//response
	buffer *reponseFilePath = buffer_init_size(versionFilePath->size + REPONSE_LOG_LEN);
	stringAppend(reponseFilePath, expectVersionFilePath->ptr, expectVersionFilePath->used);
	stringAppend(reponseFilePath, REPONSE_LOG, REPONSE_LOG_LEN);
	config->reponseFilePath = reponseFilePath;
	debug_buffer(reponseFilePath, "reponseFilePath");
	//tmp
	buffer *tmpVersionFilePath = buffer_init_size(versionFilePath->size + TMP_LEN);
	stringAppend(tmpVersionFilePath, versionFilePath->ptr, versionFilePath->used);
	stringAppend(tmpVersionFilePath, TMP, TMP_LEN);
	config->tmpVersionFilePath = tmpVersionFilePath;
	debug_buffer(tmpVersionFilePath, "tmpVersionFilePath");
}
void intervalWork(VersionUpdateConfig *config) {

	if(debug) {
		fprintf(stdout, "start intervalWork\n");
	}
	//clean old responsefile
	remove(config->reponseFilePath->ptr);

	buffer *lastModifiedTime = NULL;

	int paramLen = config->URLDomain->used + config->tmpVersionFilePath->used + config->reponseFilePath->used;
	buffer *param = buffer_init_size(20 + paramLen);
	stringAppend(param, " ", 1);
	stringAppend(param, config->URLDomain->ptr, config->URLDomain->used);
	stringAppend(param, " -O ", 4);
	stringAppend(param, config->tmpVersionFilePath->ptr, config->tmpVersionFilePath->used);
	stringAppend(param, " > ", 3);
	stringAppend(param, config->reponseFilePath->ptr, config->reponseFilePath->used);
	stringAppend(param, " 2>&1 ", 6);

	while(1) {
		char *responseCnt = readResponse(config->reponseFilePath->ptr);
		int httpStatus = getHttpStatus(responseCnt);
		if(debug) {
			fprintf(stdout, "httpStatus:%d\n", httpStatus);
		}
		// ignore the lock checke for the first version file request
		if(0 != httpStatus && 404 != httpStatus) {
			int bLocked = checkLockStatus(config->lockRequestURL->ptr);
			if(bLocked){
				sleep(config->intervalSecond);
				continue;
			}
		}
		if(304 != httpStatus) {
			getLastModified(responseCnt, &lastModifiedTime);
		}
		debug_buffer(lastModifiedTime, "lastModifiedTime");
		
		//thread interval exec
		buffer *cmdBuf = buffer_init_size(LAST_MODIFIED_LEN + WGET_CMD_LEN + HEADER_LEN + param->used);
		stringAppend(cmdBuf, WGET_CMD, WGET_CMD_LEN);
		if(NULL != lastModifiedTime) {
			stringAppend(cmdBuf, HEADER, HEADER_LEN);
			stringAppend(cmdBuf, lastModifiedTime->ptr, lastModifiedTime->used);
			stringAppend(cmdBuf, "\"", 1);
		}
		stringAppend(cmdBuf, param->ptr, param->used);
		debug_buffer(cmdBuf, "cmdBuf");

		if(-1 == system(cmdBuf->ptr)) {
			fprintf(stderr, "system (wget...) error:%s\n", cmdBuf->ptr);
			exit(4);
		}

		free(responseCnt);
		buffer_free(cmdBuf);

		checkAndGzip(config->tmpVersionFilePath, config->versionFilePath,
					config->expectVersionFilePath, config->reponseFilePath);

		sleep(config->intervalSecond);
	}
}
Beispiel #23
0
/* Reset a string to an empty string */
static void stringReset(String *p){
  if( p->z==0 ) stringAppend(p, " ", 1);
  p->n = 0;
  p->z[0] = 0;
}