Beispiel #1
0
/*
 * Delete file 'fname' to 'newname'.
 */
bool file_move(const char *fname, const char *newname)
{
	char buf[1024];
	char aux[1024];

	/* Get the system-specific paths */
	path_parse(buf, sizeof(buf), fname);
	path_parse(aux, sizeof(aux), newname);

	return (rename(buf, aux) == 0);
}
Beispiel #2
0
static char filesystem_get_url(char const *path, char **url) {
    path_t *path_parsed = path_parse(path);
    if(path_parsed->parts_length != 2) {
        pthread_mutex_unlock(filesystem_io_mutex);
        path_free(path_parsed);
        logging_log("Filesystem", LOGGING_LEVEL_WARNING,
                    "filesystem_get_url() - Invalid path %s...", path);
        return -1;
    }

    pthread_mutex_lock(filesystem_io_mutex);
    ALDictionary *results = searcher_get_search_results(path_parsed->parts[0]);

    if(results == NULL) {
        pthread_mutex_unlock(filesystem_io_mutex);
        path_free(path_parsed);
        logging_log("Filesystem", LOGGING_LEVEL_WARNING, "Invalid file %s...", path);
        return -1;
    }

    char result;
    *url = (char*)al_dictionary_get(results, &result, path_parsed->parts[1]);
    pthread_mutex_unlock(filesystem_io_mutex);

    if(result) {
        logging_log("Filesystem", LOGGING_LEVEL_WARNING,
                    "filesystem_get_url() - Invalid path %s...", path);
        return -1;
    } else
        logging_log("Filesystem", LOGGING_LEVEL_INFO, "filesystem_get_url() - Url is %s...", *url);

    path_free(path_parsed);

    return 0;
}
Beispiel #3
0
/*
 * Open file 'fname', in mode 'mode', with filetype 'ftype'.
 * Returns file handle or NULL.
 */
ang_file *file_open(const char *fname, file_mode mode, file_type ftype)
{
	ang_file *f = ZNEW(ang_file);
	char buf[1024];

	(void)ftype;

	/* Get the system-specific path */
	path_parse(buf, sizeof(buf), fname);

	switch (mode)
	{
		case MODE_WRITE:  f->fh = fopen(buf, "wb"); break;
		case MODE_READ:   f->fh = fopen(buf, "rb"); break;
		case MODE_APPEND: f->fh = fopen(buf, "a+"); break;
		default:          f->fh = fopen(buf, "__");
	}

	if (f->fh == NULL)
	{
		FREE(f);
		return NULL;
	}

	f->fname = string_make(buf);
	f->mode = mode;

	if (mode != MODE_READ && file_open_hook)
		file_open_hook(buf, ftype);

	return f;
}
Beispiel #4
0
static void
builtin_glob_back(
	void	*closure,
	const char *file,
	int	status,
	time_t	time )
{
	struct globbing *globbing = (struct globbing *)closure;
	LIST		*l;
	PATHNAME	f;
	char		buf[ MAXJPATH ];

	/* Null out directory for matching. */
	/* We wish we had file_dirscan() pass up a PATHNAME. */

	path_parse( file, &f );
	f.f_dir.len = 0;
	path_build( &f, buf, 0 );

	for( l = globbing->patterns; l; l = l->next )
	    if( !glob( l->string, buf ) )
	{
	    globbing->results = list_new( globbing->results, file, 0 );
	    break;
	}
}
Beispiel #5
0
/**
 * Gets FSID and PID by path and cuts path to relative path for FS
 *  @param path Path to file
 *  @param parent If FS of parent directory of file is needed
 *  @return FSID
 */
static struct fslist_item *fsbypath(char *path,int parent) {
  if (path==NULL || path[0]==0) return NULL;
  struct fslist_item *fs = mp_match(path,parent);
  if (fs==NULL) {
    fs = malloc(sizeof(struct fslist_item));
    char *mountpoint = strdup(path);
    fs->id = rpc_call("vfs_getfsid",RPC_FLAG_RETPARAMS,path,parent);
    if (fs->id<0) {
      free(mountpoint);
      errno = -fs->id;
      return NULL;
    }
    fs->pid = rpc_call("vfs_getpid",0,fs->id);
    if (fs->pid<0) {
      errno = -fs->pid;
      return NULL;
    }
    mountpoint[strlen(mountpoint)-strlen(path)] = 0;
    fs->mountpoint = path_parse(mountpoint);
    fs->mountpoint_str = path_output(fs->mountpoint,NULL);
    free(mountpoint);
    llist_push(fslist,fs);
  }

  return fs;
}
Beispiel #6
0
/* 返回路径深度,比如/a/b/c,深度为3 */
int32_t path_depth_cnt(char* pathname) {
   ASSERT(pathname != NULL);
   char* p = pathname;
   char name[MAX_FILE_NAME_LEN];       // 用于path_parse的参数做路径解析
   uint32_t depth = 0;

   /* 解析路径,从中拆分出各级名称 */ 
   p = path_parse(p, name);
   while (name[0]) {
      depth++;
      memset(name, 0, MAX_FILE_NAME_LEN);
      if (p) {	     // 如果p不等于NULL,继续分析路径
	p  = path_parse(p, name);
      }
   }
   return depth;
}
Beispiel #7
0
/*
 * Delete file 'fname'.
 */
bool file_delete(const char *fname) 
{
	char buf[1024];

	/* Get the system-specific paths */
	path_parse(buf, sizeof(buf), fname);

	return (remove(buf) == 0);
}
Beispiel #8
0
/**
 * Gets absolute path by relative path
 *  @param relative Relative or absolute path
 *  @return Absolute path (Can be passed to free())
 */
static char *getabsolutepath(const char *relative) {
  path_t *path = path_parse(relative);
  if (!path->root) {
    path_t *newpath = path_cat(workdir.path,path);
    path_destroy(path);
    path = newpath;
  }
  path_reject_dots(path);
  return path_output(path,NULL);
}
static void
builtin_glob_back(
    void    *closure,
    char    *file,
    int status,
    time_t  time )
{
    PROFILE_ENTER(BUILTIN_GLOB_BACK);
    
    struct globbing *globbing = (struct globbing *)closure;
    LIST        *l;
    PATHNAME    f;
    string          buf[1];
    
    /* Null out directory for matching. */
    /* We wish we had file_dirscan() pass up a PATHNAME. */

    path_parse( file, &f );
    f.f_dir.len = 0;

    /* For globbing, we unconditionally ignore current and parent
       directory items. Since they items always exist, there's not
       reason why caller of GLOB would want to see them.
       We could also change file_dirscan, but then paths with embedded
       "." and ".." won't work anywhere.
    */
    if (strcmp(f.f_base.ptr, ".") == 0 || strcmp(f.f_base.ptr, "..") == 0)
    {
        PROFILE_EXIT(BUILTIN_GLOB_BACK);
        return;
    }

    string_new( buf );
    path_build( &f, buf, 0 );

    if (globbing->case_insensitive) {
        downcase_inplace( buf->value );
    }

    for( l = globbing->patterns; l; l = l->next )
    {
        if( !glob( l->string, buf->value ) )
        {
            globbing->results = list_new( globbing->results, newstr( file ) );
            break;
        }
    }
    
    string_free( buf );
    
    PROFILE_EXIT(BUILTIN_GLOB_BACK);
}
Beispiel #10
0
/*
 * Open file 'fname', in mode 'mode', with filetype 'ftype'.
 * Returns file handle or NULL.
 */
