Ejemplo n.º 1
0
 void __glob_gdn( const char* a_path, const char* a_fnpattern, 
                  VArray &a_va ) // glob getdirname
 {
   VString pat = a_fnpattern;
   pat += "*";
   
   a_va.undef();
   DIR *dir;
   dirent *de; 
   if ( !a_path || a_path[0] == 0 ) 
     dir = opendir(".");
   else 
     dir = opendir( a_path );
   if (dir) 
     { 
     while ( (de = readdir(dir)) )
       { 
       if ( strcmp( de->d_name, "." ) == 0 || 
            strcmp( de->d_name, ".." ) == 0 ) continue;
       if ( a_fnpattern[0] == 0 || FNMATCH( pat, de->d_name)==0 )
         { 
         VString str; // = a_path;
         str += de->d_name;
         if ( file_is_dir( a_path + str ) ) 
           {
           str += "/";
           a_va.push(str);
           }
         } 
       } 
     closedir(dir); 
     } 
 }
Ejemplo n.º 2
0
/* Finds the next element of the given directory and stores the element's name
   in the given buffer. Returns true if an element was found, false if not.
   NOTE : "." and ".." are not considered true elements, and will never be
   returned by this function. */
bool
dir_readdir (struct file *dir, char *buf)
{
  ASSERT (file_is_dir (dir));
  bool locked = file_lock (dir);

  /* If the cursor is before the third entry, then it's pointing at "." or "..",
     since these are *always* the first two directory entries. Seek to beyond
     them, since we don't want to return them. */
  off_t min_cursor = 2 * sizeof (struct dir_entry);
  if (file_tell (dir) < min_cursor)
    file_seek (dir, min_cursor);

  bool success = false;
  while (true)
    {
      struct dir_entry e;
      if (file_read (dir, &e, sizeof e) != sizeof e)
        goto done;
      if (e.in_use)
        {
          strlcpy (buf, e.name, NAME_MAX + 1);
          return true;
          goto done;
        }
    }
    
done:
  if (locked) file_unlock (dir);
  return success;
}
Ejemplo n.º 3
0
Archivo: file.c Proyecto: albertz/navit
int file_mkdir(char *name, int pflag)
{
	char *buffer=g_alloca(sizeof(char)*(strlen(name)+1));
	int ret;
	char *next;
	dbg(1,"enter %s %d\n",name,pflag);
	if (!pflag) {
		if (file_is_dir(name))
			return 0;
#if defined HAVE_API_WIN32_BASE || defined _MSC_VER
		return mkdir(name);
#else
		return mkdir(name, 0777);
#endif
	}
	strcpy(buffer, name);
	next=buffer;
	while ((next=strchr(next, '/'))) {
		*next='\0';
		if (*buffer) {
			ret=file_mkdir(buffer, 0);
			if (ret)
				return ret;
		}
		*next++='/';
	}
	if (pflag == 2)
		return 0;
	return file_mkdir(buffer, 0);
}
Ejemplo n.º 4
0
/* NOTE - Assumes that the caller has already acquired a lock on dir. */
static int
lookup (struct file *dir, const char *name, off_t *out_ofs,
        struct dir_entry *out_entry)
{
  ASSERT (file_is_dir (dir));
  struct dir_entry e;
  size_t ofs;
  
  ASSERT (name != NULL);
  
  int return_value = -1;

