Exemple #1
0
/*
 * Reads an HTTP request from stream (fd), and writes an HTTP response
 * containing:
 *
 *   1) If user requested an existing file, respond with the file
 *   2) If user requested a directory and index.html exists in the directory,
 *      send the index.html file.
 *   3) If user requested a directory and index.html doesn't exist, send a list
 *      of files in the directory with links to each.
 *   4) Send a 404 Not Found response.
 */
void handle_files_request(int fd) {
  struct http_request*request=http_request_parse(fd);
  char*fullpath,*fullfullpath;
  struct stat st;
  
  if(0==strcmp("GET",request->method)){
    fullpath=conc(server_files_directory,request->path);
    if(0==stat(fullpath,&st)){ // file/dir exists
      if(S_ISREG(st.st_mode)){ // is file
	http_send_file(fd,fullpath);
      }else if(S_ISDIR(st.st_mode)){ // is dir
	fullfullpath=conc(fullpath,"/index.html");
	if(0==stat(fullfullpath,&st)){ // has an index.html
	  http_send_file(fd,fullfullpath);
	}else{ // hasnt. list files
	  DIR*d=opendir(fullpath);
	  struct dirent*di;
	  http_start_response(fd,200);
	  http_send_header(fd,"Content-type","text/html");
	  http_end_headers(fd);
	  while(NULL!=(di=readdir(d)))
	    http_send_anchor(fd,di->d_name);
	}
	free(fullfullpath);
      }
    }else{ // doesnt exist. error 404
      http_start_response(fd,404);
      http_send_header(fd,"Content-type","text/html");
      http_end_headers(fd);
      http_send_string(fd,"<center><p>ERROR 404</p></center>");
    }
    free(fullpath);
  }
}
Exemple #2
0
int cwmp_agent_upload_file(upload_arg_t * ularg)
{
    int faultcode = 0;
    FUNCTION_TRACE();
    char * fromfile;

	if(strcpy(ularg->filetype, "1 Vendor Configuration File") == 0)
	{
		//根据实际情况, 修改这里的配置文件路径
		
		fromfile = "/tmp/mysystem.cfg";
	}
	else if(strcpy(ularg->filetype, "2 Vendor Log File") == 0)
	{
		//根据实际情况, 修改这里的配置文件路径
		fromfile = "/tmp/mysystem.log";
	}
	else
	{
		fromfile = "/tmp/mysystem.cfg";
	}
	
    faultcode = http_send_file(fromfile, ularg->url);

    if(faultcode != CWMP_OK)
    {
	faultcode = 9001;
    }
   


    return faultcode;
}
Exemple #3
0
void http_thread_work(void *arg)
{
    struct http_job *job = arg;
    struct stat st;

    if (stat(job->filepath, &st) == -1){
        http_not_found(job->fd);
        return;
    }

    if (S_ISDIR(st.st_mode)){
        http_show_dir(job->fd, job->filepath);
    }
    
    if (S_ISREG(st.st_mode)){
        http_send_file(job->fd, job->filepath);
    } 

    if (strcasecmp(walkerconf[THREADNUMBER].value, "0")!=0)
        close(job->fd);


    free(job);
    return ;

}
Exemple #4
0
DWORD WINAPI http_do_request(void *lPtr)
{
	socket_conn* conn = (socket_conn*)lPtr;
	if(conn == 0)
		return 0;

	printf("[%08x]new connection\n", GetCurrentThreadId());
	while(1)
	{
		int keepalive = 0;
		dynamic_object * req = dynamic_create();
		if(http_read_request(conn, req) == 0)
		{
			dynamic_delete(req);
			break;
		}
		char* path = dynamic_get_string(dynamic_map_find(req, "PATH"));
		char* method = dynamic_get_string(dynamic_map_find(req, "METHOD"));
		char* connection = dynamic_get_string(dynamic_map_find(req, HTTP_HEADER_CONNECTION));
		if(connection && strcmp(connection, "keep-alive")==0)
			keepalive = 1;
		printf("[%08x]%s %s\n", GetCurrentThreadId(), method, path);

		if(strcmp(path, "/hello") == 0)
		{
			char* html = "<html><body>Hello World!</body></html>";
			int htmllen = strlen(html);
			dynamic_object * res = dynamic_create();
			dynamic_string_printf(dynamic_map_insert(res, HTTP_HEADER_CONTENT_LENGTH), "%d", htmllen);
			dynamic_set_string(dynamic_map_insert(res, HTTP_HEADER_CONTENT_TYPE), "text/html");

			http_send_response(conn, 200, res);
			write_socket(conn, html, htmllen, -1);
			dynamic_delete(res);
		}else
		{
			http_send_file(conn, req);
		}
		dynamic_delete(req);
		if(keepalive == 0)
			break;
	}

	close_socket(conn);
	printf("[%08x]close connection\n", GetCurrentThreadId());
	return 0;
}
Exemple #5
0
void serve(int sockfd)
{
	char buf[BUF_LEN];
	read(sockfd, buf, BUF_LEN);
	if(!strncmp(buf, "GET", 3))
	{
		char *file = buf+5;
		char *space = strchr(file, ' ');
		*space = '\0';
		http_send_file(file, sockfd);
	}
	else
	{
		printf("unsupported request\n");
		return;
	}
}
Exemple #6
0
/* Called by: */
int http_decode(struct hi_thr* hit, struct hi_io* io)
{
  struct hi_pdu* req = io->cur_pdu;
  char* url;
  char* url_lim = 0;
  char* p = req->m;
  int n = req->ap - p;
  
  if (n < HTTP_MIN_PDU_SIZE) {   /* too little, need more */
    req->need = HTTP_MIN_PDU_SIZE - n;
    return 0;
  }
  
  if (memcmp(p, "GET /", sizeof("GET /")-1)) {
    ERR("Not a GET HTTP PDU. fd(%x). Got(%.*s)", io->fd, HTTP_MIN_PDU_SIZE, req->m);
    return HI_CONN_CLOSE;
  }

  for (p += 5; p < req->ap - (sizeof(" HTTP/1.0")-2); ++p)
    if (!memcmp(p, " HTTP/1.0\n", sizeof(" HTTP/1.0")-1)) {
      /* Found end of URL */
      url = req->m + 4;
      url_lim = p;
      break;
    }
  
  if (!url_lim) {
    req->need = 1;
    return 0;
  }
  /* *** Proper processing of content-length and setting need to length of PDU is still needed. */
  D("need=%d len=%d buf(%.*s)", req->need, (int)(req->ap-req->m), (int)(req->ap-req->m), req->m);

  hi_add_to_reqs(hit, io, req, HTTP_MIN_PDU_SIZE);

  /* 01234567890
   * GET / HTTP/1.0 */
  switch (req->m[6]) {
  case 'a': http_send_data(hit, io, req, url_lim-url, url); break;
  case 'b': http_send_file(hit, io, req, url_lim-url, url); break;  /* *** */
  default:  http_send_err(hit, io, req, 500, "Error"); break;
  }
  return HI_CONN_CLOSE; /* HTTP/1.0 without keep-alive: close connection after every req-resp */
}
Exemple #7
0
void APISelect(void *data)
{
    OPS("### @ API : Accept Success - Thread[%d]", pthread_self());
    // struct data
    qqclient* qq = ((void**)data)[0];
    qq->api_select_count ++ ;
    apiclient* apis = ((void**)data)[1];
    int client = apis->sock;
    pthread_mutex_unlock(&apis->mxsock);
    // Request
    char *buffer;
    NEW(buffer, REQUEST_BUFFER);
    // Select 模型读取请求
    fd_set fdRead;
    struct timeval fdRTV = {1, 0};

    FD_ZERO(&fdRead);
    FD_SET(client, &fdRead);
    switch ( select(client, &fdRead, NULL, NULL, &fdRTV) )
    {
        default:
        if ( FD_ISSET(client, &fdRead) )
        {
            recv(client, buffer, REQUEST_BUFFER, 0);
        }
    }

    if ( strlen(buffer) < 9 )
    {
        OPS("### @ API : Request Unavailable.");
        DEL(buffer);
        return;
    }

    // Request Test
    DBG("##### Request Begin #####\n%s\n##### Request End #####\n", buffer);

    char *http;
    NEW(http, 16);
    mid_value(buffer, "GET ", " HTTP/1.1", http, 16);
    if ( strstr(http, "/v?") >0 )
    {
        // 验证码读取
        char *uid, *file;
        NEW(uid, 18);
        NEW(file, 32);
        if ( strstr(http, "&") > 0 )
        {
            mid_value(http, "/v?", "&", uid, 18);
        }
        else
        {
            mid_value(http, "/v?", NULL, uid, 18);
        }
        sprintf(file, "./verify/%s.png", uid);
        http_send_file(client, file);
        DEL(uid);
        DEL(file);
        DEL(http);
        DEL(buffer);
        return;
    }
    else if ( strstr(http, "/send?") > 0 )
    {
        // 发送自定义信息
        char *msg;
        NEW(msg, REQUEST_BUFFER);
        mid_value(buffer, "GET /send?", " HTTP/1.1", msg, REQUEST_BUFFER);
        api_callback_build("http.send", msg);
        DEL(msg);
        http_send(client, "Message Sends OK.");
        DEL(http);
        DEL(buffer);
        return;
    }
    else if ( strlen(http) > 0 )
    {
        http_send(client, "QQRobot API Server.");
        DEL(http);
        DEL(buffer);
        return;
    }
    DEL(http);

    char *api;
    NEW(api, API_BUFFER);
    mid_value(buffer, "API ", " MOYO/1.1", api, API_BUFFER);
    if (strlen(api) == 0)
    {
        http_send(client, "API IS EMPTY");
        DEL(api);
        DEL(buffer);
        return;
    }

    // API Commands
    char *response;
    NEW(response, RESPONSE_BUFFER);
    // Check SecKey
    char *seckey;
    NEW(seckey, 255);
    mid_value(buffer, "<seckey>", "</seckey>", seckey, 255);
    if ( strcmp(apis->APISeckey, seckey)!=0 )
    {
        strcat(response, "ACCESS DENIED");
        OPS("### @ API : Denied of : %s", api);
        DEL(seckey);
        goto API_RESPONSE;
    }
    DEL(seckey);
    // API Runs
    OPS("### @ API : Command of : %s ...Runs ...", api);
    // ##### API of login #####
    if ( stricmp(api, "login.create")==0 )
    {
        char *uid, *password;
        NEW(uid, 10);
        NEW(password, 32);
        mid_value(buffer, "<uid>", "</uid>", uid, 10);
        mid_value(buffer, "<password>", "</password>", password, 32);
        strcat(response, myqq_login(atoi(uid), password));
        //printf("Done of %s.\n", api);
        DEL(uid);
        DEL(password);
    }
    else if ( stricmp(api, "login.destroy")==0 )
    {
        strcat(response, myqq_logout());
        //printf("Done of %s.\n", api);
    }
    else if ( stricmp(api, "login.verify")==0 )
    {
        char *vcode;
        NEW(vcode, 4);
        mid_value(buffer, "<verify>", "</verify>", vcode, 4);
        if ( qq->process == P_VERIFYING )
        {
            qqclient_verify(qq, vcode);
            OPS("### @ API : [Input] Verify Code : %s", vcode);
            strcat(response, myqq_resume_login());
        }
        else
        {
            strcat(response, "DONT NEED");
        }
        //printf("Done of %s.\n", api);
        DEL(vcode);
    }
    else if ( stricmp(api, "login.check")==0 )
    {
        strcat(response, myqq_check_login(qq));
        //printf("Done of %s.\n", api);
    }
    // ##### API of buddy #####
    else if ( stricmp(api, "buddy.name")==0 )
    {
        char *uid;
        NEW(uid, 10);
        mid_value(buffer, "<uid>", "</uid>", uid, 10);
        strcat(response, myqq_get_buddy_name(qq, atoi(uid)));
        //printf("Done of %s.\n", api);
        DEL(uid);
    }
    else if ( stricmp(api, "buddy.send")==0 )
    {
        char *uid, *message;
        NEW(uid, 10);
        NEW(message, SEND_MESSAGE_SIZE);
        mid_value(buffer, "<uid>", "</uid>", uid, 10);
        mid_value(buffer, "<message>", "</message>", message, SEND_MESSAGE_SIZE);
        if ( myqq_send_im_to_buddy(qq, atoi(uid), message, 0) )
        {
            strcat(response, "SEND FAILED");
        }
        else
        {
            strcat(response, "SEND SUCCESS");
        }
        //printf("Done of %s.\n", api);
        DEL(uid);
        DEL(message);
    }
    else if ( stricmp(api, "buddy.info")==0 )
    {
        char *uid;
        NEW(uid, 10);
        mid_value(buffer, "<uid>", "</uid>", uid, 10);
        char *info;
        NEW(info, KB(4));
        myqq_get_buddy_info(qq, atoi(uid), info, KB(4));
        strcat(response, info);
        //printf("Done of %s.\n", api);
        DEL(uid);
        DEL(info);
    }
    else if ( stricmp(api, "buddy.list")==0 )
    {
        char *online;
        NEW(online, 3);
        mid_value(buffer, "<online>", "</online>", online, 3);
        char *info;
        NEW(info, BUDDY_BUF_SIZE);
        if ( stricmp(online, "yes")==0 )
        {
            myqq_get_buddy_list(qq, info, BUDDY_BUF_SIZE, 1);
        }
        else
        {
            myqq_get_buddy_list(qq, info, BUDDY_BUF_SIZE, 0);
        }
        strcat(response, info);
        //printf("Done of %s.\n", api);
        DEL(online);
        DEL(info);
    }
    // ##### API of qun #####
    else if ( stricmp(api, "qun.name")==0 )
    {
        char *gid;
        NEW(gid, 10);
        mid_value(buffer, "<gid>", "</gid>", gid, 10);
        strcat(response, myqq_get_qun_name(qq, atoi(gid)));
        //printf("Done of %s.\n", api);
        DEL(gid);
    }
    else if ( stricmp(api, "qun.send")==0 )
    {
        char *gid, *message;
        NEW(gid, 10);
        NEW(message, SEND_MESSAGE_SIZE);
        mid_value(buffer, "<gid>", "</gid>", gid, 10);
        mid_value(buffer, "<message>", "</message>", message, SEND_MESSAGE_SIZE);
        if ( myqq_send_im_to_qun(qq, atoi(gid), message, 0) )
        {
            strcat(response, "SEND FAILED");
        }
        else
        {
            strcat(response, "SEND SUCCESS");
        }
        //printf("Done of %s.\n", api);
        DEL(gid);
        DEL(message);
    }
    else if ( stricmp(api, "qun.buddy.name")==0 )
    {
        char *gid, *uid;
        NEW(gid, 10);
        NEW(uid, 10);
        mid_value(buffer, "<gid>", "</gid>", gid, 10);
        mid_value(buffer, "<uid>", "</uid>", uid, 10);
        strcat(response, myqq_get_qun_member_name(qq, atoi(gid), atoi(uid)));
        //printf("Done of %s.\n", api);
        DEL(gid);
        DEL(uid);
    }
    else if ( stricmp(api, "qun.info")==0 )
    {
        char *gid;
        NEW(gid, 10);
        mid_value(buffer, "<gid>", "</gid>", gid, 10);
        char *info;
        NEW(info, KB(4));
        myqq_get_qun_info(qq, atoi(gid), info, KB(4));
        strcat(response, info);
        //printf("Done of %s.\n", api);
        DEL(gid);
        DEL(info);
    }
    else if ( stricmp(api, "qun.list")==0 )
    {
        char *info;
        NEW(info, QUN_BUF_SIZE);
        myqq_get_qun_list(qq, info, QUN_BUF_SIZE);
        strcat(response, info);
        //printf("Done of %s.\n", api);
        DEL(info);
    }
    else if ( stricmp(api, "qun.buddy.list")==0 )
    {
        char *gid, *online;
        NEW(gid, 10);
        NEW(online, 3);
        mid_value(buffer, "<gid>", "</gid>", gid, 10);
        mid_value(buffer, "<online>", "</online>", online, 3);
        char *info;
        NEW(info, BUDDY_BUF_SIZE);
        if ( stricmp(online, "yes")==0 )
        {
            myqq_get_qun_member_list(qq, atoi(gid), info, BUDDY_BUF_SIZE, 1);
        }
        else
        {
            myqq_get_qun_member_list(qq, atoi(gid), info, BUDDY_BUF_SIZE, 0);
        }
        strcat(response, info);
        //printf("Done of %s.\n", api);
        DEL(gid);
        DEL(online);
        DEL(info);
    }
    // ##### API of me #####
    else if ( stricmp(api, "me.sleep")==0 )
    {
        char *power;
        NEW(power, 3);
        mid_value(buffer, "<power>", "</power>", power, 3);
        if ( strcmp(power, "on")==0 )
        {
            apis->APISleep = 1;
        }
        else
        {
            apis->APISleep = 0;
        }
        strcat(response, "SWITCH SUCCESS");
        //printf("Done of %s.\n", api);
        DEL(power);
    }
    else if ( stricmp(api, "me.list.update")==0 )
    {
        qun_update_all(qq);
        buddy_update_list(qq);
        group_update_list(qq);
        if ( qqclient_wait(qq, 10)<0 )
        {
            strcat(response, "UPDATE FAILED");
        }
        else
        {
            strcat(response, "UPDATE SUCCESS");
        }
        //printf("Done of %s.\n", api);
    }
    else if ( stricmp(api, "me.autoreply")==0 )
    {
        char *power;
        NEW(power, 3);
        mid_value(buffer, "<power>", "</power>", power, 3);
        if ( strcmp(power, "on")==0 )
        {
            myqq_auto_reply(1);
        }
        else
        {
            myqq_auto_reply(0);
        }
        strcat(response, "SWITCH SUCCESS");
        //printf("Done of %s.\n", api);
        DEL(power);
    }
    else if ( stricmp(api, "me.status.update")==0 )
    {
        char *status;
        NEW(status, 6);
        mid_value(buffer, "<status>", "</status>", status, 6);
        if( strcmp( status, "away") == 0 )
            qqclient_change_status( qq, QQ_AWAY );
        else if( strcmp( status, "online") == 0 )
            qqclient_change_status( qq, QQ_ONLINE );
        else if( strcmp( status, "hidden") == 0 )
            qqclient_change_status( qq, QQ_HIDDEN );
        else if( strcmp( status, "killme") == 0 )
            qqclient_change_status( qq, QQ_KILLME );
        else if( strcmp( status, "busy") == 0 )
            qqclient_change_status( qq, QQ_BUSY );
        strcat(response, "UPDATE SUCCESS");
        //printf("Done of %s.\n", api);
        DEL(status);
    }
    else if ( stricmp(api, "me.buddy.add")==0 )
    {
        char *uid, *message;
        NEW(uid, 10);
        NEW(message, 50);
        mid_value(buffer, "<uid>", "</uid>", uid, 10);
        mid_value(buffer, "<message>", "</message>", message, 50);
        qqclient_add(qq, atoi(uid), message);
        strcat(response, "ADD SUCCESS");
        //printf("Done of %s.\n", api);
        DEL(uid);
        DEL(message);
    }
    else if ( stricmp(api, "me.buddy.del")==0 )
    {
        char *uid;
        NEW(uid, 10);
        mid_value(buffer, "<uid>", "</uid>", uid, 10);
        qqclient_del(qq, atoi(uid));
        strcat(response, "DELETE SUCCESS");
        //printf("Done of %s.\n", api);
        DEL(uid);
    }
    else
    {
        strcat(response, "UNKNOWN API COMMAND");
        OPS("### @ API : Command Unknown : %s", api);
    }
API_RESPONSE:
    // Send
    send(client, response, strlen(response), 0);

    // print
    OPS("### @ API : Command of : %s ...Done.", api);

    // Response Test
    DBG("##### Response Begin #####\n%s\n##### Response End #####\n", response);
    // Close
    shutdown(client, SD_BOTH);
    closesocket(client);
    // Clear
    DEL(response);
    //DEL(client);
    pthread_detach(pthread_self());
}
Exemple #8
0
/** Main execution routine
 @param argc Number of args (0)
 @param argv Args (always empty)
 */