ang_file *file_open(const char *fname, file_mode mode, file_type ftype)
{
	ang_file *f = ZNEW(ang_file);
	char buf[1024];

	(void)ftype;

	/* Get the system-specific path */
	path_parse(buf, sizeof(buf), fname);

	switch (mode) {
		case MODE_WRITE: { 
			if (ftype == FTYPE_SAVE) {
				/* open only if the file does not exist */
				int fd;
				fd = open(buf, O_CREAT | O_EXCL | O_WRONLY | O_BINARY, S_IRUSR | S_IWUSR);
				if (fd < 0) {
					/* there was some error */
					f->fh = NULL;
				} else {
					f->fh = fdopen(fd, "wb");
				}
			} else {
				f->fh = fopen(buf, "wb");
			}
			break;
		}
		case MODE_READ:
			f->fh = fopen(buf, "rb");
			break;
		case MODE_APPEND:
			f->fh = fopen(buf, "a+");
			break;
		default:
			assert(0);
	}

	if (f->fh == NULL)
	{
		FREE(f);
		return NULL;
	}

	f->fname = string_make(buf);
	f->mode = mode;

	if (mode != MODE_READ && file_open_hook)
		file_open_hook(buf, ftype);

	return f;
}
Beispiel #11
0
/*
 * Open file 'fname', in mode 'mode', with filetype 'ftype'.
 * Returns file handle or NULL.
 */
ang_file *file_open(const char *fname, file_mode mode, file_type ftype)
{
	ang_file *f = ZNEW(ang_file);
	char buf[1024];

	(void)ftype;

	/* Get the system-specific path */
	path_parse(buf, sizeof(buf), fname);

	switch (mode)
	{
		case MODE_WRITE:  f->fh = fopen(buf, "wb"); break;
		case MODE_READ:   f->fh = fopen(buf, "rb"); break;
		case MODE_APPEND: f->fh = fopen(buf, "a+"); break;
		default:          f->fh = fopen(buf, "__");
	}

	if (f->fh == NULL)
	{
		FREE(f);
		return NULL;
	}

	f->fname = string_make(buf);
	f->mode = mode;

#ifdef MACH_O_CARBON
	extern void fsetfileinfo(cptr path, u32b fcreator, u32b ftype);

	/* OS X uses its own kind of filetypes */
	if (mode != MODE_READ)
	{
		u32b mac_type = 'TEXT';

		if (ftype == FTYPE_RAW) mac_type = 'DATA';
		else if (ftype == FTYPE_SAVE) mac_type = 'SAVE';

		fsetfileinfo(buf, 'A271', mac_type);
	}
#endif /* MACH_O_CARBON */

#if defined(RISCOS) && 0
	/* do something for RISC OS here? */
	if (mode != MODE_READ)
		File_SetType(n, ftype);
#endif

	return f;
}
Beispiel #12
0
static void
var_edit_file(
	const char *in,
	BUFFER *buff,
	VAR_EDITS *edits )
{
	PATHNAME pathname;
	char		buf[ MAXJPATH ];

	/* Parse apart original filename, putting parts into "pathname" */

	path_parse( in, &pathname );

	/* Replace any pathname with edits->f */

	if( edits->f.f_grist.ptr )
	    pathname.f_grist = edits->f.f_grist;

	if( edits->f.f_root.ptr )
	    pathname.f_root = edits->f.f_root;

	if( edits->f.f_dir.ptr )
	    pathname.f_dir = edits->f.f_dir;

	if( edits->f.f_base.ptr )
	    pathname.f_base = edits->f.f_base;

	if( edits->f.f_suffix.ptr )
	    pathname.f_suffix = edits->f.f_suffix;

	if( edits->f.f_member.ptr )
	    pathname.f_member = edits->f.f_member;

	/* If requested, modify pathname to point to parent */

	if( edits->parent )
	    path_parent( &pathname );

	/* Put filename back together */

#ifdef OPT_ROOT_PATHS_AS_ABSOLUTE_EXT
	path_build( &pathname, buf, 0, 1 );
#else
	path_build( &pathname, buf, 0 );
#endif
	buffer_addstring( buff, buf, strlen( buf ) + 1 );
}
Beispiel #13
0
/*
 * Create an ".angband/" directory in the users home directory.
 *
 * ToDo: Add error handling.
 * ToDo: Only create the directories when actually writing files.
 */
static void create_user_dir(void)
{
	char dirpath[1024];
	char subdirpath[1024];

	/* Get an absolute path from the filename */
	path_parse(dirpath, 1024, PRIVATE_USER_PATH);

	/* Create the ~/.angband/ directory */
	mkdir(dirpath, 0700);

	/* Build the path to the variant-specific sub-directory */
	path_build(subdirpath, sizeof(subdirpath), dirpath, VERSION_NAME);

	/* Create the directory */
	mkdir(subdirpath, 0700);
}
Beispiel #14
0
/* Records the binding of a target with an explicit LOCATE. */
void set_explicit_binding( OBJECT * target, OBJECT * locate )
{
    OBJECT * boundname;
    OBJECT * key;
    PATHNAME f[ 1 ];
    string buf[ 1 ];
    int found;
    BINDING * ba;

    if ( !explicit_bindings )
        explicit_bindings = hashinit( sizeof( BINDING ), "explicitly specified "
            "locations" );

    string_new( buf );

    /* Parse the filename. */
    path_parse( object_str( target ), f );

    /* Ignore the grist. */
    f->f_grist.ptr = 0;
    f->f_grist.len = 0;

    /* Root the target path at the given location. */
    f->f_root.ptr = object_str( locate );
    f->f_root.len = strlen( object_str( locate ) );

    path_build( f, buf );
    boundname = object_new( buf->value );
    if ( DEBUG_SEARCH )
        printf( "explicit locate %s: %s\n", object_str( target ), buf->value );
    string_free( buf );
    key = path_as_key( boundname );
    object_free( boundname );

    ba = (BINDING *)hash_insert( explicit_bindings, key, &found );
    if ( !found )
    {
        ba->binding = key;
        ba->target = target;
    }
    else
        object_free( key );
}
Beispiel #15
0
static void
var_edit_file( 
	char	*in,
	string	*out,
	VAR_EDITS *edits )
{
	PATHNAME pathname;

	/* Parse apart original filename, putting parts into "pathname" */

	path_parse( in, &pathname );

	/* Replace any pathname with edits->f */

	if( edits->f.f_grist.ptr )
	    pathname.f_grist = edits->f.f_grist;

	if( edits->f.f_root.ptr )
	    pathname.f_root = edits->f.f_root;

	if( edits->f.f_dir.ptr )
	    pathname.f_dir = edits->f.f_dir;

	if( edits->f.f_base.ptr )
	    pathname.f_base = edits->f.f_base;

	if( edits->f.f_suffix.ptr )
	    pathname.f_suffix = edits->f.f_suffix;

	if( edits->f.f_member.ptr )
	    pathname.f_member = edits->f.f_member;

	/* If requested, modify pathname to point to parent */

	if( edits->parent )
	    path_parent( &pathname );

	/* Put filename back together */

    path_build( &pathname, out, 0 );
}
Beispiel #16
0
gboolean
workspace_load_compat( Workspace *ws, int major, int minor )
{
	char pathname[FILENAME_MAX];
	GSList *path;
	int best_major;
	int best_minor;

	if( workspace_have_compat( major, minor, &best_major, &best_minor ) ) {
		/* Make a private toolkitgroup local to this workspace to 
		 * hold the compatibility defs we are planning to load.
		 */
		UNREF( ws->kitg );
		ws->kitg = toolkitgroup_new( ws->sym );
		g_object_ref( G_OBJECT( ws->kitg ) );
		iobject_sink( IOBJECT( ws->kitg ) );

		im_snprintf( pathname, FILENAME_MAX, 
			"$VIPSHOME/share/" PACKAGE "/compat/%d.%d", 
			best_major, best_minor );
		path = path_parse( pathname );
		if( path_map( path, "*.def", 
			(path_map_fn) workspace_load_toolkit, ws->kitg ) ) {
			path_free2( path );
			return( FALSE );
		}
		path_free2( path );

		ws->compat_major = best_major;
		ws->compat_minor = best_minor;
	}
	else {
		/* No compat defs necessary for this ws. 
		 */
		ws->compat_major = 0;
		ws->compat_minor = 0;
	}

	return( TRUE );
}
Beispiel #17
0
/**
 * Match mountpoint
 *  @param file Path to file
 *  @param parent If FS of parent directory of file is needed
 *  @return FS List item
 */