  /* Search the directory for the given element. */
  size_t dir_size = inode_length (dir->inode);
  for (ofs = 0; ofs < dir_size; ofs += sizeof e) 
    {
      inode_read_at (dir->inode, &e, sizeof e, ofs);
      if (e.in_use && !strcmp (name, e.name))
        {
          if (out_ofs)    *out_ofs = ofs;
          if (out_entry)  *out_entry = e;
          return_value = e.inode_sector;
          break;
        }
    }
  return return_value;
}
Ejemplo n.º 5
0
static int
opkg_download_cache(const char *src, const char *dest_file_name,
	curl_progress_func cb, void *data)
{
    char *cache_name = xstrdup(src);
    char *cache_location, *p;
    int err = 0;

    if (!conf->cache || str_starts_with(src, "file:")) {
	err = opkg_download(src, dest_file_name, cb, data, 0);
	goto out1;
    }

    if(!file_is_dir(conf->cache)){
	    opkg_msg(ERROR, "%s is not a directory.\n",
			    conf->cache);
	    err = 1;
	    goto out1;
    }

    for (p = cache_name; *p; p++)
	if (*p == '/')
	    *p = ',';	/* looks nicer than | or # */

    sprintf_alloc(&cache_location, "%s/%s", conf->cache, cache_name);
    if (file_exists(cache_location))
	opkg_msg(NOTICE, "Copying %s.\n", cache_location);
    else {
       /* cache file with funky name not found, try simple name */
        free(cache_name);
        char *filename = strrchr(dest_file_name,'/');
        if (filename)
           cache_name = xstrdup(filename+1); // strip leading '/'
        else
           cache_name = xstrdup(dest_file_name);
        free(cache_location);
        sprintf_alloc(&cache_location, "%s/%s", conf->cache, cache_name);
        if (file_exists(cache_location))
           opkg_msg(NOTICE, "Copying %s.\n", cache_location);
        else  {
 	    err = opkg_download(src, cache_location, cb, data, 0);
	    if (err) {
	       (void) unlink(cache_location);
	       goto out2;
	  }
	}
    }

    err = file_copy(cache_location, dest_file_name);


out2:
    free(cache_location);
out1:
    free(cache_name);
    return err;
}
Ejemplo n.º 6
0
int
file_move(const char *src, const char *dst, size_t bs)
{
	if (rename(src, dst) == 0)
		return 0;
	if (bs == 0)
		return -1;
	if (file_is_dir(src)) {
		WARN("Cannot move directory by copying");
		return -1;
	}
	if (file_copy(src, dst, -1, bs, 0) < 0)
		return -1;
	return unlink(src);
}
Ejemplo n.º 7
0
/* Adds a file named NAME to DIR, which must not already contain a
   file by that name.  The file's inode is in sector
   INODE_SECTOR.
   Returns true if successful, false on failure.
   Fails if NAME is invalid (i.e. too long) or a disk or memory
   error occurs. */
bool
dir_add (struct file *dir, const char *name, block_sector_t inode_sector)
{
  ASSERT (file_is_dir (dir));
  struct dir_entry e;
  size_t ofs;
  bool success = false;

  ASSERT (dir != NULL);
  ASSERT (name != NULL);

  /* Check NAME for validity. */
  if (*name == '\0' || strlen (name) > NAME_MAX)
    return false;

  bool locked = file_lock (dir);
  /* Check that NAME is not in use. */
  if (dir_lookup (dir, name) >= 0)
    goto done;

  /* Set OFS to offset of free slot.
     If there are no free slots, then it will be set to the
     current end-of-file.
     
     inode_read_at() will only return a short read at end of file.
     Otherwise, we'd need to verify that we didn't get a short
     read due to something intermittent such as low memory. */
  size_t dir_size = inode_length (dir->inode);
  for (ofs = 0; ofs < dir_size; ofs += sizeof e) 
    {
      inode_read_at (dir->inode, &e, sizeof e, ofs);
      if (!e.in_use)
        break;
    }

  /* Write slot. */
  e.in_use = true;
  strlcpy (e.name, name, sizeof e.name);
  e.inode_sector = inode_sector;
  success = inode_write_at (dir->inode, &e, sizeof e, ofs) == sizeof e;

 done:
  if (locked) file_unlock (dir);
  return success;
}
Ejemplo n.º 8
0
/* Returns whether or not the given directory is empty (an empty directory is
   one in which the only entries are "." and "..").
   NOTE : Assumes the caller has already acquired a lock on the directory. */