int
main (int argc, char *argv[])
{


  /* ---------------------------------------------------------------------
   *  Alert! setuid program with root privileges
   * ---------------------------------------------------------------------*/

  /* syslog */
  openlog ("odcgi", LOG_PID, LOG_USER);

  script_env_t env;


  /* Agent address */
  //! @todo: what if eth0 don't exists?
  snprintf (env.agent_address, MAX_ENV_SIZE, "%s", getip ("eth0"));

  //! @todo: lots of static variables. Maybe some can be reused to save memory
  char http_gui[8];
  //char http_style[10];
  char http_logout[8];
  char http_user[256];
  char http_pass[256];
  char http_session[1024];
  char http_noheader[8];
  char http_newuser[256];
  char http_newpass1[256];
  char http_newpass2[256];
  char http_deluser[256];
  char http_moduser[256];
  char http_modpass1[256];
  char http_modpass2[256];
  char http_modoldpass[256];
  char http_getfile[256];
  char http_resource[50];
  char http_play_mjpg[100];
  char http_temp[100];

  /* Configuration vars */
  FILE *fh;
  read_config_file (fh, OD_APP_I18N_CONF, lang, "en");
  //read_config_file(fh,OD_APP_STYLE_CONF,style,"default");
  //read_config_file(fh,OD_APP_SKIN_CONF,skin,"silver");

  /* Get HTTP variables */
  cgi_t *cgi = cgi_alloc ();

  cgi_get_param_by_name (cgi, "GUI", http_gui, sizeof (http_gui));
  cgi_get_param_by_name (cgi, "LOGOUT", http_logout, sizeof (http_logout));
  cgi_get_param_by_name (cgi, "USER", http_user, sizeof (http_user));
  cgi_get_param_by_name (cgi, "PASS", http_pass, sizeof (http_pass));
  cgi_get_param_by_name (cgi, "HTSESSID", http_session,
			 sizeof (http_session));
  cgi_get_param_by_name (cgi, "NOHEADER", http_noheader,
			 sizeof (http_noheader));
  cgi_get_param_by_name (cgi, "NEWUSER", http_newuser, sizeof (http_newuser));
  cgi_get_param_by_name (cgi, "NEWPASS1", http_newpass1,
			 sizeof (http_newpass1));
  cgi_get_param_by_name (cgi, "NEWPASS2", http_newpass2,
			 sizeof (http_newpass2));
  cgi_get_param_by_name (cgi, "DELUSER", http_deluser, sizeof (http_deluser));
  cgi_get_param_by_name (cgi, "MODUSER", http_moduser, sizeof (http_moduser));
  cgi_get_param_by_name (cgi, "MODPASS1", http_modpass1,
			 sizeof (http_modpass1));
  cgi_get_param_by_name (cgi, "MODPASS2", http_modpass2,
			 sizeof (http_modpass2));
  cgi_get_param_by_name (cgi, "MODOLDPASS", http_modoldpass,
			 sizeof (http_modoldpass));
  cgi_get_param_by_name (cgi, "FILE", http_getfile, sizeof (http_getfile));
  cgi_get_param_by_name (cgi, "resource", http_resource,
			 sizeof (http_resource));
  cgi_get_param_by_name (cgi, "play_mjpg", http_play_mjpg,
			 sizeof (http_play_mjpg));



//      if (cgi_get_param_by_name(cgi,"style", http_style, sizeof(http_style))==1)
//      {
//              //cgi_get_cookie("HTSTYLE", http_style, sizeof(http_style));
//              strncpy(style, http_style, sizeof(http_style));
//              cgi_http_header_set_cookie("HTSTYLE", style);
//      }

  // Si se ha solicitado una hoja de estilo, la entregamos
  if (cgi_get_param_by_name (cgi, "css", http_temp, sizeof (http_temp)) == 1)
    {
      syslog (LOG_NOTICE, "printing style: %s\n", http_temp);
      odcgi_print_file (http_temp);
      cgi_free (cgi);
      return 0;
    }
/*	// Si se ha solicitado el javascript específico, lo entregamos
	if (cgi_get_param_by_name(cgi, "js", http_temp, sizeof(http_temp))==1) 
	{
		syslog(LOG_NOTICE, "printing script: %s\n", http_temp);
		odcgi_print_file(http_temp);
		return 0;
	} */


  if (strlen (http_session) == 0)
    {
      cgi_get_cookie ("HTSESSID", http_session, sizeof (http_session));
      syslog (LOG_NOTICE, "session from cookie: %s\n", http_session);
    }

  /* get gui type */
  if (strcmp (http_gui, "XML") == 0)
    gui = xml;
  if (strcmp (http_gui, "none") == 0)
    gui = none;


  /* login process */
  if (odcgi_login (&env, http_user, http_pass,
		   http_session, sizeof (http_session)) == -1)
    {
      syslog (LOG_NOTICE, "login failed: %s-%s\n", http_user, http_pass);
      cgi_free (cgi);
      return -1;
    }

//      syslog(LOG_NOTICE, "env.user: %s\n", env.user);
//      syslog(LOG_NOTICE, "http_user: %s\n", http_user);


  /* check logout */
  if (odcgi_logout (&env, http_logout))
    {
      cgi_free (cgi);
      return -1;
    }


  /* ---------------------------------------------------------------------
   *  Login OK: odcgi is setuid root
   * --------------------------------------------------------------------- */
  //syslog(LOG_NOTICE, "[odcgi] userid: %d\n", getuid());

  /* root has not access */
  if (odcgi_check_root (http_user))
    {
      cgi_free (cgi);
      return -1;
    }


  /* ---------------------------------------------------------------------
   *  Login OK:
   *  + admin has root privileges
   *  + normal user has Linux privileges
   * --------------------------------------------------------------------- */
  syslog (LOG_NOTICE, "[odcgi] user: %s, uid: %d, guid: %d\n",
	  env.user, getuid (), getgid ());

	/* NO USER MANAGEMENT FUNCTIONS IN
  // adds a new user 
  if (odcgi_add_user (http_newuser, http_newpass1, http_newpass2) == -1)
    {
      cgi_free (cgi);
      return -1;
    }

  // delete user 
  if (odcgi_del_user (http_deluser) == -1)
    {
      cgi_free (cgi);
      return -1;
    }

  // modify user password 
  if (odcgi_mod_user (http_moduser, http_modoldpass,
		      http_modpass1, http_modpass2) == -1)
    {
      cgi_free (cgi);
      return -1;
    }

	*/

  /* set session */
  /* Privilege separation: drop root privileges */
//   syslog(LOG_NOTICE, "set session %s\n", http_session);
//   syslog(LOG_NOTICE, "[odcgi] session_set_ids user: %s\n", env.user);
  session_set_ids (env.user);
  syslog (LOG_NOTICE, "[odcgi] dropped privileges user: %s, uid: %d, guid: %d\n",
	  env.user, getuid (), getgid ());
  

  /* File reference with user permissions applied */
  if (strlen (http_getfile) > 5)
    {
      char buffer[1024] = "/media/";
      strcat (buffer, http_getfile);
      if (http_send_file (buffer))
	{
	  cgi_free (cgi);
	  return 0;
	}
      else
	{
	  //! @todo Mostrar error
	}
    }


  /* play mjpg file */
  if (strlen (http_play_mjpg) > 3)
	{
		syslog (LOG_NOTICE, "play: %s\n", http_play_mjpg);
		mjpg_play (http_play_mjpg);
		cgi_free (cgi);
		return 0;
	}

	switch (gui)
	{
		case xml:
			cgi_http_header_begin ("text/xml");
		break;
		case html:
			cgi_http_header_begin ("text/html");
		break;
		default:
			cgi_http_header_begin ("text/plain");
	}


  /* Resource reference */
  //TODO Verificar permisos de usuario
  if (strlen (http_resource) > 3)
	{
		syslog (LOG_NOTICE, "Serving resource %s\n", http_resource);
		if (mjpg_streaming_rsc (http_resource))
		{
			cgi_free (cgi);
			return 0;
		}
		else
		{
			//printf("<div id='connfail'><p class='error'>%s</p></div>\n",
			//              T(ODCGI_ERROR__CONNECTION_FAILURE));
			cgi_free (cgi);
			return 0;
		}
	}



	syslog (LOG_NOTICE, "1.session: %s\n", http_session);
	cgi_http_header_set_cookie ("HTSESSID", http_session);
	//   cgi_get_cookie("HTSTYLE", style, sizeof(style));
	//   cgi_http_header_set_cookie("HTSTYLE", style);
	cgi_http_header_end ();




	/* ---------------------------------------------------------------------
	*  User privileges
	* ---------------------------------------------------------------------*/

	size_t len = cgi->decoded_url->size;
	char path_info[256 + len];
	path_info[0] = 0;
	sstrncpy (path_info, cgi_get_path_info (cgi), sizeof (path_info));
	syslog (LOG_NOTICE, "path_info %s - %d\n", path_info, strlen (path_info));



	// If any POST/GET vars matches with submit_X.sh, X.sh is the target
	// then replace 'path_info'.
	char options[256 + len];
	int index = 0;
	char varname[256];
	char varvalue[256 + len];
	int has_option = 0;
	char scriptname[256] = "";
	char path[256 + len];
	path[0] = 0;

	while (cgi_get_param_by_index (cgi, index, varname, sizeof (varname),
				 varvalue, sizeof (varvalue)))
	{
		// Replace "+" for " "
		for (int i=0;i<sizeof(varvalue);i++) {
			if (varvalue[i]=='+') varvalue[i]=' ';
		}

		syslog (LOG_DEBUG, "CGIParam %d %s=%s\n", index, varname, varvalue);
		
		if (strcmp (varname, "GUI") == 0)
		{
		// Ignore               

		}
		else if (strcmp (varname, "odcgioptionsel") == 0)
		{
			sstrncat (options, varvalue, sizeof (options));
			sstrncat (options, " ", sizeof (options));
			has_option = 1;
		}

		else if (strncmp (varname, "submit_", 7) == 0)
		{
			syslog (LOG_NOTICE, "Submit redirection found at %s\n", varname);
			sstrncpy (scriptname, varname + 7, sizeof (scriptname));
			//sstrncpy(path_info, scriptname, sizeof(path_info));
			snprintf (path, sizeof (path), "/usr/local/opendomo/%s",
			    scriptname);
			syslog (LOG_DEBUG, "debugging %s - %s [%s]\n", scriptname, path,
			  options);
			break;
		}
		index++;
	}


  /* Check PATH variable */
  if (strlen (path_info) == 0)
    strcpy (path_info, "/");

  /* filters */
  if (!match
      (path_info,
       "^/[a-záéíóúàèäëïöüñçA-ZÁÉÍÓÚÀÈÄËÏÖÜÑÇ0-9_/]*\\.{0,1}[a-záéíóúàèäëïöüñçA-ZÁÉÍÓÚÀÈÄËÏÖÜÑÇ0-9_/+ =?:]*$"))
    {
      odcgi_print_header ("error", env.user);
      syslog (LOG_ERR, "%s\n", ODCGI_ERROR__INVALID_PATH);
      odcgi_msg_error (ODCGI_ERROR__INVALID_PATH,
      	"Invalid character found in the command.");
      printf ("\n<!-- PATH_INFO: %s-->\n", path_info);
      odcgi_print_footer ("", 0, cgi);
      cgi_free (cgi);
      return -1;
    }

  int err = 0;

  char *param_regex = "[$;'\\\"]";
  if (strstr (cgi_get_query_string (cgi), ".."))
    err = 1;
  else if (strstr (cgi_get_decoded_url (cgi), ".."))
    err = 2;
  else if (strlen (cgi_get_query_string (cgi)) > 0 &&
	   match (cgi_get_query_string (cgi), param_regex))
    err = 3;
  else if (strlen (cgi_get_decoded_url (cgi)) > 0 &&
	   match (cgi_get_decoded_url (cgi), param_regex))
    err = 4;

  if (err!=0)
    {
      odcgi_print_header ("error", env.user);
      syslog (LOG_ERR, "%s\n", ODCGI_ERROR__INVALID_PATH);
      odcgi_msg_error (ODCGI_ERROR__INVALID_PATH,
		 "Invalid character found in the parameters.");
      printf ("\n<!-- PATH ERROR: %d (not allowed) \n\t%s \n\t %s -->\n", 
      	err,
      	cgi_get_query_string (cgi),
      	cgi_get_decoded_url (cgi));
      odcgi_print_footer ("", 0, cgi);
      cgi_free (cgi);
      return -1;
    }

  // If PATH is not modified, use the default path in CONF_DIR.
  if (path[0] == 0)
    {
      snprintf (path, sizeof (path), "%s/%s", OD_CFG_ROOT_DIR, path_info);
    }

  /* root directory */
  if (chdir (OD_CFG_ROOT_DIR) != 0)
    {
      odcgi_print_header ("error", env.user);
      syslog (LOG_ERR, "%s\n", ODCGI_ERROR__ROOT_PATH_ACCESS);
      odcgi_msg_error (ODCGI_ERROR__ROOT_PATH_ACCESS,
		 "Cannot access the configuration directory. "
		 "Missing privileges or misconfiguration");
      odcgi_print_footer ("", 0, cgi);
      cgi_free (cgi);
      return -1;
    }


  char name[256 + len];
  char value[256 + len];
  char prename[256 + len];
  char *shname;
  string_t *cmd = string_alloc ("");

  file_t fs;
  strcpy (scriptname, basename (path));

  /* HTML-head begin */
  odcgi_print_header (scriptname, env.user);

  printf ("<!-- path: %s, path_info: %s-->\n", path, path_info);

  /* Check NOHEADER */
  if ((gui == html) && (atoi (http_noheader) != 1))
    {
      string_assign_str (cmd, "/usr/bin/categories.sh ");
      string_append (cmd, path_info);

      script_exec (cmd->str, "header", &env);
      if (strlen (path_info) < 2)
	{
	  printf
	    ("  <div class='applicationTitle'><h1>OpenDomo</h1></div>\n");
	}
      else
	{
	  printf ("  <div class='root'><a href='" OD_URI "/'> </a></div>\n");
	}
    }



  sstrncpy (prename, path, sizeof (prename));
  shname = strtok (prename, " ");
  file_set_filename (&fs, shname);
  strcpy (scriptname, basename (path));

  /* if dir: list contents */
  if (file_is_dir (&fs))
    {
      string_assign_str (cmd,  "/usr/bin/list.sh ");
      string_append (cmd, path_info);
      string_append (cmd, " contents");

      script_exec (cmd->str, "main", &env);
    }
  else
    {
      /* if file: execute */
      // The path might be a redirection (no actual link in ..opendomo/root/)
      if (!file_is_file (&fs))
	{
	  snprintf (path, sizeof (path), "/usr/local/opendomo/%s",
		    basename (scriptname));
	  printf ("\n<!-- debug paths: %s / %s [%s] -->\n", path, path_info,
		  scriptname);
	  file_set_filename (&fs, path);
	  if (!file_is_file (&fs))	// If it's still not a valid path, abort
	    {
	      odcgi_msg_error (ODCGI_ERROR__SCRIPT_NOT_FOUND,
			 "The script was not found. "
			 "Maybe the function you are requiring "
			 "is not installed in this system");
	      printf ("<!-- BASENAME: %s -->\n", basename (scriptname));
	      odcgi_print_footer ("", 0, cgi);
	      cgi_free (cgi);
	      return 1;
	    }
	}
      //printf("<!-- debug path: %s -->\n", path);
      //char *p = strrchr(path, '/');
      if (has_option /*&& p */ )
	{
	  string_assign_str (cmd, path);
	  string_append (cmd, " ");
	  string_append (cmd, options);
	}
      else
	{
	  string_assign_str (cmd, path);
	  string_append (cmd, " ");
	}
      printf ("\n<!-- decoded_url: %s \n\tquery_string: %s-->\n", 
      	cgi->decoded_url->str, cgi->query_string->str);
      int i = 0;
      while (cgi_get_param_by_index (cgi, i++,
				     name, sizeof (name), value,
				     sizeof (value)))
	{
		if (strcmp (name, ODCGI_SESSION_NAME) == 0)
		{
			// Ignoring session name var ...
		}
		else if (strncmp (name, "GUI", 3) == 0)
		{
			// Ignoring GUI param
		}
		else if (strncmp (name, "submit_", 7) == 0)
		{
			// Ignoring possible submit redirection ...
		}
		else
		{
			//for (i = 0; i < sizeof(value); i++){
			//	if (value[i]=='+') value[i]=' ';
			//}
			// Avoid overwritting a defined environment var
			if (getenv (name) == NULL)
				setenv (name, value, 1);
			string_append (cmd, " \"");
			string_append (cmd, value);
			string_append (cmd, "\" ");
		}
	}
	string_replace (cmd, "+", " ");
	string_replace (cmd, "'", "&apos;");

     printf ("<!-- cmd (file): %s -->\n", cmd->str);
      //fflush(stdout); // Force flush, otherwise an error will preceed stdout
      // Check the returned value of script_exec()


      int ret = script_exec (cmd->str, "main", &env);
      if (ret != 0)
	{
	  /* else: empty div */
	  printf ("<div id='main'><p class='error'>%s</p></div>",
		  ODCGI_ERROR__SCRIPT_NOT_FOUND);
	}
    }
  /* Print scripts */
  //odcgi_print_script(path); DEPRECATED

  /* HTML end */
  if (atoi (http_noheader) != 1)
    {
      odcgi_print_footer ("", BUTTON_LOGOUT + BUTTON_DEBUG, cgi);
    }

  string_free (cmd);
  cgi_free (cgi);
  closelog ();
  return 0;
}