static struct fslist_item *mp_match(char *file,int parent) {
  size_t i,curcmp;
  size_t maxcmp = 0;
  struct fslist_item *fs;
  struct fslist_item *maxfs = NULL;
  path_t *path = path_parse(file);

  if (parent) path_parent(path);

  for (i=0;(fs = llist_get(fslist,i));i++) {
    curcmp = path_compare(path,fs->mountpoint);
    if (curcmp>maxcmp) {
      maxcmp = curcmp;
      maxfs = fs;
    }
  }

  if (maxfs!=NULL) memmove(file,file+strlen(maxfs->mountpoint_str),strlen(file)-strlen(maxfs->mountpoint_str)+1);
  if (file[0]==0) strcpy(file,"/");

  return maxfs;
}
Beispiel #18
0
const char *checksums_filename() {
	LIST *var;
	if ( checksumsfilename ) {
		return checksumsfilename;
	}

	var = var_get( "JAM_CHECKSUMS_FILE" );
	if ( list_first( var ) ) {
		const char *value = list_value( list_first( var ) );
		TARGET *t = bindtarget( value );
		checksumsfilename = copystr( search_using_target_settings( t, t->name, &t->time ) );
	}

	if ( !checksumsfilename ) {
		PATHNAME f[1];
		char buf[ MAXJPATH ];

		var = var_get( "ALL_LOCATE_TARGET" );
		if ( !var ) {
			var = var_get( "CWD" );
		}

		path_parse( ".jamchecksums", f );

		f->f_grist.ptr = 0;
		f->f_grist.len = 0;

		if ( var ) {
			f->f_root.ptr = list_value( list_first( var ) );
			f->f_root.len = (int)( strlen( f->f_root.ptr ) );
		}

		path_build( f, buf, 1, 1 );
		checksumsfilename = newstr( buf );
	}

	return checksumsfilename;
}
Beispiel #19
0
/**
 * Unpack filehandles
 *  @param buf Buffer
 *  @note This function should be called before any other file function (except _fs_init())
 */