bool
dir_is_empty (struct file *dir)
{
  ASSERT (file_is_dir (dir));
  
  /* Look through all the directory entries, counting up the entries that are
     in use. */
  size_t dir_size = inode_length (dir->inode);
  struct dir_entry e;
  size_t ofs;
  size_t entries = 0;
  for (ofs = 0; ofs < dir_size; ofs += sizeof e) 
    {
      inode_read_at (dir->inode, &e, sizeof e, ofs);
      if (e.in_use) entries++;
    }

  /* A directory should never have less than 2 entries. */
  ASSERT (entries >= 2);
  
  /* The directory is empty if it contains only "." and ".." - 2 entries. */
  return entries == 2;
}
Ejemplo n.º 9
0
/* Removes any entry for NAME in DIR.
   Returns true if successful, false on failure,
   which occurs only if there is no file with the given NAME. */
bool
dir_remove (struct file *dir, const char *name) 
{
  ASSERT (file_is_dir (dir));
  struct dir_entry e;
  struct inode *inode = NULL;
  bool success = false;
  off_t ofs;
  int sector;

  ASSERT (dir != NULL);
  ASSERT (name != NULL);

  bool locked = file_lock (dir);
  /* Find directory entry. */
  if ((sector = lookup (dir, name, &ofs, &e)) < 0)
    goto done;

  /* Open inode. */
  inode = inode_open (sector);
  if (inode == NULL)
    goto done;

  /* Erase directory entry. */
  e.in_use = false;
  if (inode_write_at (dir->inode, &e, sizeof e, ofs) != sizeof e) 
    goto done;

  /* Remove inode. */
  inode_remove (inode);
  success = true;

 done:
  if (locked) file_unlock (dir);
  if (inode)  inode_close (inode);
  return success;
}
Ejemplo n.º 10
0
void remove_data_files_and_list(pkg_t * pkg)
{
    str_list_t installed_dirs;
    str_list_t *installed_files;
    str_list_elt_t *iter;
    char *file_name;
    conffile_t *conffile;
    int removed_a_dir;
    pkg_t *owner;
    int rootdirlen = 0;
    int r;

    installed_files = pkg_get_installed_files(pkg);
    if (installed_files == NULL) {
        opkg_msg(ERROR,
                 "Failed to determine installed "
                 "files for %s. None removed.\n", pkg->name);
        return;
    }

    str_list_init(&installed_dirs);

    /* don't include trailing slash */
    if (opkg_config->offline_root)
        rootdirlen = strlen(opkg_config->offline_root);

    for (iter = str_list_first(installed_files); iter;
            iter = str_list_next(installed_files, iter)) {
        file_name = (char *)iter->data;

        owner = file_hash_get_file_owner(file_name);
        if (owner != pkg)
            /* File may have been claimed by another package. */
            continue;

        if (!file_is_symlink(file_name) && file_is_dir(file_name)) {
            str_list_append(&installed_dirs, file_name);
            continue;
        }

        conffile = pkg_get_conffile(pkg, file_name + rootdirlen);
        if (conffile) {
            if (conffile_has_been_modified(conffile)) {
                opkg_msg(NOTICE, "Not deleting modified conffile %s.\n",
                         file_name);
                continue;
            }
        }

        if (!opkg_config->noaction) {
            opkg_msg(INFO, "Deleting %s.\n", file_name);
            unlink(file_name);
        } else
            opkg_msg(INFO, "Not deleting %s. (noaction)\n", file_name);

        file_hash_remove(file_name);
    }

    /* Remove empty directories */
    if (!opkg_config->noaction) {
        do {
            removed_a_dir = 0;
            for (iter = str_list_first(&installed_dirs); iter;
                    iter = str_list_next(&installed_dirs, iter)) {
                file_name = (char *)iter->data;

                r = rmdir(file_name);
                if (r == 0) {
                    opkg_msg(INFO, "Deleting %s.\n", file_name);
                    removed_a_dir = 1;
                    str_list_remove(&installed_dirs, &iter);
                }
            }
        } while (removed_a_dir);
    }

    pkg_free_installed_files(pkg);
    pkg_remove_installed_files_list(pkg);

    /* Don't print warning for dirs that are provided by other packages */
    for (iter = str_list_first(&installed_dirs); iter;
            iter = str_list_next(&installed_dirs, iter)) {
        file_name = (char *)iter->data;

        owner = file_hash_get_file_owner(file_name);
        if (owner) {
            free(iter->data);
            iter->data = NULL;
            str_list_remove(&installed_dirs, &iter);
        }
    }

    /* cleanup */
    while (!void_list_empty(&installed_dirs)) {
        iter = str_list_pop(&installed_dirs);
        free(iter->data);
        free(iter);
    }
    str_list_deinit(&installed_dirs);
}
Ejemplo n.º 11
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;
}
Ejemplo n.º 12
0
/* To reduce redundant error handling code [calls to abort_connection()]
 * most of the function is build around conditions that will assign the error
 * code to @state if anything goes wrong. The rest of the function will then just
 * do the necessary cleanups. If all works out we end up with @state being S_OK
 * resulting in a cache entry being created with the fragment data generated by
 * either reading the file content or listing a directory. */
void
file_protocol_handler(struct connection *connection)
{
	unsigned char *redirect_location = NULL;
	struct string page, name;
	struct connection_state state;
	int set_dir_content_type = 0;

	if (get_cmd_opt_bool((const unsigned char *)"anonymous")) {
		if (strcmp((const char *)connection->uri->string, "file:///dev/stdin")
		    || isatty(STDIN_FILENO)) {
			abort_connection(connection,
					 connection_state(S_FILE_ANONYMOUS));
			return;
		}
	}

#ifdef CONFIG_CGI
	if (!execute_cgi(connection)) return;
#endif /* CONFIG_CGI */

	/* Treat /dev/stdin in special way */
	if (!strcmp((const char *)connection->uri->string, "file:///dev/stdin")) {
		int fd = open("/dev/stdin", O_RDONLY);

		if (fd == -1) {
			abort_connection(connection, connection_state(-errno));
			return;
		}
		set_nonblocking_fd(fd);
		if (!init_http_connection_info(connection, 1, 0, 1)) {
			abort_connection(connection, connection_state(S_OUT_OF_MEM));
			close(fd);
			return;
		}
		connection->socket->fd = fd;
		connection->data_socket->fd = -1;
		read_from_stdin(connection);
		return;
	}


	/* This function works on already simplified file-scheme URI pre-chewed
	 * by transform_file_url(). By now, the function contains no hostname
	 * part anymore, possibly relative path is converted to an absolute one
	 * and uri->data is just the final path to file/dir we should try to
	 * show. */

	if (!init_string(&name)
	    || !add_uri_to_string(&name, connection->uri, URI_PATH)) {
		done_string(&name);
		abort_connection(connection, connection_state(S_OUT_OF_MEM));
		return;
	}

	decode_uri_string(&name);

	/* In Win32, file_is_dir seems to always return 0 if the name
	 * ends with a directory separator.  */
	if ((name.length > 0 && dir_sep(name.source[name.length - 1]))
	    || file_is_dir(name.source)) {
		/* In order for global history and directory listing to
		 * function properly the directory url must end with a
		 * directory separator. */
		if (name.source[0] && !dir_sep(name.source[name.length - 1])) {
			redirect_location = (unsigned char *)STRING_DIR_SEP;
			state = connection_state(S_OK);
		} else {
			state = list_directory(connection, name.source, &page);
			set_dir_content_type = 1;
		}

	} else {
		state = read_encoded_file(&name, &page);
		/* FIXME: If state is now S_ENCODE_ERROR we should try loading
		 * the file undecoded. --jonas */
	}

	done_string(&name);

	if (is_in_state(state, S_OK)) {
		struct cache_entry *cached;

		/* Try to add fragment data to the connection cache if either
		 * file reading or directory listing worked out ok. */
		cached = connection->cached = get_cache_entry(connection->uri);
		if (!connection->cached) {
			if (!redirect_location) done_string(&page);
			state = connection_state(S_OUT_OF_MEM);

		} else if (redirect_location) {
			if (!redirect_cache(cached, redirect_location, 1, 0))
				state = connection_state(S_OUT_OF_MEM);

		} else {
			add_fragment(cached, 0, page.source, page.length);
			connection->from += page.length;

			if (!cached->head && set_dir_content_type) {
				unsigned char *head;

				/* If the system charset somehow
				 * changes after the directory listing
				 * has been generated, it should be
				 * parsed with the original charset.  */
				head = straconcat((const unsigned char *)"\r\nContent-Type: text/html; charset=",
						  get_cp_mime_name(get_cp_index((const unsigned char *)"System")),
						  "\r\n", (unsigned char *) NULL);

				/* Not so gracefully handle failed memory
				 * allocation. */
				if (!head)
					state = connection_state(S_OUT_OF_MEM);

				/* Setup directory listing for viewing. */
				mem_free_set(&cached->head, head);
			}

			done_string(&page);
		}
	}

	abort_connection(connection, state);
}
Ejemplo n.º 13
0
/* Returns the inode encapsulated by DIR. */
struct inode *
dir_get_inode (struct file *dir) 
{
  ASSERT (file_is_dir (dir));
  return dir->inode;
}
Ejemplo n.º 14
0
/* Searches for the element with the given name in the given directory.
   Returns the sector of the given element, or -1 if the element was not found
   in dir. */