void _fs_unpack_filehandles(pack_t buf) {
  struct filelist_item *file;
  struct fslist_item *fs;
  size_t i,files_num,fs_num;
  char *tmp;
  id_t id;

  // Unpack filesystems
  unpacki(buf,&fs_num);
  for (i=0;i<fs_num;i++) {
    fs = malloc(sizeof(struct fslist_item));
    unpacki(buf,&(fs->id));
    unpacki(buf,&(fs->pid));
    unpackstr(buf,&tmp);
    fs->mountpoint = path_parse(tmp);
    fs->mountpoint_str = strdup(tmp);
    llist_push(fslist,fs);
  }

  // Unpack files
  unpacki(buf,&files_num);
  for (i=0;i<files_num;i++) {
    file = malloc(sizeof(struct filelist_item));
    unpacki(buf,&(file->fh));
    unpacki(buf,&(file->fs_fh));
    unpacki(buf,&(file->shmid));
    unpacki(buf,&(file->type));
    unpacki(buf,&(file->mode));
    unpacki(buf,&(file->stfl));
    unpacki(buf,&(file->fdfl));
    unpacki(buf,&id);
    unpackstr(buf,&(file->path));
    file->shmbuf = shmat(file->shmid,NULL,0);
    file->fs = fsbyid(id);
    llist_push(filelist,file);
  }
}
Beispiel #20
0
/* 搜索文件pathname,若找到则返回其inode号,否则返回-1 */
static int search_file(const char* pathname, struct path_search_record* searched_record) {
   /* 如果待查找的是根目录,为避免下面无用的查找,直接返回已知根目录信息 */
   if (!strcmp(pathname, "/") || !strcmp(pathname, "/.") || !strcmp(pathname, "/..")) {
      searched_record->parent_dir = &root_dir;
      searched_record->file_type = FT_DIRECTORY;
      searched_record->searched_path[0] = 0;	   // 搜索路径置空
      return 0;
   }

   uint32_t path_len = strlen(pathname);
   /* 保证pathname至少是这样的路径/x且小于最大长度 */
   ASSERT(pathname[0] == '/' && path_len > 1 && path_len < MAX_PATH_LEN);
   char* sub_path = (char*)pathname;
   struct dir* parent_dir = &root_dir;	
   struct dir_entry dir_e;

   /* 记录路径解析出来的各级名称,如路径"/a/b/c",
    * 数组name每次的值分别是"a","b","c" */
   char name[MAX_FILE_NAME_LEN] = {0};

   searched_record->parent_dir = parent_dir;
   searched_record->file_type = FT_UNKNOWN;
   uint32_t parent_inode_no = 0;  // 父目录的inode号
   
   sub_path = path_parse(sub_path, name);
   while (name[0]) {	   // 若第一个字符就是结束符,结束循环
      /* 记录查找过的路径,但不能超过searched_path的长度512字节 */
      ASSERT(strlen(searched_record->searched_path) < 512);

      /* 记录已存在的父目录 */
      strcat(searched_record->searched_path, "/");
      strcat(searched_record->searched_path, name);

      /* 在所给的目录中查找文件 */
      if (search_dir_entry(cur_part, parent_dir, name, &dir_e)) {
	 memset(name, 0, MAX_FILE_NAME_LEN);
	 /* 若sub_path不等于NULL,也就是未结束时继续拆分路径 */
	 if (sub_path) {
	    sub_path = path_parse(sub_path, name);
	 }

	 if (FT_DIRECTORY == dir_e.f_type) {   // 如果被打开的是目录
	    parent_inode_no = parent_dir->inode->i_no;
	    dir_close(parent_dir);
	    parent_dir = dir_open(cur_part, dir_e.i_no); // 更新父目录
	    searched_record->parent_dir = parent_dir;
	    continue;
	 } else if (FT_REGULAR == dir_e.f_type) {	 // 若是普通文件
	    searched_record->file_type = FT_REGULAR;
	    return dir_e.i_no;
	 }
      } else {		   //若找不到,则返回-1
	 /* 找不到目录项时,要留着parent_dir不要关闭,
	  * 若是创建新文件的话需要在parent_dir中创建 */
	 return -1;
      }
   }

   /* 执行到此,必然是遍历了完整路径并且查找的文件或目录只有同名目录存在 */
   dir_close(searched_record->parent_dir);	      

   /* 保存被查找目录的直接父目录 */
   searched_record->parent_dir = dir_open(cur_part, parent_inode_no);	   
   searched_record->file_type = FT_DIRECTORY;
   return dir_e.i_no;
}
Beispiel #21
0
void
timestamp( 
	char	*target,
	time_t	*time )
{
	PATHNAME f1, f2;
	BINDING	binding, *b = &binding;
	string buf[1];

# ifdef DOWNSHIFT_PATHS
        string path; 
	char *p;

        string_copy( &path, target );
        p = path.value;

	do
            *p = tolower( *p );
	while( *p++ );

	target = path.value;
# endif
        string_new( buf );

	if( !bindhash )
	    bindhash = hashinit( sizeof( BINDING ), "bindings" );

	/* Quick path - is it there? */

	b->name = target;
	b->time = b->flags = 0;
	b->progress = BIND_INIT;

	if( hashenter( bindhash, (HASHDATA **)&b ) )
	    b->name = newstr( target );		/* never freed */

	if( b->progress != BIND_INIT )
	    goto afterscanning;

	b->progress = BIND_NOENTRY;

	/* Not found - have to scan for it */

	path_parse( target, &f1 );

	/* Scan directory if not already done so */

	{
	    BINDING binding, *b = &binding;

	    f2 = f1;
	    f2.f_grist.len = 0;
	    path_parent( &f2 );
	    path_build( &f2, buf, 0 );

	    b->name = buf->value;
	    b->time = b->flags = 0;
	    b->progress = BIND_INIT;

	    if( hashenter( bindhash, (HASHDATA **)&b ) )
		b->name = newstr( buf->value );	/* never freed */

	    if( !( b->flags & BIND_SCANNED ) )
	    {
		file_dirscan( buf->value, time_enter, bindhash );
		b->flags |= BIND_SCANNED;
	    }
	}

	/* Scan archive if not already done so */

	if( f1.f_member.len )
	{
	    BINDING binding, *b = &binding;

	    f2 = f1;
	    f2.f_grist.len = 0;
	    f2.f_member.len = 0;
            string_truncate( buf, 0 );
	    path_build( &f2, buf, 0 );

	    b->name = buf->value;
	    b->time = b->flags = 0;
	    b->progress = BIND_INIT;

	    if( hashenter( bindhash, (HASHDATA **)&b ) )
		b->name = newstr( buf->value );	/* never freed */

	    if( !( b->flags & BIND_SCANNED ) )
	    {
		file_archscan( buf->value, time_enter, bindhash );
		b->flags |= BIND_SCANNED;
	    }
	}

    afterscanning:

	if( b->progress == BIND_SPOTTED )
	{
	    if( file_time( b->name, &b->time ) < 0 )
		b->progress = BIND_MISSING;
	    else
		b->progress = BIND_FOUND;
	}

	*time = b->progress == BIND_FOUND ? b->time : 0;
        string_free( buf );
# ifdef DOWNSHIFT_PATHS
        string_free( &path );
#endif
}
Beispiel #22
0
static int filesystem_readdir(const char *path, void *buffer, fuse_fill_dir_t fill_dir,
                              off_t offset, struct fuse_file_info *file_info) {
    int retstat = 0;
    //	DIR *dp;
    //	struct dirent *de;

    logging_log("Filesystem", LOGGING_LEVEL_INFO,
                "filesystem_readdir(path=\"%s\", buf=0x%08x, filler=0x%08x, offset=%ld, fi=0x%08x)...",
                path, buffer, fill_dir, offset, file_info);

    if(!strcmp(path, "/")) {
        pthread_mutex_lock(filesystem_io_mutex);
        ArrayList *search_dirs = searcher_get_searches();
        pthread_mutex_unlock(filesystem_io_mutex);
        if(search_dirs != NULL) {
            for(size_t i = 0; i < array_list_get_length(search_dirs); i++) {
                char *name;
                array_list_get(search_dirs, (const void **)&name, i);

                if(fill_dir(buffer, name, NULL, 0) != 0) {
                    array_list_free(search_dirs);
                    return -ENOMEM;
                }
            }
            array_list_free(search_dirs);
        }
    } else {
        path_t *path_parsed = path_parse(path);

        logging_log("Filesystem", LOGGING_LEVEL_INFO, "path_parsed->parts_length: %lu...",
                    path_parsed->parts_length);
        if(path_parsed->parts_length) {
            pthread_mutex_lock(filesystem_io_mutex);
            ALDictionary *results = searcher_get_search_results(path_parsed->parts[0]);
            if(results != NULL) {
                logging_log("Filesystem", LOGGING_LEVEL_INFO, "results != NULL...");
                ALDictionaryEnumerator *e = al_dictionary_get_enumerator(results);
                while(al_dictionary_enumerator_move_next(e)) {
                    ALDictionaryKeyValuePair *pair;
                    al_dictionary_enumerator_get_current(e, &pair);

                    logging_log("Filesystem", LOGGING_LEVEL_INFO, "pair->key: %s...",
                                (char*)pair->key);
                    if(fill_dir(buffer, (char*)pair->key, NULL, 0) != 0) {
                        al_dictionary_enumerator_free(e);
                        path_free(path_parsed);
                        pthread_mutex_unlock(filesystem_io_mutex);
                        return -ENOMEM;
                    }
                }
                al_dictionary_enumerator_free(e);
            } else
                retstat = -1;
            pthread_mutex_unlock(filesystem_io_mutex);
        } else
            retstat = -1;
        path_free(path_parsed);
    }

    return retstat;
}
Beispiel #23
0
static int filesystem_getattr(const char *path, struct stat *statbuf) {
    int retstat;

    logging_log("Filesystem", LOGGING_LEVEL_INFO,
                "filesystem_getattr(path=\"%s\", statbuf=0x%08x)", path, statbuf);

    struct timeval tv;
    gettimeofday(&tv, NULL);

    struct timespec ts;
    ts.tv_nsec = tv.tv_usec * 1000;
    ts.tv_sec = tv.tv_sec;

    statbuf->st_uid = getuid();
    statbuf->st_size = 0;
    statbuf->st_rdev = 0;
    statbuf->st_nlink = 0;
    statbuf->st_mtime = ts.tv_sec;
    statbuf->st_mtimensec = ts.tv_nsec;
    statbuf->st_ino = 0;
    statbuf->st_gid = getgid();
    statbuf->st_dev = 0;
    statbuf->st_ctime = ts.tv_sec;
    statbuf->st_ctimensec = ts.tv_nsec;
    statbuf->st_blocks = 0;
    statbuf->st_blksize = 0;
    statbuf->st_atime = ts.tv_sec;
    statbuf->st_atimensec = ts.tv_nsec;

    path_t *path_parsed = path_parse(path);

    logging_log("Filesystem", LOGGING_LEVEL_INFO, "path_parsed->parts_length: %lu...",
                path_parsed->parts_length);

    switch(path_parsed->parts_length) {
    case 0: {
        logging_log("Filesystem", LOGGING_LEVEL_INFO, "filesystem_getattr() - /...");
        statbuf->st_mode = configuration->filesystem_directory_mode;
        retstat = 0;
        break;
    }
    case 1: {
        if(!strcmp(path_parsed->parts[0], "search")) {
            retstat = 0;
            statbuf->st_mode = configuration->filesystem_directory_mode;
            break;
        }
        //			if(path_parsed->parts[0][0] == '.')
        //				retstat = -1;
        //			else {
        //				statbuf->st_mode = FILESYSTEM_DIRECTORY_MODE;
        //				retstat = 0;
        //			}
        pthread_mutex_lock(filesystem_io_mutex);
        ArrayList *search_dirs = searcher_get_searches();
        pthread_mutex_unlock(filesystem_io_mutex);
        if(search_dirs != NULL) {
            retstat = -1;
            for(size_t i = 0; i < array_list_get_length(search_dirs); i++) {
                char *name;
                array_list_get(search_dirs, (const void **)&name, i);

                if(!strcmp(path_parsed->parts[0], name)) {
                    retstat = 0;
                    statbuf->st_mode = configuration->filesystem_directory_mode;
                    goto for_end;
                }
            }
for_end:
            ;
            array_list_free(search_dirs);
        } else
            retstat = -1;
        break;
    }
    case 2: {
        if(!strcmp(path_parsed->parts[0], "search"))
            if(strlen(path_parsed->parts[0]) > 3) {
                ALDictionary *value = searcher_file_name_url_dictionary_get(path_parsed->parts[1]);
                pthread_mutex_lock(filesystem_io_mutex);
                searcher_add_search(path_parsed->parts[1], value);
                pthread_mutex_unlock(filesystem_io_mutex);
                retstat = 0;
                statbuf->st_mode = configuration->filesystem_file_mode;
                break;
            }

        pthread_mutex_lock(filesystem_io_mutex);
        ALDictionary *results = searcher_get_search_results(path_parsed->parts[0]);
        if(results != NULL) {
            logging_log("Filesystem", LOGGING_LEVEL_INFO, "results != NULL...");

            char result;
            char *url = (char*)al_dictionary_get(results, &result, path_parsed->parts[1]);

            if(result) {
                logging_log("Filesystem", LOGGING_LEVEL_INFO, "Invalid file %s...", path);
                retstat = -1;
            } else {
                logging_log("Filesystem", LOGGING_LEVEL_INFO, "Url is %s...", url);

                retstat = 0;
                statbuf->st_mode = configuration->filesystem_file_mode;
                statbuf->st_size = downloader_file_size_try_get(url);
            }
        } else
            retstat = -1;
        pthread_mutex_unlock(filesystem_io_mutex);
        break;
    }
    default: {
        break;
    }
    }
    path_free(path_parsed);

    logging_log("Filesystem", LOGGING_LEVEL_INFO, "filesystem_getattr() finished...");

    return retstat;
}
Beispiel #24
0
OBJECT *
search(
    OBJECT * target,
    time_t *time,
    OBJECT * * another_target,
    int file
)
{
    PATHNAME f[1];
    LIST   * varlist;
    string   buf[1];
    int      found = 0;
    /* Will be set to 1 if target location is specified via LOCATE. */
    int      explicitly_located = 0;
    OBJECT * boundname = 0;
    OBJECT * varname;

    if ( another_target )
        *another_target = 0;

    if (! explicit_bindings )
        explicit_bindings = hashinit( sizeof(BINDING),
                                      "explicitly specified locations");

    string_new( buf );
    /* Parse the filename */

    path_parse( object_str( target ), f );

    f->f_grist.ptr = 0;
    f->f_grist.len = 0;

    varname = object_new( "LOCATE" );
    varlist = var_get( varname );
    object_free( varname );
    if ( varlist )
    {
        OBJECT * key;
        f->f_root.ptr = object_str( varlist->value );
        f->f_root.len = strlen( object_str( varlist->value ) );

        path_build( f, buf, 1 );

        if ( DEBUG_SEARCH )
            printf( "locate %s: %s\n", object_str( target ), buf->value );

        explicitly_located = 1;

        key = object_new( buf->value );
        timestamp( key, time );
        object_free( key );
        found = 1;
    }
    else if ( ( varname = object_new( "SEARCH" ),
                varlist = var_get( varname ),
                object_free( varname ),
                varlist ) )
    {
        while ( varlist )
        {
            BINDING b, *ba = &b;
            file_info_t *ff;
            OBJECT * key;
            OBJECT * test_path;

            f->f_root.ptr = object_str( varlist->value );
            f->f_root.len = strlen( object_str( varlist->value ) );

            string_truncate( buf, 0 );
            path_build( f, buf, 1 );

            if ( DEBUG_SEARCH )
                printf( "search %s: %s\n", object_str( target ), buf->value );

            test_path = object_new( buf->value );
            key = path_as_key( test_path );
            object_free( test_path );
            ff = file_query( key );
            timestamp( key, time );

            b.binding = key;

            if ( hashcheck( explicit_bindings, (HASHDATA**)&ba ) )
            {
                if ( DEBUG_SEARCH )
                    printf(" search %s: found explicitly located target %s\n",
                           object_str( target ), object_str( ba->target ) );
                if ( another_target )
                    *another_target = ba->target;
                found = 1;
                object_free( key );
                break;
            }
            else if ( ff && ff->time )
            {
                if ( !file || ff->is_file )
                {
                    found = 1;
                    object_free( key );
                    break;
                }
            }
            object_free( key );

            varlist = list_next( varlist );
        }
    }

    if ( !found )
    {
        /* Look for the obvious */
        /* This is a questionable move.  Should we look in the */
        /* obvious place if SEARCH is set? */
        OBJECT * key;

        f->f_root.ptr = 0;
        f->f_root.len = 0;

        string_truncate( buf, 0 );
        path_build( f, buf, 1 );

        if ( DEBUG_SEARCH )
            printf( "search %s: %s\n", object_str( target ), buf->value );

        key = object_new( buf->value );
        timestamp( key, time );
        object_free( key );
    }

    boundname = object_new( buf->value );
    string_free( buf );

    if ( explicitly_located )
    {
        BINDING b;
        BINDING * ba = &b;
        OBJECT * key = path_as_key( boundname );
        b.binding = key;
        b.target = target;
        /* CONSIDER: we probably should issue a warning is another file
           is explicitly bound to the same location. This might break
           compatibility, though. */
        if ( !hashenter( explicit_bindings, (HASHDATA * *)&ba ) )
        {
            object_free( key );
        }
    }

    /* prepare a call to BINDRULE if the variable is set */
    call_bind_rule( target, boundname );

    return boundname;
}
Beispiel #25
0
static const char *
search_helper( 
	   const char *target,
	   time_t	*time,
	   LIST *(*varget)( const char*, void* ),
	   void *userData,
	   int uncached )
{
	PATHNAME f[1];
	LIST	*varlist;
	char	buf[ MAXJPATH ];
#ifdef OPT_PATH_BINDING_EXT
	PATHNAME bf[1];
#endif
	
	/* Parse the filename */
	
	path_parse( target, f );
	
	f->f_grist.ptr = 0;
	f->f_grist.len = 0;
	
#ifdef OPT_PATH_BINDING_EXT
	if ( list_first(varlist = varget( "BINDING", userData )) )
	{
		path_parse( list_value(list_first(varlist)), bf );
		
		f->f_dir = bf->f_dir;
		f->f_base = bf->f_base;
		f->f_suffix = bf->f_suffix;
	}
#endif
	
	if( list_first(varlist = varget( "LOCATE", userData )) )
	{
		f->f_root.ptr = list_value(list_first(varlist));
		f->f_root.len = (int)(strlen( list_value(list_first(varlist)) ));
		
#ifdef OPT_ROOT_PATHS_AS_ABSOLUTE_EXT
		path_build( f, buf, 1, 1 );
#else
		path_build( f, buf, 1 );
#endif
		
		if( DEBUG_SEARCH )
			printf( "locate %s: %s\n", target, buf );
		
		if ( uncached )
		{
			file_time( buf, time );
		}
		else
		{
			timestamp( buf, time, 0 );
		}
		
		return newstr( buf );
	}
	else if( list_first(varlist = varget( "SEARCH", userData )) )
	{
		LIST *searchextensionslist;
		LISTITEM* var = list_first(varlist);
		while( var )
		{
			f->f_root.ptr = list_value(var);
			f->f_root.len = (int)(strlen( list_value(var) ));
			
#ifdef OPT_ROOT_PATHS_AS_ABSOLUTE_EXT
			path_build( f, buf, 1, 1 );
#else
			path_build( f, buf, 1 );
#endif
			
			if( DEBUG_SEARCH )
				printf( "search %s: %s\n", target, buf );
			
			if ( uncached )
			{
				file_time( buf, time );
			}
			else
			{
				timestamp( buf, time, 0 );
			}
			
			if( *time )
				return newstr( buf );
			
			var = list_next( var );
		}
		
		searchextensionslist = varget( "SEARCH_EXTENSIONS", userData );
		if ( list_first(searchextensionslist) )
		{
			LISTITEM* ext = list_first(searchextensionslist);
			for ( ; ext; ext = list_next(ext) )
			{
				LISTITEM* var = list_first(varlist);
				while( var )
				{
					f->f_root.ptr = list_value(var);
					f->f_root.len = (int)(strlen( list_value(var) ));
					
#ifdef OPT_ROOT_PATHS_AS_ABSOLUTE_EXT
					strcpy( path_build( f, buf, 1, 1 ), list_value(ext) );
#else
					strcpy( path_build( f, buf, 1 ), list_value(ext) );
#endif
					
					if( DEBUG_SEARCH )
						printf( "search %s: %s\n", target, buf );
					
					if ( uncached )
					{
						file_time( buf, time );
					}
					else
					{
						timestamp( buf, time, 0 );
					}
					
					if( *time )
						return newstr( buf );
					
					var = list_next( var );
				}
			}
		}			
	}
	
	/* Look for the obvious */
	/* This is a questionable move.  Should we look in the */
	/* obvious place if SEARCH is set? */
	
	f->f_root.ptr = 0;
	f->f_root.len = 0;
	
#ifdef OPT_ROOT_PATHS_AS_ABSOLUTE_EXT
	path_build( f, buf, 1, 1 );
#else
	path_build( f, buf, 1 );
#endif
	
	if( DEBUG_SEARCH )
		printf( "search %s: %s\n", target, buf );
	
	if ( uncached )
	{
		file_time( buf, time );
	}
	else
	{
		timestamp( buf, time, 0 );
	}
	
	return newstr( buf );
}
Beispiel #26
0
TARGET* search_for_target ( char * name, LIST* search_path )
{
    PATHNAME f[1];
    string buf[1];
    LOCATED_TARGET lt, *lta = &lt;
    time_t time;
    int found = 0;
    TARGET* result;

    string_new( buf );

	path_parse( name, f );

    f->f_grist.ptr = 0;
    f->f_grist.len = 0;

    while( search_path )
    {
        f->f_root.ptr = search_path->string;
        f->f_root.len = strlen( search_path->string );

        string_truncate( buf, 0 );
        path_build( f, buf, 1 );

        lt.file_name = buf->value ;

        if (! located_targets )
            located_targets = hashinit( sizeof(LOCATED_TARGET),
                                        "located targets" );


        if ( hashcheck( located_targets, (HASHDATA **)&lta ) )
        {
            return lta->target;
        }

        timestamp( buf->value, &time );
        if (time)
        {
            found = 1;
            break;
        }

        search_path = list_next( search_path );
    }

    if ( ! found )
    {
        f->f_root.ptr = 0;
        f->f_root.len = 0;

        string_truncate( buf, 0 );
        path_build( f, buf, 1 );

        timestamp( buf->value, &time );        
    }

    result = bindtarget( name );
    result->boundname = newstr( buf->value );
    result->time = time;
    result->binding = time ? T_BIND_EXISTS : T_BIND_MISSING;

    call_bind_rule( result->name, result->boundname );
    
    string_free( buf );

    return result;

}
Beispiel #27
0
const char *search(const char *source, const char *_header, time_t *time)
{
	PATHNAME f[1];
	char buf[MAXJPATH];
	char buf2[MAXSYM], *header = buf2;
	char buf3[MAXJPATH];
	int system = (_header[0] == '<');
	LIST *list = searchdirs->next;
	
	/* D support */
	int dMode=0;
	int fnlen=strlen(source);
	if(source[fnlen-2]=='.' && source[fnlen-1]=='d')
		dMode=1;

	/* <foo.h> --> foo.h */
	strcpy(header, _header + 1);
	header[strlen(header) - 1] = '\0';

	/* src/foo.c --> src */
	path_parse(source, f);
	path_parent(f);
	path_build(f, buf3, 1);

	/* C::B patch: Fix bug with usage of root folder */
# if PATH_DELIM == '\\'
	/* Special case for D:/ - dirname is D:/, not "D:" */
	if ((strlen(buf3)==3) && (buf3[1]==':') && ((buf3[2]=='\\') || (buf3[2]=='/')))
		buf3[2] = 0;
# endif

	if (DEBUG_SEARCH)
		printf( "search %s\n  included by %s\n", _header, source);

#ifdef SEARCH_OPTIM
	{
		char key[MAXJPATH] = "";
		SEARCH search, *s = &search;
		if (!system)
		{
			strcpy(key, buf3);
			strcat(key, ",");
		}
		strcat(key, _header);
		s->key = key;
		if (!searchhash)
			searchhash = hashinit(sizeof(SEARCH), "search");
		if (hashcheck(searchhash, (HASHDATA **)&s))
		{
			if (DEBUG_SEARCH)
				printf("  %s: %s [CACHED]\n", _header, s->time ? s->path : "*missing*" );
			*time = s->time;
			return s->path;
		}
	}
#endif

	/* If this is "foo.h" not <foo.h> then set the first search directory
	 * to the including file's directory */
	if (!system)
	{
		searchdirs->string = buf3;
		list = searchdirs;
	}

	path_parse(header, f);

	f->f_grist.ptr = 0;
	f->f_grist.len = 0;
	
	for (; list; list = list->next)
	{
		f->f_root.ptr = list->string;
		f->f_root.len = strlen(list->string);

		path_build(f, buf, 1);

{
PATHSPLIT f;
char buf2[MAXJPATH];
path_split(buf, &f);
path_normalize(&f, NULL);
path_tostring(&f, buf2);
strcpy(buf, buf2);
}

		if (DEBUG_SEARCH)
			printf("  %s: %s [TRY]\n", _header, buf);

		timestamp(buf, time);

#ifdef SEARCH_OPTIM
		if (*time)
		{
			char key[MAXJPATH] = "";
			SEARCH search, *s = &search;
			if (!system)
			{
				strcpy(key, buf3);
				strcat(key, ",");
			}
			strcat(key, _header);
			s->key = newstr(key);
			s->time = *time;
			s->path = newstr(buf);
			(void) hashenter(searchhash, (HASHDATA **)&s);
		}
#endif

		if (*time)
			return newstr(buf);
	}

	if(!dMode)
	{
#ifdef SEARCH_OPTIM
		/* remember that this file could not be found */
		{
			char key[MAXJPATH] = "";
			SEARCH search, *s = &search;
			if (!system)
			{
				strcpy(key, buf3);
				strcat(key, ",");
			}
			strcat(key, _header);
			s->key = newstr(key);
			s->time = 0;
			s->path = NULL;
			(void) hashenter(searchhash, (HASHDATA **)&s);
		}
#endif

		/* C compilers do *not* look in the current directory for #include files */
		*time = 0;
		return NULL;
	}
	/* D support (look in current directory) */
	else
	{
		f->f_root.ptr = 0;
		f->f_root.len = 0;

		path_build( f, buf, 1 );

{
PATHSPLIT f;
char buf2[MAXJPATH];
path_split(buf, &f);
path_normalize(&f, NULL);
path_tostring(&f, buf2);
strcpy(buf, buf2);
}

		if( DEBUG_SEARCH )
			printf( "search %s: %s\n", _header, buf );

		timestamp( buf, time );


#ifdef SEARCH_OPTIM
		if (*time)
		{
			char key[MAXJPATH] = "";
			SEARCH search, *s = &search;
			if (!system)
			{
				strcpy(key, buf3);
				strcat(key, ",");
			}
			strcat(key, _header);
			s->key = newstr(key);
			s->time = *time;
			s->path = newstr(buf);
			(void) hashenter(searchhash, (HASHDATA **)&s);
		}
#endif

		if (*time)
			return newstr(buf);
		
#ifdef SEARCH_OPTIM
		/* remember that this file could not be found */
		{
			char key[MAXJPATH] = "";
			SEARCH search, *s = &search;
			if (!system)
			{
				strcpy(key, buf3);
				strcat(key, ",");
			}
			strcat(key, _header);
			s->key = newstr(key);
			s->time = 0;
			s->path = NULL;
			(void) hashenter(searchhash, (HASHDATA **)&s);
		}
#endif

		*time = 0;
		return NULL;
	}
}
Beispiel #28
0
int parseRequest(int client, request_t* req, response_t* resp)
{
        enum {
                REQ_METHOD,
                REQ_PATH,
                REQ_HTTPVERSION,
                REQ_ARGS_NAME,
                REQ_ARGS_VALUE,
                REQ_REQLINE_LF,
                REQ_HEADER_NAME,
                REQ_HEADER_VALUE_START,
                REQ_HEADER_VALUE,
                REQ_HEADER_LF,
                REQ_HEADERS_END_LF,
                REQ_BODY,
        };

#define BUFLEN 512
        int state = REQ_METHOD;
        char buffer[BUFLEN];
        int count = 0;
        char c;
        int r;
        pair_t* p;

        while (1) {

                if (state == REQ_BODY)
                        break;
                
                r = read(client, &c, 1);
                
                if (r == 0) {
                        if (state == REQ_BODY)
                                return 0;
                        else {
                                log_err("Daemon: Unexpected end of request");
                                resp->status = 400;
                                return -1;
                        }
                }
                if (r == -1) {
                        log_err("Daemon: Failed to parse the request");
                        resp->status = 400;
                        return -1;
                }
                
                switch (state) {

                case REQ_METHOD: 
                        if (c == ' ') {
                                buffer[count] = 0;
                                if (strcmp(buffer, "GET") == 0)
                                        req->method = HTTP_GET;
                                else if (strcmp(buffer, "PUT") == 0)
                                        req->method = HTTP_PUT;
                                else if (strcmp(buffer, "POST") == 0)
                                        req->method = HTTP_POST;
                                else
                                        req->method = HTTP_UNKNOWN;
                                count = 0;
                                state = REQ_PATH;

                        } else if ((c == '\r') || (c == '\n')) {
                                log_warn("Daemon: Bad request: %s\n", buffer);
                                resp->status = 400;
                                return -1;
                                
                        } else if (count < BUFLEN-1) {
                                buffer[count++] = (char) c;

                        } else {
                                buffer[BUFLEN-1] = 0;
                                log_warn("Daemon: Request line too long: %s\n", buffer);
                                resp->status = 400;
                                return -1;
                        }
                        break;

                case REQ_PATH: 
                        if (c == ' ') {
                                buffer[count++] = 0;
                                req->path = (char *)malloc(count);
                                if (req->path == NULL) {
                                        log_err("Out of memory");
                                        return -1;
                                }
                                memcpy(req->path, buffer, count);
                                count = 0;
                                state = REQ_HTTPVERSION;

                        } else if (c == '?') {
                                buffer[count++] = 0;
                                req->path = (char *) malloc(count);
                                memcpy(req->path, buffer, count);
                                count = 0;
                                state = REQ_ARGS_NAME;

                        } else if ((c == '\r') || (c == '\n')) {
                                log_warn("Daemon: Bad request: %s\n", buffer);
                                resp->status = 400;
                                return -1;

                        } else if (count < BUFLEN-1) {
                                buffer[count++] = (char) c;
                        } else {
                                buffer[BUFLEN-1] = 0;
                                log_warn("Daemon: Requested path too long: %s\n", buffer);
                                resp->status = 400;
                                return -1;
                        }
                        break;

                case REQ_ARGS_NAME: 
                        if (c == ' ') {
                                buffer[count++] = 0;
                                count = 0;
                                p = new_pair_dup(buffer, NULL);
                                req->args = list_append(req->args, p);
                                state = REQ_HTTPVERSION;
                                
                        } else if (c == '=') {
                                buffer[count++] = 0;
                                count = 0;
                                p = new_pair_dup(buffer, NULL);
                                state = REQ_ARGS_VALUE;

                        } else if (c == '&') {
                                buffer[count++] = 0;
                                count = 0;
                                p = new_pair_dup(buffer, NULL);
                                req->args = list_append(req->args, p);
                                state = REQ_ARGS_NAME;

                        } else if ((c == '\r') || (c == '\n')) {
                                log_warn("Daemon: Bad request: %s\n", buffer);
                                resp->status = 400;
                                return -1;
                        } else if (count < BUFLEN-1) {
                                buffer[count++] = (char) c;
                        } else {
                                buffer[BUFLEN-1] = 0;
                                log_warn("Daemon: Requested path too long: %s\n", buffer);
                                resp->status = 400;
                                return -1;
                        }
                        break;

                case REQ_ARGS_VALUE: 
                        if (c == ' ') {
                                if (count > 0) {
                                        buffer[count++] = 0;
                                        count = 0;
                                        p->value = strdup(buffer);
                                        if (p->value == NULL) {
                                                log_err("Out of memory");
                                        }
                                } else {
                                        log_warn("Args: missing value for name: %s\n", p->name);
                                        p->value = NULL;
                                        buffer[count++] = 0;
                                        count = 0;
                                }
                                req->args = list_append(req->args, p);
                                state = REQ_HTTPVERSION;
                                
                        } else if (c == '&') {
                                if (count > 0) {
                                        buffer[count++] = 0;
                                        count = 0;
                                        p->value = strdup(buffer);
                                        if (p->value == NULL) {
                                                log_err("Out of memory");
                                        }
                                } else {
                                        log_warn("Args: missing value for name: %s\n", p->name);
                                        p->value = NULL;
                                        buffer[count++] = 0;
                                        count = 0;
                                }
                                req->args = list_append(req->args, p);
                                state = REQ_ARGS_NAME;

                        } else if ((c == '\r') || (c == '\n')) {
                                log_warn("Daemon: Bad request: %s\n", buffer);
                                resp->status = 400;
                                return -1;
                        } else if (count < BUFLEN-1) {
                                buffer[count++] = (char) c;
                        } else {
                                buffer[BUFLEN-1] = 0;
                                log_warn("Daemon: Requested path too long: %s\n", buffer);
                                resp->status = 400;
                                return -1;
                        }
                        break;

                case REQ_HTTPVERSION: 
                        if (c == '\n') {
                                buffer[count] = 0;
                                // check HTTP version? Not needed in this app...
                                count = 0;
                                state = REQ_HEADER_NAME;
                        } else if (c == '\r') {
                                buffer[count] = 0;
                                // check HTTP version? Not needed in this app...
                                count = 0;
                                state = REQ_REQLINE_LF;
                        } else if (strchr("HTTP/1.0", c) == NULL) {
                                log_warn("Daemon: Invalid HTTP version string\n");
                                resp->status = 400;
                                return -1;
                        } else {
                                buffer[count++] = (char) c;
                        }
                        break;

                case REQ_REQLINE_LF: 
                        if (c != '\n') {
                                log_warn("Daemon: Invalid HTTP version string\n");
                                resp->status = 400;
                                return -1;
                        } else {
                                count = 0;
                                state = REQ_HEADER_NAME;
                        }
                        break;

                case REQ_HEADER_NAME: 
                        if ((c == '\n') && (count == 0)) {
                                state = REQ_BODY;
                                
                        } else if ((c == '\r') && (count == 0)) {
                                state = REQ_HEADERS_END_LF;
                                
                        } else if (c == ':') {
                                buffer[count++] = 0;
                                count = 0;
                                p = new_pair_dup(buffer, NULL);
                                state = REQ_HEADER_VALUE_START;

                        } else if (count < BUFLEN-1) {
                                buffer[count++] = (char) c;

                        } else {
                                buffer[BUFLEN-1] = 0;
                                log_warn("Daemon: Header name too long: %s\n", buffer);
                                resp->status = 400;
                                return -1;
                        }
                        break;

                case REQ_HEADER_VALUE_START: 
                        if ((c == ' ') || (c == '\t')) {
                                // Do nothing

                        } else if (c == '\r') {
                                log_warn("Daemon: Bad header: %s\n", p->name);
                                resp->status = 400;
                                return -1;

                        } else if (c == '\n') {
                                log_warn("Daemon: Bad header: %s\n", p->name);
                                resp->status = 400;
                                return -1;
                                
                        } else if (count < BUFLEN-1) {
                                buffer[0] = (char) c;
                                count = 1;
                                state = REQ_HEADER_VALUE;
                        }
                        break;

                case REQ_HEADER_VALUE: 
                        if (c == '\r') {
                                buffer[count++] = 0;
                                count = 0;
                                p->value = strdup(buffer);
                                req->headers = list_append(req->headers, p);
                                state = REQ_HEADER_LF;

                        } else if (c == '\n') {
                                buffer[count++] = 0;
                                count = 0;
                                p->value = strdup(buffer);
                                req->headers = list_append(req->headers, p);
                                state = REQ_HEADER_NAME;
                                
                        } else if (count < BUFLEN-1) {
                                buffer[count++] = (char) c;

                        } else {
                                buffer[BUFLEN-1] = 0;
                                log_warn("Daemon: Header value too long: %s\n", buffer);
                                resp->status = 400;
                                return -1;
                        }
                        break;
 
                case REQ_HEADER_LF: 
                        if (c != '\n') {
                                log_warn("Daemon: Invalid HTTP header\n");
                                resp->status = 400;
                                return -1;
                        } else {
                                count = 0;
                                state = REQ_HEADER_NAME;
                        }
                        break;

                case REQ_HEADERS_END_LF: 
                        if (c != '\n') {
                                log_warn("Daemon: Invalid HTTP header\n");
                                resp->status = 400;
                                return -1;
                        } else {
                                count = 0;
                                state = REQ_BODY;
                        }
                        break;
                }
       }

        r = path_parse(req->path, &req->pathnodes);
        if (r != 0) {
                resp->status = 400;
                return -1;
        }

        int content_length = request_content_length(req);
        if (content_length == -1) {
                log_err("Failed to determine the content length");
                resp->status = 400;
                return -1;
        }

        for (int i = 0; i < content_length; i++) {
                r = read(client, &c, 1);
                if (request_append(req, c) != 0)
                        return -1;
        }

        return 0;
}
Beispiel #29
0
path_t path_copy(path_t p)
{
  return path_parse(path_json(p),0);
}
Beispiel #30
0
static void exe_n_cwd_tab_completion(char *command, int type)
{
	DIR *dir;
	struct dirent *next;
	char dirbuf[MAX_LINELEN];
	struct stat st;
	char *path1[1];
	char **paths = path1;
	int npaths;
	int i;
	char *found;
	char *pfind = strrchr(command, '/');

	npaths = 1;
	path1[0] = (char*)".";

	if (pfind == NULL) {
		/* no dir, if flags==EXE_ONLY - get paths, else "." */
		npaths = path_parse(&paths, type);
		pfind = command;
	} else {
		/* dirbuf = ".../.../.../" */
		safe_strncpy(dirbuf, command, (pfind - command) + 2);
#if ENABLE_FEATURE_USERNAME_COMPLETION
		if (dirbuf[0] == '~')   /* ~/... or ~user/... */
			username_tab_completion(dirbuf, dirbuf);
#endif
		paths[0] = dirbuf;
		/* point to 'l' in "..../last_component" */
		pfind++;
	}

	for (i = 0; i < npaths; i++) {
		dir = opendir(paths[i]);
		if (!dir)                       /* Don't print an error */
			continue;

		while ((next = readdir(dir)) != NULL) {
			int len1;
			const char *str_found = next->d_name;

			/* matched? */
			if (strncmp(str_found, pfind, strlen(pfind)))
				continue;
			/* not see .name without .match */
			if (*str_found == '.' && *pfind == 0) {
				if (NOT_LONE_CHAR(paths[i], '/') || str_found[1])
					continue;
				str_found = ""; /* only "/" */
			}
			found = concat_path_file(paths[i], str_found);
			/* hmm, remover in progress? */
			if (stat(found, &st) < 0)
				goto cont;
			/* find with dirs? */
			if (paths[i] != dirbuf)
				strcpy(found, next->d_name);    /* only name */

			len1 = strlen(found);
			found = xrealloc(found, len1 + 2);
			found[len1] = '\0';
			found[len1+1] = '\0';

			if (S_ISDIR(st.st_mode)) {
				/* name is directory      */
				if (found[len1-1] != '/') {
					found[len1] = '/';
				}
			} else {
				/* not put found file if search only dirs for cd */
				if (type == FIND_DIR_ONLY)
					goto cont;
			}
			/* Add it to the list */
			add_match(found);
			continue;
 cont:
			free(found);
		}
		closedir(dir);
	}
	if (paths != path1) {
		free(paths[0]);                 /* allocated memory only in first member */
		free(paths);
	}
}