int
dir_lookup (struct file *dir, const char *name)
{
  ASSERT (file_is_dir (dir));
  return lookup (dir, name, NULL, NULL);
}
Ejemplo n.º 15
0
Archivo: z.c Proyecto: Keidan/tk
/**
 * @fn int z_compress(z_t zip, const z_file_t zname, const char* password, z_clevel_et level, _Bool append, _Bool exclude_path, fifo_t files)
 * @brief Creation of a new ZIP file.
 * @param zip The ZIP context.
 * @param zname The zip file name.
 * @param password the zip password else NULL or empty.
 * @param level The compression level.
 * @param append Append mode.
 * @param exclude_path Exclude the file path.
 * @param files The file list.
 * @retunr 0 on success else -1.
 */
int z_compress(z_t zip, const z_file_t zname, const char* password, z_clevel_et level, _Bool append, _Bool exclude_path, fifo_t files) {
  struct z_s* z = Z_CAST(zip);
  z_file_t filename_try;
  int size_buf = 0;
  void* buf = NULL;
  zipFile zf;

  size_buf = Z_WRITE_BUFFER_SIZE;
  buf = (void*)malloc(size_buf);
  if (!buf) {
    logger(LOG_ERR, "Error allocating memory\n");
    return -1;
  }
  bzero(filename_try, sizeof(z_file_t));
  strcpy(filename_try, zname);
  if(!string_indexof(filename_try, ".") == -1)
    strcat(filename_try, ".zip");

  zf = zipOpen64(filename_try, (append) ? 2 : 0);
  if (!zf) {
    free(buf);
    logger(LOG_ERR, "Error opening %s\n", filename_try);
    return -1;
  } else
    logger(LOG_DEBUG, "Creating %s\n", filename_try);
  
  while(!fifo_empty(files)) {
     const char* filenameinzip = fifo_pop(files);
     FILE * fin;
     int size_read;
     const char *savefilenameinzip;
     zip_fileinfo zi;
     unsigned long crc_file = 0;
     int zip64 = 0;
     memset(&zi, 0, sizeof(zip_fileinfo));
     if(file_is_dir(filenameinzip)) {
       ((char*)filenameinzip)[strlen(filenameinzip)] = z->dir_delimiter;
       strncat((char*)filenameinzip, ".empty", sizeof(file_name_t));
       file_touch(filenameinzip);
     }
     logger(LOG_DEBUG, "Trying to add file '%s'\n", filenameinzip);
     file_time(filenameinzip, (struct tm*)&zi.tmz_date);

     if(password != NULL && strlen(password))
       if(z_get_file_crc(filenameinzip, buf, size_buf, &crc_file) != ZIP_OK) {
	 zipClose(zf, NULL);
	 free(buf);
	 logger(LOG_ERR, "Error getting the crc for the file %s\n", filenameinzip);
	 return -1;
       }

     zip64 = file_is_large_file(filenameinzip);
     /* The path name saved, should not include a leading slash. */
     /*if it did, windows/xp and dynazip couldn't read the zip file. */
     savefilenameinzip = filenameinzip;
     while(savefilenameinzip[0] == z->dir_delimiter)
       savefilenameinzip++;

     /*should the zip file contain any path at all?*/
     if(exclude_path) {
       const char *tmpptr;
       const char *lastslash = 0;
       for(tmpptr = savefilenameinzip; *tmpptr; tmpptr++) {
	 if(*tmpptr == z->dir_delimiter)
	   lastslash = tmpptr;
       }
       if(lastslash)
	 savefilenameinzip = lastslash+1; // base filename follows last slash.
     }

     if(zipOpenNewFileInZip3_64(zf, savefilenameinzip, &zi,
				NULL, 0, NULL, 0, NULL /* comment*/,
				(level != 0) ? Z_DEFLATED : 0, level,0,
				-MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
				(password != NULL && strlen(password)) ? password : NULL, crc_file, zip64) != ZIP_OK) {
	 zipClose(zf, NULL);
	 free(buf);
	 logger(LOG_ERR, "Error in opening %s in zipfile\n", filenameinzip);
	 return -1;
     }

     fin = fopen64(filenameinzip, "rb");
     if(!fin) {
       zipCloseFileInZip(zf);
       zipClose(zf, NULL);
       free(buf);
       logger(LOG_ERR, "Error in opening %s for reading\n", filenameinzip);
       return -1;
     }
     do {
       size_read = (int)fread(buf,1,size_buf,fin);
       if(size_read < size_buf)
	 if(!feof(fin)) {
	   logger(LOG_ERR, "Error in reading %s\n",filenameinzip);
	   break;
	 }

       if (size_read > 0) {
	 if(zipWriteInFileInZip(zf, buf, size_read) < 0)  {
	   logger(LOG_ERR, "Error in writing %s in the zipfile\n", filenameinzip);
	   break;
	 }
       }
     } while(size_read > 0);

     if(fin) fclose(fin);
     if(zipCloseFileInZip(zf) != ZIP_OK) {
       logger(LOG_ERR, "Error in closing %s in the zipfile\n", filenameinzip);
       break;
     }
  }
  if(zipClose(zf, NULL) != ZIP_OK)
    logger(LOG_ERR, "Error in closing %s\n",filename_try);
  free(buf);

  return 0;
}
Ejemplo n.º 16
0
static void
provisioning_mode()
{
	INFO("Check for existence of device certificate");

	bool need_initialization = (!file_exists(DEVICE_CERT_FILE) || !token_file_exists());

	// device needs a device certificate
	if (!file_exists(DEVICE_CONF)) {
		INFO("Going back to bootloader mode, device config does not exist (Proper"
		    "userdata image needs to be flashed first)");
		reboot_reboot(REBOOT);
	}

	if (need_initialization) {
		sleep(5);
		ssl_init();
	}

	// if no certificate exists, create a csr
	if (!file_exists(DEVICE_CERT_FILE)) {

		INFO("Device certificate not available. Switch to device provisioning mode");

		if (!file_exists(DEVICE_CSR_FILE) || !file_exists(DEVICE_KEY_FILE)) {

			DEBUG("Create CSR (recreate if corresponding private key file misses)");

			if (file_exists(SCD_TOKEN_DIR) && file_is_dir(SCD_TOKEN_DIR)) {
				DEBUG("CSR folder already exists");
			} else if (mkdir(SCD_TOKEN_DIR, 00755) != 0) {
				FATAL("Failed to create CSR directory");
			}

#ifdef ANDROID
			char *hw_serial = mem_alloc0(PROPERTY_VALUE_MAX);
			char *hw_name = mem_alloc0(PROPERTY_VALUE_MAX);
			bool property_read_failure = false;
			if (!(property_get(PROP_SERIALNO, hw_serial, NULL) > 0)) {
				ERROR("Failed to read hardware serialno property");
				property_read_failure = true;
			}
			if (!(property_get(PROP_HARDWARE, hw_name, NULL) > 0)) {
				ERROR("Failed to read hardware name property");
				property_read_failure = true;
			}
			char *common_name;
			if (!property_read_failure)
				common_name = mem_printf("%s %s", hw_name, hw_serial);
			else
				common_name = mem_printf("%s %s", "x86", "0000");
			DEBUG("Using common name %s", common_name);
#else
			char *common_name = mem_strdup("common_name");
			char *hw_serial = mem_strdup("hw_serial");
			char *hw_name = mem_strdup("hw_unknown");
#endif


			// create device uuid and write to device.conf
			uuid_t *dev_uuid = uuid_new(NULL);
			const char *uid;
			if (!dev_uuid || (uid = uuid_string(dev_uuid)) == NULL) {
				FATAL("Could not create device uuid");
			}

			DeviceConfig *dev_cfg = (DeviceConfig *)
			    protobuf_message_new_from_textfile(DEVICE_CONF, &device_config__descriptor);

			if (!dev_cfg) {
				FATAL("Failed load device config from file \"%s\"!", DEVICE_CONF);
			}

			// set device uuid
			char *proto_uid = mem_strdup(uid);
			// free this element, as it is overwritten
			mem_free(dev_cfg->uuid);
			dev_cfg->uuid = proto_uid;

			// write the uuid to device config file
			if (protobuf_message_write_to_file(DEVICE_CONF, (ProtobufCMessage *) dev_cfg) < 0) {
				FATAL("Could not write device config to \"%s\"!", DEVICE_CONF);
			}

			if (ssl_create_csr(DEVICE_CSR_FILE, DEVICE_KEY_FILE, NULL, common_name, uid) != 0) {
				FATAL("Unable to create CSR");
			}

			// this call also frees proto_uid
			protobuf_free_message((ProtobufCMessage *) dev_cfg);
			mem_free(hw_serial);
			mem_free(hw_name);
			mem_free(common_name);
			uuid_free(dev_uuid);
			DEBUG("CSR with keyfile created and stored");
		} else {
			DEBUG("CSR with keyfile already exists");
		}

		// self-sign device csr to bring the device up
		// corresponding cert is overwritten during provisioning
		DEBUG("Create self-signed certificate from CSR");

		if (ssl_self_sign_csr(DEVICE_CSR_FILE, DEVICE_CERT_FILE, DEVICE_KEY_FILE) != 0) {
			FATAL("Unable to self sign existing device.csr");
		}
	}
	else {
		INFO("Device certificate found");
		if (file_exists(DEVICE_CSR_FILE)) {
			// this is the case when a non-provisioned trustme phone
			// created its own device.cert and user.p12
			WARN("Device CSR still exists. Device was not correctly provisioned!");
		}
	}

	// self-create a user token to bring the device up
	// is removed during provisioning
	if (!token_file_exists()) {

		DEBUG("Create initial soft token");

		char *token_file = mem_printf("%s/%s%s", SCD_TOKEN_DIR,
			TOKEN_DEFAULT_NAME, TOKEN_DEFAULT_EXT);
		if (ssl_create_pkcs12_token(token_file, NULL, TOKEN_DEFAULT_PASS, TOKEN_DEFAULT_NAME) != 0) {
			FATAL("Unable to create initial user token");
		}
		mem_free(token_file);
	}

	// we now have anything for a clean startup so just die and let us be restarted by init
	if (need_initialization) {
		ssl_free();
		exit(0);
	}

	// remark: no certificate validation checks are carried out
	if (!file_exists(DEVICE_KEY_FILE) || !file_exists(SSIG_ROOT_CERT)
		|| !file_exists(GEN_ROOT_CERT) || !token_file_exists()) {
		FATAL("Missing certificate chains, user token, or private key for device certificate");
	}

}
Ejemplo n.º 17
0
// filtloc and filter operate on the filenames and determine whether they
// may be selected:
// ALL: don't filter, in this case, filter can be NULL
// BASE: filter with cmp_base(filename, filter) - only show when part up to
//       last extension matches
// EXT: filter with cmp_ext(filename, filter) - only show when (last) extension
//      matches
// NAME: filter with strcasecmp(filename, filter) - only show when whole name
//       matches
char * select_file(enum filter_spec filtloc, char *filter) {
	char *selected_file, str[256];
	int npages, pagenum = 1;
	const int perpage = PERPAGE - 1;

	DECL_LINE(backbtn);
	DECL_LINE(prevpage);
	DECL_LINE(nextpage);

	strcpy(sbstr, "file browser");

	selected_file = malloc(PATH_MAX * sizeof(char));

	selected_file[0] = '\0';

	while (selected_file[0] == '\0') {
		char *pwd = NULL;
		int n;
		int *by, *kept;
		int j, nkept;
		int match, keep;
		uint16_t mode;

		sel = -1;

		clear_screen();
		START_LIST(8, 48, 448, 0xFF404040, 0xFF808080, 0xFFC0C0C0)

		update_dir_list();
		n = file_count();
		by = malloc(n * sizeof(int));
		kept = malloc(n * sizeof(int));
		npages = 1 + n / perpage;

		pwd = getcwd(pwd, PATH_MAX);
		text(pwd, 16, 24, 1, 1, 0xFF606060, 0xFF000000);

		DRAW_LINE(backbtn, "back", "return to previous menu without making a selection"); 
		if (pagenum > 1) {
			DRAW_LINE(prevpage, "previous page", "not all files are shown"); 
		}

		j = 0;
		for (int i = 0; i < n; ++i) {
			switch (filtloc) {
			case ANY:
				match = 1;
				break;
			case BASE:
				match = !cmp_base(file_name(i), filter);
				break;
			case EXT:
				match = !cmp_ext(file_name(i), filter);
				break;
			case NAME:
				match = !strcasecmp(file_name(i), filter);
				break;
			default:
				match = 0;
			}

			if (file_is_dir(i) || match) {
				kept[j] = i; 
				++j;
			}
		}
		nkept = j;

		for (int i = perpage * (pagenum - 1); i < nkept; ++i) {
			if (i > pagenum * perpage) break;

			snprintf(str, sizeof(str), "permissions = %o", file_mode(kept[i]) & 07777);

			USECOLR = !USECOLR; 
			CURCOLR = USECOLR ? BG1COLR : BG2COLR; 
			current_y += 48; 
			by[i] =  current_y; 
			fill_rect(0, by[i], 1024, 44, CURCOLR);
			text(file_name(kept[i]), col1_x, by[i] + 8, 1, 1, 0xFFFFFFFF, CURCOLR);
			text(str, col2_x, by[i] + 8, 1, 1, 0xFFFFFFFF, CURCOLR);
		}
		if (pagenum < npages) {
			DRAW_LINE(nextpage, "next page", "not all files are shown");
		}

		while (sel == -1) {
			update_screen();
			input_read();

			if (BTN_CLICKED(backbtn)) {
				free(by);
				free(kept);
				return NULL;
			}
			for (int i = perpage * (pagenum - 1); i <= nkept; ++i)
				if (was_clicked(0, by[i], 1024, 44))
					sel = kept[i];
			if (BTN_CLICKED(prevpage)) {
				--pagenum;
				break;
			} else if (BTN_CLICKED(nextpage)) {
				++pagenum;
				break;
			}
		}

		if (sel != -1) {
			free(by);
			free(kept);
			pagenum = 1;
	
			if (file_is_dir(sel)) {
				if (chdir(file_name(sel)) == -1)
					perror("chdir");
			} else {
				strcpy(selected_file, pwd);
				strcat(selected_file, "/");
				strcat(selected_file, file_name(sel));
			}
		}
	}

	return selected_file;
}