예제 #1
0
파일: gpmondb.c 프로젝트: karthijrk/gpdb
// Find all files start with 'gpdb-alert' under GPMON_LOG directory, sort it and
// remove the latest one 'gpdb-alert-*.csv' as it is still used by GPDB.
static void get_alert_log_tail_files(apr_array_header_t *tail_files, apr_pool_t *pool)
{
	apr_dir_t *dir;
	apr_status_t status = apr_dir_open(&dir, GPMON_LOG, pool);
	if (status != APR_SUCCESS)
	{
		gpmon_warningx(FLINE, status, "failed opening directory:%s", GPMON_LOG);
		return;
	}

	apr_finfo_t dirent;
	static const char gpdb_prefix[] = "gpdb-alert";
	while (apr_dir_read(&dirent, APR_FINFO_DIRENT, dir) == APR_SUCCESS)
	{
		if (strncmp(dirent.name, gpdb_prefix, sizeof(gpdb_prefix) - 1) == 0)
		{
			void *file_slot = apr_array_push(tail_files);
			if (! file_slot)
			{
				gpmon_warningx(FLINE, 0, "failed getting alert tail log:%s due to out of memory", dirent.name);
				continue;
			}
			(*(const char**)file_slot) = apr_pstrcat(pool, GPMON_LOG, "/", dirent.name, NULL);
		}
	}

	// We only want to use qsort in stdlib.h, not the macro qsort in port.h.
	(qsort)(tail_files->elts, tail_files->nelts, tail_files->elt_size, cmp_string);
	(void)apr_array_pop(tail_files);
	apr_dir_close(dir);
}
예제 #2
0
파일: lock.c 프로젝트: jmckenna/mapcache
void mapcache_locker_disk_clear_all_locks(mapcache_context *ctx, mapcache_locker *self) {
  mapcache_locker_disk *ldisk = (mapcache_locker_disk*)self;
  apr_dir_t *lockdir;
  char errmsg[120];
  apr_finfo_t finfo;
  apr_status_t rv = apr_dir_open(&lockdir,ldisk->dir,ctx->pool);
  if(rv != APR_SUCCESS) {
    ctx->set_error(ctx,500, "failed to open lock directory %s: %s" ,ldisk->dir,apr_strerror(rv,errmsg,120));
    return;
  }

  while ((apr_dir_read(&finfo, APR_FINFO_DIRENT|APR_FINFO_TYPE|APR_FINFO_NAME, lockdir)) == APR_SUCCESS) {
    if(finfo.filetype == APR_REG) {
      if(!strncmp(finfo.name, MAPCACHE_LOCKFILE_PREFIX, strlen(MAPCACHE_LOCKFILE_PREFIX))) {
        ctx->log(ctx,MAPCACHE_WARN,"found old lockfile %s/%s, deleting it",ldisk->dir,
            finfo.name);
        rv = apr_file_remove(apr_psprintf(ctx->pool,"%s/%s",ldisk->dir, finfo.name),ctx->pool);
        if(rv != APR_SUCCESS) {
          ctx->set_error(ctx,500, "failed to remove lockfile %s: %s",finfo.name,apr_strerror(rv,errmsg,120));
          return;
        }

      }

    }
  }
  apr_dir_close(lockdir);
}
예제 #3
0
static apt_bool_t test_dir_process(apt_test_suite_t *suite)
{
	apr_status_t rv;
	apr_dir_t *dir;

	const char *dir_name = "msg";
	if(apr_dir_open(&dir,dir_name,suite->pool) != APR_SUCCESS) {
		apt_log(APT_PRIO_WARNING,"Cannot Open Directory [%s]",dir_name);
		return FALSE;
	}

	do {
		apr_finfo_t finfo;
		rv = apr_dir_read(&finfo,APR_FINFO_DIRENT,dir);
		if(rv == APR_SUCCESS) {
			if(finfo.filetype == APR_REG && finfo.name) {
				char *file_path;
				apr_filepath_merge(&file_path,dir_name,finfo.name,0,suite->pool);
				test_file_process(suite,file_path);
			}
		}
	} 
	while(rv == APR_SUCCESS);

	apr_dir_close(dir);
	return TRUE;
}
예제 #4
0
static apt_bool_t test_dir_process(apt_test_suite_t *suite, mrcp_resource_factory_t *factory, mrcp_version_e version)
{
	apr_status_t rv;
	apr_dir_t *dir;

	const char *dir_name = "v2";
	if(version == MRCP_VERSION_1) {
		dir_name = "v1";
	}
	if(apr_dir_open(&dir,dir_name,suite->pool) != APR_SUCCESS) {
		apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Cannot Open Directory [%s]",dir_name);
		return FALSE;
	}

	do {
		apr_finfo_t finfo;
		rv = apr_dir_read(&finfo,APR_FINFO_DIRENT,dir);
		if(rv == APR_SUCCESS) {
			if(finfo.filetype == APR_REG && finfo.name) {
				char *file_path;
				apr_filepath_merge(&file_path,dir_name,finfo.name,0,suite->pool);
				test_file_process(suite,factory,version,file_path);
				printf("\nPress ENTER to continue\n");
				getchar();
			}
		}
	} 
	while(rv == APR_SUCCESS);

	apr_dir_close(dir);
	return TRUE;
}
예제 #5
0
파일: switch_apr.c 프로젝트: gujun/sscore
SWITCH_DECLARE(switch_status_t) switch_dir_close(switch_dir_t *thedir)
{
	switch_status_t status = apr_dir_close(thedir->dir_handle);

	free(thedir);
	return status;
}
예제 #6
0
static void test_opendir(abts_case *tc, void *data)
{
    apr_status_t rv;
    apr_dir_t *dir;

    rv = apr_dir_open(&dir, "data", p);
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
    apr_dir_close(dir);
}
예제 #7
0
파일: io.c 프로젝트: mah0x211/libkahana
apr_status_t kahanaIOReadDir( apr_pool_t *p, kDir_t **newDirObj, const char *path, apr_int32_t wanted, ... )
{
	apr_dir_t *dir = NULL;
	kDir_t *dirObj = NULL;
	apr_pool_t *sp = NULL;
	apr_status_t rc;
	
	if( ( rc = apr_dir_open( &dir, dirObj->path, p ) ) ){
		kahanaLogPut( NULL, NULL, "failed to apr_dir_open(): %s", STRERROR_APR( rc ) );
	}
	else if( ( rc = kahanaMalloc( p, sizeof( kDir_t ), (void**)&dirObj, &sp ) ) ){
		kahanaLogPut( NULL, NULL, "failed to kahanaMalloc(): %s", STRERROR_APR( rc ) );
	}
	else
	{
		apr_filetype_e type;
		va_list types;
		
		dirObj->p = sp;
		dirObj->files = apr_array_make( sp, 0, sizeof( apr_finfo_t ) );
		dirObj->path = (const char*)apr_pstrdup( sp, path );
		*newDirObj = dirObj;
		
		do
		{
			apr_finfo_t finfo = { 0 };
			
			if( ( rc = apr_dir_read( &finfo, wanted, dir ) ) ){
				kahanaLogPut( NULL, NULL, "failed to apr_dir_read(): %s", STRERROR_APR( rc ) );
				break;
			}
			else
			{
				va_start( types, wanted );
				while( ( type = va_arg( types, apr_filetype_e ) ) )
				{
					if( finfo.filetype == type ){
						APR_ARRAY_PUSH( dirObj->files, apr_finfo_t ) = finfo;
						break;
					}
				}
				va_end( types );
			}
		
		} while( rc == APR_SUCCESS );
		
		rc = ( rc == APR_ENOENT ) ? APR_SUCCESS : rc;
		if( ( rc = apr_dir_close( dir ) ) ){
			kahanaLogPut( NULL, NULL, "failed to apr_dir_close(): %s", STRERROR_APR( rc ) );
		}
	}
	
	return rc;
}
예제 #8
0
파일: io_dir.c 프로젝트: LuaDist/lua-apr
static int dir_close(lua_State *L)
{
  lua_apr_dir *directory;
  apr_status_t status;

  directory = checkdir(L, 1, 1);
  status = apr_dir_close(directory->handle);
  if (status == APR_SUCCESS)
    directory->handle = NULL;

  return push_status(L, status);
}
예제 #9
0
/* Test for a (fixed) bug in apr_dir_read().  This bug only happened
   in threadless cases. */
static void test_uncleared_errno(abts_case *tc, void *data)
{
    apr_file_t *thefile = NULL;
    apr_finfo_t finfo;
    apr_int32_t finfo_flags = APR_FINFO_TYPE | APR_FINFO_NAME;
    apr_dir_t *this_dir;
    apr_status_t rv; 

    rv = apr_dir_make("dir1", APR_OS_DEFAULT, p);
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
    rv = apr_dir_make("dir2", APR_OS_DEFAULT, p);
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
    rv = apr_file_open(&thefile, "dir1/file1",
                       APR_FOPEN_READ | APR_FOPEN_WRITE | APR_FOPEN_CREATE, APR_OS_DEFAULT, p);
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
    rv = apr_file_close(thefile);
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);

    /* Try to remove dir1.  This should fail because it's not empty.
       However, on a platform with threads disabled (such as FreeBSD),
       `errno' will be set as a result. */
    rv = apr_dir_remove("dir1", p);
    ABTS_INT_EQUAL(tc, 1, APR_STATUS_IS_ENOTEMPTY(rv));
    
    /* Read `.' and `..' out of dir2. */
    rv = apr_dir_open(&this_dir, "dir2", p);
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
    rv = apr_dir_read(&finfo, finfo_flags, this_dir);
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
    rv = apr_dir_read(&finfo, finfo_flags, this_dir);
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);

    /* Now, when we attempt to do a third read of empty dir2, and the
       underlying system readdir() returns NULL, the old value of
       errno shouldn't cause a false alarm.  We should get an ENOENT
       back from apr_dir_read, and *not* the old errno. */
    rv = apr_dir_read(&finfo, finfo_flags, this_dir);
    ABTS_INT_EQUAL(tc, 1, APR_STATUS_IS_ENOENT(rv));

    rv = apr_dir_close(this_dir);
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
		 
    /* Cleanup */
    rv = apr_file_remove("dir1/file1", p);
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
    rv = apr_dir_remove("dir1", p);
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
    rv = apr_dir_remove("dir2", p);
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);

}
예제 #10
0
void mapcache_configuration_parse(mapcache_context *ctx, const char *filename, mapcache_cfg *config, int cgi) {
 apr_dir_t *lockdir;
   apr_status_t rv;
   char errmsg[120];  
   char *url;

 mapcache_configuration_parse_xml(ctx,filename,config);
  

   GC_CHECK_ERROR(ctx);

   if(!config->lockdir || !strlen(config->lockdir)) {
      config->lockdir = apr_pstrdup(ctx->pool, "/tmp");
   }
   rv = apr_dir_open(&lockdir,config->lockdir,ctx->pool);
   if(rv != APR_SUCCESS) {
      ctx->set_error(ctx,500, "failed to open lock directory %s: %s"
            ,config->lockdir,apr_strerror(rv,errmsg,120));
      return;
   }

   /* only remove lockfiles if we're not in cgi mode */
   if(!cgi) {
      apr_finfo_t finfo;
      while ((apr_dir_read(&finfo, APR_FINFO_DIRENT|APR_FINFO_TYPE|APR_FINFO_NAME, lockdir)) == APR_SUCCESS) {
         if(finfo.filetype == APR_REG) {
            if(!strncmp(finfo.name, MAPCACHE_LOCKFILE_PREFIX, strlen(MAPCACHE_LOCKFILE_PREFIX))) {
               ctx->log(ctx,MAPCACHE_WARN,"found old lockfile %s/%s, deleting it",config->lockdir,
                     finfo.name);
               rv = apr_file_remove(apr_psprintf(ctx->pool,"%s/%s",config->lockdir, finfo.name),ctx->pool);
               if(rv != APR_SUCCESS) {
                  ctx->set_error(ctx,500, "failed to remove lockfile %s: %s",finfo.name,apr_strerror(rv,errmsg,120));
                  return;
               }

            }

         }
      }
   }
   apr_dir_close(lockdir);

   /* if we were suppplied with an onlineresource, make sure it ends with a / */
   if(NULL != (url = (char*)apr_table_get(config->metadata,"url"))) {
      char *urlend = url + strlen(url)-1;
      if(*urlend != '/') {
         url = apr_pstrcat(ctx->pool,url,"/",NULL);
         apr_table_setn(config->metadata,"url",url);
      }
   }
}
// Multicast index handler
static int multicast_index_handler(request_rec *rec)
{
  multicast_conf* conf = ap_get_module_config(rec->per_dir_config, &multicast_index_module);
  apr_status_t status = APR_SUCCESS;
  apr_finfo_t finfo;
  apr_dir_t* dir;

  if(strcasecmp(rec->handler, MULTICAST_INDEX)) return DECLINED;
  if(!conf || !conf->enabled) return DECLINED;
  if(rec->method_number!=M_GET) return DECLINED;

  // setup content-type of response.
  rec->content_type = "text/json";

  // do request
  status = apr_dir_open(&dir, rec->filename, rec->pool);
  if(status!=APR_SUCCESS) {
    // 404 Not Found.
    rec->status = HTTP_NOT_FOUND;
    return multicast_404_not_found(rec, conf);
  }

  // 200 OK.
  if(!rec->header_only) {
    int the_first = TRUE;
    ap_rputs("[", rec);
    while((status=apr_dir_read(&finfo, APR_FINFO_NAME|APR_FINFO_TYPE, dir))==APR_SUCCESS) {
      if((strcmp(finfo.name, ".")==0) || (strcmp(finfo.name, "..")==0)) continue;
      if(the_first) { the_first = FALSE; } else { ap_rputs(",", rec); }
      switch(finfo.filetype) {
      case APR_DIR:
        ap_rprintf(rec, "\"%s/\"", finfo.name);
        break;
      case APR_REG:
        ap_rprintf(rec, "\"%s\"", finfo.name);
        break;
      case APR_LNK:
        ap_rprintf(rec, "\"%s@\"", finfo.name);
        break;
      default:
        break;
      }
    }
    ap_rputs("]\n", rec);
    rec->status = HTTP_OK;
  }
  apr_dir_close(dir);

  return multicast_200_ok(rec, conf);
}
예제 #12
0
/*
 * get a list of configured OIDC providers based on the entries in the provider metadata directory
 */
apr_byte_t oidc_metadata_list(request_rec *r, oidc_cfg *cfg,
		apr_array_header_t **list) {
	apr_status_t rc;
	apr_dir_t *dir;
	apr_finfo_t fi;
	char s_err[128];

	oidc_debug(r, "enter");

	/* open the metadata directory */
	if ((rc = apr_dir_open(&dir, cfg->metadata_dir, r->pool)) != APR_SUCCESS) {
		oidc_error(r, "error opening metadata directory '%s' (%s)",
				cfg->metadata_dir, apr_strerror(rc, s_err, sizeof(s_err)));
		return FALSE;
	}

	/* allocate some space in the array that will hold the list of providers */
	*list = apr_array_make(r->pool, 5, sizeof(sizeof(const char*)));
	/* BTW: we could estimate the number in the array based on # directory entries... */

	/* loop over the entries in the provider metadata directory */
	while (apr_dir_read(&fi, APR_FINFO_NAME, dir) == APR_SUCCESS) {

		/* skip "." and ".." entries */
		if (fi.name[0] == '.')
			continue;
		/* skip other non-provider entries */
		char *ext = strrchr(fi.name, '.');
		if ((ext == NULL)
				|| (strcmp(++ext, OIDC_METADATA_SUFFIX_PROVIDER) != 0))
			continue;

		/* get the issuer from the filename */
		const char *issuer = oidc_metadata_filename_to_issuer(r, fi.name);

		/* get the provider and client metadata, do all checks and registration if possible */
		oidc_provider_t *provider = NULL;
		if (oidc_metadata_get(r, cfg, issuer, &provider) == TRUE) {
			/* push the decoded issuer filename in to the array */
			*(const char**) apr_array_push(*list) = provider->issuer;
		}
	}

	/* we're done, cleanup now */
	apr_dir_close(dir);

	return TRUE;
}
예제 #13
0
파일: bif_file.c 프로젝트: aidanhs/teeterl
term_t bif_list_dir1(term_t Dir, process_t *ctx)
{
	apr_status_t rs;
	apr_pool_t *p;
	
	const char *path;
	apr_dir_t *dir;

	term_t r = nil;
	term_t cons = nil;

	if (!is_string(Dir))
		return A_BADARG;

	apr_pool_create(&p, 0);

	path = ltoz(Dir, p);
	rs = apr_dir_open(&dir, path, p);
	if (rs == 0)
	{
		apr_finfo_t fi;
		for (;;)
		{
			rs = apr_dir_read(&fi, APR_FINFO_NAME | APR_FINFO_SIZE, dir);
			if (rs == 0 || APR_STATUS_IS_INCOMPLETE(rs))
			{
				term_t name = ztol(fi.name, proc_gc_pool(ctx));
				lst_add(r, cons, name, proc_gc_pool(ctx));
			}

			if (APR_STATUS_IS_ENOENT(rs))
			{
				rs = APR_SUCCESS;
				break;
			}
		}

		apr_dir_close(dir);
	}

	if (rs != 0 && !APR_STATUS_IS_ENOENT(rs))
		result(make_tuple2(A_ERROR, decipher_status(rs), proc_gc_pool(ctx)));
	else
		result(make_tuple2(A_OK, r, proc_gc_pool(ctx)));

	apr_pool_destroy(p);
	return AI_OK;
}
예제 #14
0
파일: io_dir.c 프로젝트: LuaDist/lua-apr
static int dir_gc(lua_State *L)
{
  lua_apr_dir *directory = checkdir(L, 1, 0);
  if (object_collectable((lua_apr_refobj*)directory)) {
    if (directory->handle != NULL) {
      apr_dir_close(directory->handle);
      directory->handle = NULL;
    }
    if (directory->memory_pool != NULL) {
      apr_pool_destroy(directory->memory_pool);
      directory->memory_pool = NULL;
    }
  }
  release_object((lua_apr_refobj*)directory);
  return 0;
}
예제 #15
0
파일: bif_file.c 프로젝트: aidanhs/teeterl
term_t bif_list_dir3_0_1(term_t Dir, process_t *ctx)
{
	apr_status_t rs;
	apr_pool_t *p;
	const char *path;
	apr_dir_t *dir;
	term_t r = nil;
	term_t cons = nil;

	apr_uint32_t wanted = APR_FINFO_MTIME | APR_FINFO_CTIME | APR_FINFO_ATIME |
		 APR_FINFO_NAME | APR_FINFO_SIZE | APR_FINFO_TYPE |
		 APR_FINFO_USER | APR_FINFO_GROUP | APR_FINFO_PROT;

	if (!is_string(Dir))
		return A_BADARG;

	apr_pool_create(&p, 0);
	path = ltoz(Dir, p);
	rs = apr_dir_open(&dir, path, p);
	if (rs == 0)
	{
		apr_finfo_t fi;
		for (;;)
		{
			rs = apr_dir_read(&fi, wanted, dir);
			if (rs == 0 || APR_STATUS_IS_INCOMPLETE(rs))
			{
				term_t file_info = make_file_info(&fi, proc_gc_pool(ctx));
				lst_add(r, cons, file_info, proc_gc_pool(ctx));
			}
			else if (APR_STATUS_IS_ENOENT(rs))
			{
				rs = 0;
				break;
			}
		}
		apr_dir_close(dir);
	}

	if (rs != 0)
		result(make_tuple2(A_ERROR, decipher_status(rs), proc_gc_pool(ctx)));
	else
		result(make_tuple2(A_OK, r, proc_gc_pool(ctx)));

	apr_pool_destroy(p);
	return AI_OK;
}
예제 #16
0
파일: apr_fnmatch.c 프로젝트: Ga-vin/apache
/* Find all files matching the specified pattern */
APR_DECLARE(apr_status_t) apr_match_glob(const char *pattern, 
                                         apr_array_header_t **result,
                                         apr_pool_t *p)
{
    apr_dir_t *dir;
    apr_finfo_t finfo;
    apr_status_t rv;
    char *path;

    /* XXX So, this is kind of bogus.  Basically, I need to strip any leading
     * directories off the pattern, but there is no portable way to do that.
     * So, for now we just find the last occurance of '/' and if that doesn't
     * return anything, then we look for '\'.  This means that we could
     * screw up on unix if the pattern is something like "foo\.*"  That '\'
     * isn't a directory delimiter, it is a part of the filename.  To fix this,
     * we really need apr_filepath_basename, which will be coming as soon as
     * I get to it.  rbb
     */
    char *idx = strrchr(pattern, '/');
    
    if (idx == NULL) {
        idx = strrchr(pattern, '\\');
    }
    if (idx == NULL) {
        path = ".";
    }
    else {
        path = apr_pstrndup(p, pattern, idx - pattern);
        pattern = idx + 1;
    }

    *result = apr_array_make(p, 0, sizeof(char *));
    rv = apr_dir_open(&dir, path, p);
    if (rv != APR_SUCCESS) {
        return rv;
    }

    while (apr_dir_read(&finfo, APR_FINFO_NAME, dir) == APR_SUCCESS) {
        if (apr_fnmatch(pattern, finfo.name, 0) == APR_SUCCESS) {
            *(const char **)apr_array_push(*result) = apr_pstrdup(p, finfo.name);
        }
    }
    apr_dir_close(dir);
    return APR_SUCCESS;
}
예제 #17
0
파일: bif_file.c 프로젝트: aidanhs/teeterl
term_t bif_list_dir2_1(term_t Dir, process_t *ctx)
{
	apr_status_t rs;
	apr_pool_t *p;
	const char *path;
	apr_dir_t *dir;
	term_t r = nil;
	if (!is_string(Dir))
		return A_BADARG;
	apr_pool_create(&p, 0);
	path = ltoz(Dir, p);
	rs = apr_dir_open(&dir, path, p);
	if (rs == 0)
	{
		term_t cons = nil;
		apr_finfo_t fi;
		for (;;)
		{
			term_t v;
			term_t name;
			rs = apr_dir_read(&fi, APR_FINFO_NAME | APR_FINFO_SIZE, dir);
			if (rs != 0)
				break;
			name = ztol(fi.name, proc_gc_pool(ctx));
			if (fi.filetype == APR_DIR)
				v = make_tuple2(A_DIR, name, proc_gc_pool(ctx));
			else if (fi.filetype == APR_REG)
				v = make_tuple3(A_FILE, name, intnum(fi.size), proc_gc_pool(ctx));	//TODO: large size
			else
				v = make_tuple2(A_UNKNOWN, name, proc_gc_pool(ctx));
			lst_add(r, cons, v, proc_gc_pool(ctx));
		}

		apr_dir_close(dir);
	}

	if (rs != 0 && !APR_STATUS_IS_ENOENT(rs))
		result(make_tuple2(A_ERROR, decipher_status(rs), proc_gc_pool(ctx)));
	else
		result(make_tuple2(A_OK, r, proc_gc_pool(ctx)));

	apr_pool_destroy(p);
	return AI_OK;
}
예제 #18
0
List* read_dir(apr_pool_t* pool, List* file_list, const char* dir_path, int* count, error_messages_t* error_messages){
	apr_status_t rv;
	char errorbuf [255];

	apr_dir_t *dir;
	apr_finfo_t filef;

	char* file_path;

	rv = apr_dir_open(&dir, dir_path, pool);
	if (rv != 0){
		 apr_strerror(rv, (char *)&errorbuf, 255);
		error_messages_add(error_messages, ERROR,apr_psprintf(pool, "Error opening directory (%s) (%d)", dir_path, rv), errorbuf);
		return NULL;
	}
	  //Read file is directory
	while (apr_dir_read(&filef, APR_FINFO_TYPE | APR_FINFO_NAME | APR_FINFO_MTIME, dir) == 0){
		file_path =  apr_pstrcat(pool, dir_path, "/", filef.name, NULL);
		if (file_path == NULL){
			return NULL;
			///BIG ERROR
		}
		//Is a Directory
		if (filef.filetype == APR_DIR){
			if(filef.name[0] != '.'){
					file_list = read_dir(pool, file_list, file_path, count, error_messages);
			}
		}
		//Is a File
		if (filef.filetype == APR_REG){
			List* file_list_new;
			(*count)++;
			file_list_new  = apr_pcalloc(pool, sizeof(List));
			file_list->file.path = file_path;
			file_list->file.mtime = filef.mtime;
			file_list->file.type  = get_file_ext(pool,file_path);
			file_list->next = file_list_new;
			file_list = file_list_new;
		}
	}
	rv = apr_dir_close(dir);
	return file_list;
}
예제 #19
0
/*
 * check if arg is a valid directory on the file system
 */
const char *oidc_valid_dir(apr_pool_t *pool, const char *arg) {
	char s_err[STR_ERROR_MAX];
	apr_dir_t *dir = NULL;
	apr_status_t rc = APR_SUCCESS;

	/* ensure the directory exists */
	if ((rc = apr_dir_open(&dir, arg, pool)) != APR_SUCCESS) {
		return apr_psprintf(pool, "cannot access directory '%s' (%s)", arg,
				apr_strerror(rc, s_err, STR_ERROR_MAX));
	}

	/* and cleanup... */
	if ((rc = apr_dir_close(dir)) != APR_SUCCESS) {
		return apr_psprintf(pool, "cannot close directory '%s' (%s)", arg,
				apr_strerror(rc, s_err, STR_ERROR_MAX));
	}

	return NULL;
}
예제 #20
0
static void test_rewind(abts_case *tc, void *data)
{
    apr_dir_t *dir;
    apr_finfo_t first, second;

    APR_ASSERT_SUCCESS(tc, "apr_dir_open failed", apr_dir_open(&dir, "data", p));

    APR_ASSERT_SUCCESS(tc, "apr_dir_read failed",
                       apr_dir_read(&first, APR_FINFO_DIRENT, dir));

    APR_ASSERT_SUCCESS(tc, "apr_dir_rewind failed", apr_dir_rewind(dir));

    APR_ASSERT_SUCCESS(tc, "second apr_dir_read failed",
                       apr_dir_read(&second, APR_FINFO_DIRENT, dir));

    APR_ASSERT_SUCCESS(tc, "apr_dir_close failed", apr_dir_close(dir));

    ABTS_STR_EQUAL(tc, first.name, second.name);
}
예제 #21
0
파일: switch_apr.c 프로젝트: gujun/sscore
SWITCH_DECLARE(switch_status_t) switch_directory_exists(const char *dirname, switch_memory_pool_t *pool)
{
	apr_dir_t *dir_handle;
	switch_memory_pool_t *our_pool = NULL;
	switch_status_t status;

	if (!pool) {
		switch_core_new_memory_pool(&our_pool);
		pool = our_pool;
	}

	if ((status = apr_dir_open(&dir_handle, dirname, pool)) == APR_SUCCESS) {
		apr_dir_close(dir_handle);
	}

	if (our_pool) {
		switch_core_destroy_memory_pool(&our_pool);
	}

	return status;
}
예제 #22
0
/* Move current_node to point to parent node */
static struct filenode* move_up_directory(vtab_cursor *p_cur)
{
    struct filenode* d = p_cur->current_node;
 
    /* Get current pointer to parent */
    p_cur->current_node = d->parent;

    /* Close current directory */
    if (d->dir != NULL)
    {
        if (d->dirent.pool != NULL)
        {
            apr_dir_close(d->dir);
        }
    }

    /* Free memory associated with current directory. */
    deallocate_filenode(d);

    /* Update d to point to parent (now current directory) */
    return p_cur->current_node;
}
예제 #23
0
파일: testldap.c 프로젝트: 0jpq0/kbengine
static int add_ldap_certs(abts_case *tc)
{
    apr_status_t status;
    apr_dir_t *thedir;
    apr_finfo_t dirent;
    apr_ldap_err_t *result = NULL;

    if ((status = apr_dir_open(&thedir, DIRNAME, p)) == APR_SUCCESS) {
        apr_ldap_opt_tls_cert_t *cert = (apr_ldap_opt_tls_cert_t *)apr_pcalloc(p, sizeof(apr_ldap_opt_tls_cert_t));

        do {
            status = apr_dir_read(&dirent, APR_FINFO_MIN | APR_FINFO_NAME, thedir);
            if (APR_STATUS_IS_INCOMPLETE(status)) {
                continue; /* ignore un-stat()able files */
            }
            else if (status != APR_SUCCESS) {
                break;
            }

            if (strstr(dirent.name, ".der")) {
                cert->type = APR_LDAP_CA_TYPE_DER;
                cert->path = apr_pstrcat (p, DIRNAME, "/", dirent.name, NULL);
                apr_ldap_set_option(p, NULL, APR_LDAP_OPT_TLS_CERT, (void *)cert, &result);
                ABTS_TRUE(tc, result->rc == LDAP_SUCCESS);
            }
            if (strstr(dirent.name, ".b64")) {
                cert->type = APR_LDAP_CA_TYPE_BASE64;
                cert->path = apr_pstrcat (p, DIRNAME, "/", dirent.name, NULL);
                apr_ldap_set_option(p, NULL, APR_LDAP_OPT_TLS_CERT, (void *)cert, &result);
                ABTS_TRUE(tc, result->rc == LDAP_SUCCESS);
            }

        } while (1);

        apr_dir_close(thedir);
    }
    return 0;
}
예제 #24
0
bool UmcFramework::LoadScenarios()
{
	apr_dir_t* pDir;
	apr_finfo_t finfo;
	apr_status_t rv;
	const char* pDirPath;

	pDirPath = apt_dir_layout_path_compose(m_pDirLayout,APT_LAYOUT_CONF_DIR,"umc-scenarios",m_pPool);
	if(!pDirPath)
	{
		apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Compose Config File Path");
		return false;
	}

	apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Enter Directory [%s]",pDirPath);
	rv = apr_dir_open(&pDir,pDirPath,m_pPool);
	if(rv != APR_SUCCESS)
	{
		apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"No Such Directory %s",pDirPath);
		return false;
	}

	while(apr_dir_read(&finfo,APR_FINFO_NAME,pDir) == APR_SUCCESS)
	{
		if(apr_fnmatch("*.xml",finfo.name,0) == APR_SUCCESS) {
			char* pFilePath;
			if(apr_filepath_merge(&pFilePath,pDirPath,finfo.name,APR_FILEPATH_NATIVE,m_pPool) == APR_SUCCESS)
			{
				LoadScenario(pFilePath);
			}
		}
	}
	apr_dir_close(pDir);

	return true;
}
예제 #25
0
static int mediarss_index_directory(request_rec* r)
{
   apr_status_t status;
   apr_dir_t* dir;
   apr_finfo_t dirent;

   if ((status = apr_dir_open(&dir, r->filename, r->pool)) != APR_SUCCESS) {
      ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, "Can't open directory for index: %s", r->filename);
      return HTTP_FORBIDDEN;
   }

   /* Content header */
   
   char* url;
   url = ap_construct_url(r->pool, r->uri, r);

   ap_set_content_type(r, "text/xml; charset=utf-8");

   ap_rputs("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n\n", r);
   if (strcmp(r->args, "format=mediarss") == 0) {
      ap_rputs("<rss version=\"2.0\" xmlns:media=\"http://search.yahoo.com/mrss/\">\n", r);
   } else {
      ap_rputs("<rss version=\"2.0\">\n", r);
   }
   ap_rputs("  <channel>\n", r);
   ap_rvputs(r, "    <title>Index of ", url, "</title>\n", NULL);
   ap_rvputs(r, "    <link>", url, "</link>\n", NULL);

   /* Collect information about the files in the directory */
   
   while (1)
   {
      status = apr_dir_read(&dirent, APR_FINFO_MIN | APR_FINFO_NAME, dir);
      if (APR_STATUS_IS_INCOMPLETE(status)) {
         continue; /* ignore un-stat()able files */
      } else if (status != APR_SUCCESS) {
         break;
      }
      
      /* We are only interested in regular files. TODO Deal with symlinks. */
      
      if (dirent.filetype == APR_REG)
      {
         request_rec* rr;
         
         rr = ap_sub_req_lookup_dirent(&dirent, r, AP_SUBREQ_NO_ARGS, NULL);
         if (rr != NULL)
         {
            if (rr->finfo.filetype == APR_REG && rr->status == HTTP_OK)
            {
               /* In case of media rss, only include the item if it is a media type */

               if (strcmp(r->args, "format=mediarss") == 0 && mediarss_is_media_content(rr->content_type) == 0) {
                  continue;
               }

               char size[16];
               snprintf(size, sizeof(size), "%d", dirent.size);
               
               char date[APR_RFC822_DATE_LEN];
               apr_rfc822_date(date, dirent.mtime);
               
               char* guid = ap_md5(r->pool, (unsigned char*) apr_pstrcat(r->pool, url, dirent.name, NULL));
                           
               ap_rputs("    <item>\n", r);
               ap_rvputs(r, "      <guid>", guid, "</guid>\n", NULL);
               ap_rvputs(r, "      <title>", dirent.name, "</title>\n", NULL);
               ap_rvputs(r, "      <pubDate>", date, "</pubDate>\n", NULL);
               ap_rvputs(r, "      <enclosure url=\"", url, dirent.name, "\" length=\"", size, "\"\n", NULL);
               ap_rvputs(r, "        type=\"", rr->content_type, "\"/>\n", NULL);
               if (strcmp(r->args, "format=mediarss") == 0) {
                  ap_rvputs(r, "      <media:content url=\"", url, dirent.name, "\" fileSize=\"", size, "\"\n", NULL);
                  ap_rvputs(r, "        type=\"", rr->content_type, "\"/>\n", NULL);
               }
               ap_rputs("    </item>\n", r);
            }
            ap_destroy_sub_req(rr);
         }
      }
   }

   /* Content footer */

   ap_rputs("  </channel>\n", r);
   ap_rputs("</rss>\n", r);

   apr_dir_close(dir);
   
   return OK;
}
예제 #26
0
파일: htcacheclean.c 프로젝트: aptana/Jaxer
/*
 * walk the cache directory tree
 */
static int process_dir(char *path, apr_pool_t *pool)
{
    apr_dir_t *dir;
    apr_pool_t *p;
    apr_hash_t *h;
    apr_hash_index_t *i;
    apr_file_t *fd;
    apr_status_t status;
    apr_finfo_t info;
    apr_size_t len;
    apr_time_t current, deviation;
    char *nextpath, *base, *ext, *orig_basename;
    APR_RING_ENTRY(_direntry) anchor;
    DIRENTRY *d, *t, *n;
    ENTRY *e;
    int skip, retries;
    disk_cache_info_t disk_info;

    APR_RING_INIT(&anchor, _direntry, link);
    apr_pool_create(&p, pool);
    h = apr_hash_make(p);
    fd = NULL;
    skip = 0;
    deviation = MAXDEVIATION * APR_USEC_PER_SEC;

    if (apr_dir_open(&dir, path, p) != APR_SUCCESS) {
        return 1;
    }

    while (apr_dir_read(&info, 0, dir) == APR_SUCCESS && !interrupted) {
        if (!strcmp(info.name, ".") || !strcmp(info.name, "..")) {
            continue;
        }
        d = apr_pcalloc(p, sizeof(DIRENTRY));
        d->basename = apr_pstrcat(p, path, "/", info.name, NULL);
        APR_RING_INSERT_TAIL(&anchor, d, _direntry, link);
    }

    apr_dir_close(dir);

    if (interrupted) {
        return 1;
    }

    skip = baselen + 1;

    for (d = APR_RING_FIRST(&anchor);
         !interrupted && d != APR_RING_SENTINEL(&anchor, _direntry, link);
         d=n) {
        n = APR_RING_NEXT(d, link);
        base = strrchr(d->basename, '/');
        if (!base++) {
            base = d->basename;
        }
        ext = strchr(base, '.');

        /* there may be temporary files which may be gone before
         * processing, always skip these if not in realclean mode
         */
        if (!ext && !realclean) {
            if (!strncasecmp(base, AP_TEMPFILE_BASE, AP_TEMPFILE_BASELEN)
                && strlen(base) == AP_TEMPFILE_NAMELEN) {
                continue;
            }
        }

        /* this may look strange but apr_stat() may return errno which
         * is system dependent and there may be transient failures,
         * so just blindly retry for a short while
         */
        retries = STAT_ATTEMPTS;
        status = APR_SUCCESS;
        do {
            if (status != APR_SUCCESS) {
                apr_sleep(STAT_DELAY);
            }
            status = apr_stat(&info, d->basename, DIRINFO, p);
        } while (status != APR_SUCCESS && !interrupted && --retries);

        /* what may happen here is that apache did create a file which
         * we did detect but then does delete the file before we can
         * get file information, so if we don't get any file information
         * we will ignore the file in this case
         */
        if (status != APR_SUCCESS) {
            if (!realclean && !interrupted) {
                continue;
            }
            return 1;
        }

        if (info.filetype == APR_DIR) {
            /* Make a copy of the basename, as process_dir modifies it */
            orig_basename = apr_pstrdup(pool, d->basename);
            if (process_dir(d->basename, pool)) {
                return 1;
            }

            /* If asked to delete dirs, do so now. We don't care if it fails.
             * If it fails, it likely means there was something else there.
             */
            if (deldirs && !dryrun) {
                apr_dir_remove(orig_basename, pool);
            }
            continue;
        }

        if (info.filetype != APR_REG) {
            continue;
        }

        if (!ext) {
            if (!strncasecmp(base, AP_TEMPFILE_BASE, AP_TEMPFILE_BASELEN)
                && strlen(base) == AP_TEMPFILE_NAMELEN) {
                d->basename += skip;
                d->type = TEMP;
                d->dsize = info.size;
                apr_hash_set(h, d->basename, APR_HASH_KEY_STRING, d);
            }
            continue;
        }

        if (!strcasecmp(ext, CACHE_HEADER_SUFFIX)) {
            *ext = '\0';
            d->basename += skip;
            /* if a user manually creates a '.header' file */
            if (d->basename[0] == '\0') {
                continue;
            }
            t = apr_hash_get(h, d->basename, APR_HASH_KEY_STRING);
            if (t) {
                d = t;
            }
            d->type |= HEADER;
            d->htime = info.mtime;
            d->hsize = info.size;
            apr_hash_set(h, d->basename, APR_HASH_KEY_STRING, d);
            continue;
        }

        if (!strcasecmp(ext, CACHE_DATA_SUFFIX)) {
            *ext = '\0';
            d->basename += skip;
            /* if a user manually creates a '.data' file */
            if (d->basename[0] == '\0') {
                continue;
            }
            t = apr_hash_get(h, d->basename, APR_HASH_KEY_STRING);
            if (t) {
                d = t;
            }
            d->type |= DATA;
            d->dtime = info.mtime;
            d->dsize = info.size;
            apr_hash_set(h, d->basename, APR_HASH_KEY_STRING, d);
        }
    }

    if (interrupted) {
        return 1;
    }

    path[baselen] = '\0';

    for (i = apr_hash_first(p, h); i && !interrupted; i = apr_hash_next(i)) {
        void *hvalue;
        apr_uint32_t format;

        apr_hash_this(i, NULL, NULL, &hvalue);
        d = hvalue;

        switch(d->type) {
        case HEADERDATA:
            nextpath = apr_pstrcat(p, path, "/", d->basename,
                                   CACHE_HEADER_SUFFIX, NULL);
            if (apr_file_open(&fd, nextpath, APR_FOPEN_READ | APR_FOPEN_BINARY,
                              APR_OS_DEFAULT, p) == APR_SUCCESS) {
                len = sizeof(format);
                if (apr_file_read_full(fd, &format, len,
                                       &len) == APR_SUCCESS) {
                    if (format == DISK_FORMAT_VERSION) {
                        apr_off_t offset = 0;

                        apr_file_seek(fd, APR_SET, &offset);

                        len = sizeof(disk_cache_info_t);

                        if (apr_file_read_full(fd, &disk_info, len,
                                               &len) == APR_SUCCESS) {
                            apr_file_close(fd);
                            e = apr_palloc(pool, sizeof(ENTRY));
                            APR_RING_INSERT_TAIL(&root, e, _entry, link);
                            e->expire = disk_info.expire;
                            e->response_time = disk_info.response_time;
                            e->htime = d->htime;
                            e->dtime = d->dtime;
                            e->hsize = d->hsize;
                            e->dsize = d->dsize;
                            e->basename = apr_pstrdup(pool, d->basename);
                            break;
                        }
                        else {
                            apr_file_close(fd);
                        }
                    }
                    else if (format == VARY_FORMAT_VERSION) {
                        /* This must be a URL that added Vary headers later,
                         * so kill the orphaned .data file
                         */
                        apr_file_close(fd);
                        apr_file_remove(apr_pstrcat(p, path, "/", d->basename,
                                                    CACHE_DATA_SUFFIX, NULL),
                                        p);
                    }
                }
                else {
                    apr_file_close(fd);
                }

            }
            /* we have a somehow unreadable headers file which is associated
             * with a data file. this may be caused by apache currently
             * rewriting the headers file. thus we may delete the file set
             * either in realclean mode or if the headers file modification
             * timestamp is not within a specified positive or negative offset
             * to the current time.
             */
            current = apr_time_now();
            if (realclean || d->htime < current - deviation
                || d->htime > current + deviation) {
                delete_entry(path, d->basename, p);
                unsolicited += d->hsize;
                unsolicited += d->dsize;
            }
            break;

        /* single data and header files may be deleted either in realclean
         * mode or if their modification timestamp is not within a
         * specified positive or negative offset to the current time.
         * this handling is necessary due to possible race conditions
         * between apache and this process
         */
        case HEADER:
            current = apr_time_now();
            nextpath = apr_pstrcat(p, path, "/", d->basename,
                                   CACHE_HEADER_SUFFIX, NULL);
            if (apr_file_open(&fd, nextpath, APR_FOPEN_READ | APR_FOPEN_BINARY,
                              APR_OS_DEFAULT, p) == APR_SUCCESS) {
                len = sizeof(format);
                if (apr_file_read_full(fd, &format, len,
                                       &len) == APR_SUCCESS) {
                    if (format == VARY_FORMAT_VERSION) {
                        apr_time_t expires;

                        len = sizeof(expires);

                        apr_file_read_full(fd, &expires, len, &len);

                        apr_file_close(fd);

                        if (expires < current) {
                            delete_entry(path, d->basename, p);
                        }
                        break;
                    }
                }
                apr_file_close(fd);
            }

            if (realclean || d->htime < current - deviation
                || d->htime > current + deviation) {
                delete_entry(path, d->basename, p);
                unsolicited += d->hsize;
            }
            break;

        case DATA:
            current = apr_time_now();
            if (realclean || d->dtime < current - deviation
                || d->dtime > current + deviation) {
                delete_entry(path, d->basename, p);
                unsolicited += d->dsize;
            }
            break;

        /* temp files may only be deleted in realclean mode which
         * is asserted above if a tempfile is in the hash array
         */
        case TEMP:
            delete_file(path, d->basename, p);
            unsolicited += d->dsize;
            break;
        }
    }

    if (interrupted) {
        return 1;
    }

    apr_pool_destroy(p);

    if (benice) {
        apr_sleep(NICE_DELAY);
    }

    if (interrupted) {
        return 1;
    }

    return 0;
}
예제 #27
0
/** Load UniMRCP client */
static apt_bool_t unimrcp_client_load(unimrcp_client_loader_t *loader, const char *dir_path, const char *file_name, apr_pool_t *pool)
{
	apr_xml_doc *doc;
	const apr_xml_elem *elem;
	const apr_xml_elem *root;
	const apr_xml_attr *attr;
	const char *file_path;
	const char *version = NULL;
	const char *subfolder = NULL;

	if(!dir_path || !file_name) {
		return FALSE;
	}

	if(*dir_path == '\0') {
		file_path = file_name;
	}
	else {
		file_path = apr_psprintf(pool,"%s/%s",dir_path,file_name);
	}

	/* Parse XML document */
	doc = unimrcp_client_doc_parse(file_path,pool);
	if(!doc) {
		return FALSE;
	}

	root = doc->root;

	/* Match document name */
	if(!root || strcasecmp(root->name,"unimrcpclient") != 0) {
		apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Document <%s>",root->name);
		return FALSE;
	}

	/* Read attributes */
	for(attr = root->attr; attr; attr = attr->next) {
		if(strcasecmp(attr->name,"version") == 0) {
			version = attr->value;
		}
		else if(strcasecmp(attr->name,"subfolder") == 0) {
			subfolder = attr->value;
		}
	}

	/* Check version number first */
	if(!version) {
		apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Version");
		return FALSE;
	}

	loader->doc = doc;

	/* Navigate through document */
	for(elem = root->first_child; elem; elem = elem->next) {
		if(strcasecmp(elem->name,"properties") == 0) {
			unimrcp_client_properties_load(loader,elem);
		}
		else if(strcasecmp(elem->name,"components") == 0) {
			unimrcp_client_components_load(loader,elem);
		}
		else if(strcasecmp(elem->name,"settings") == 0) {
			unimrcp_client_settings_load(loader,elem);
		}
		else if(strcasecmp(elem->name,"profiles") == 0) {
			unimrcp_client_profiles_load(loader,elem);
		}
		else {
			apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Element <%s>",elem->name);
		}
	}

	if(subfolder && subfolder != '\0') {
		apr_dir_t *dir;
		apr_finfo_t finfo;
		apr_status_t rv;

		dir_path = apr_psprintf(pool,"%s/%s",dir_path,subfolder);
		apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Enter Directory [%s]",dir_path);
		rv = apr_dir_open(&dir,dir_path,pool);
		if(rv == APR_SUCCESS) {
			while(apr_dir_read(&finfo, APR_FINFO_NAME, dir) == APR_SUCCESS) {
				if(apr_fnmatch("*.xml", finfo.name, 0) == APR_SUCCESS) {
					unimrcp_client_load(loader,dir_path,finfo.name,pool);
				}
			}
			apr_dir_close(dir);
			apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Leave Directory [%s]",dir_path);
		}
		else {
			apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"No Such Directory %s",dir_path);
		}
	}
	return TRUE;
}
예제 #28
0
static int check_speling(request_rec *r)
{
    spconfig *cfg;
    char *good, *bad, *postgood, *url;
    apr_finfo_t dirent;
    int filoc, dotloc, urlen, pglen;
    apr_array_header_t *candidates = NULL;
    apr_dir_t          *dir;

    cfg = ap_get_module_config(r->per_dir_config, &speling_module);
    if (!cfg->enabled) {
        return DECLINED;
    }

    /* We only want to worry about GETs */
    if (r->method_number != M_GET) {
        return DECLINED;
    }

    /* We've already got a file of some kind or another */
    if (r->finfo.filetype != APR_NOFILE) {
        return DECLINED;
    }

    /* Not a file request */
    if (r->proxyreq || !r->filename) {
        return DECLINED;
    }

    /* This is a sub request - don't mess with it */
    if (r->main) {
        return DECLINED;
    }

    /*
     * The request should end up looking like this:
     * r->uri: /correct-url/mispelling/more
     * r->filename: /correct-file/mispelling r->path_info: /more
     *
     * So we do this in steps. First break r->filename into two pieces
     */

    filoc = ap_rind(r->filename, '/');
    /*
     * Don't do anything if the request doesn't contain a slash, or
     * requests "/"
     */
    if (filoc == -1 || strcmp(r->uri, "/") == 0) {
        return DECLINED;
    }

    /* good = /correct-file */
    good = apr_pstrndup(r->pool, r->filename, filoc);
    /* bad = mispelling */
    bad = apr_pstrdup(r->pool, r->filename + filoc + 1);
    /* postgood = mispelling/more */
    postgood = apr_pstrcat(r->pool, bad, r->path_info, NULL);

    urlen = strlen(r->uri);
    pglen = strlen(postgood);

    /* Check to see if the URL pieces add up */
    if (strcmp(postgood, r->uri + (urlen - pglen))) {
        return DECLINED;
    }

    /* url = /correct-url */
    url = apr_pstrndup(r->pool, r->uri, (urlen - pglen));

    /* Now open the directory and do ourselves a check... */
    if (apr_dir_open(&dir, good, r->pool) != APR_SUCCESS) {
        /* Oops, not a directory... */
        return DECLINED;
    }

    candidates = apr_array_make(r->pool, 2, sizeof(misspelled_file));

    dotloc = ap_ind(bad, '.');
    if (dotloc == -1) {
        dotloc = strlen(bad);
    }

    while (apr_dir_read(&dirent, APR_FINFO_DIRENT, dir) == APR_SUCCESS) {
        sp_reason q;

        /*
         * If we end up with a "fixed" URL which is identical to the
         * requested one, we must have found a broken symlink or some such.
         * Do _not_ try to redirect this, it causes a loop!
         */
        if (strcmp(bad, dirent.name) == 0) {
            apr_dir_close(dir);
            return OK;
        }

        /*
         * miscapitalization errors are checked first (like, e.g., lower case
         * file, upper case request)
         */
        else if (strcasecmp(bad, dirent.name) == 0) {
            misspelled_file *sp_new;

            sp_new = (misspelled_file *) apr_array_push(candidates);
            sp_new->name = apr_pstrdup(r->pool, dirent.name);
            sp_new->quality = SP_MISCAPITALIZED;
        }

        /*
         * simple typing errors are checked next (like, e.g.,
         * missing/extra/transposed char)
         */
        else if ((cfg->check_case_only == 0)
                 && ((q = spdist(bad, dirent.name)) != SP_VERYDIFFERENT)) {
            misspelled_file *sp_new;

            sp_new = (misspelled_file *) apr_array_push(candidates);
            sp_new->name = apr_pstrdup(r->pool, dirent.name);
            sp_new->quality = q;
        }

        /*
         * The spdist() should have found the majority of the misspelled
         * requests.  It is of questionable use to continue looking for
         * files with the same base name, but potentially of totally wrong
         * type (index.html <-> index.db).
         *
         * If you're using MultiViews, and have a file named foobar.html,
         * which you refer to as "foobar", and someone tried to access
         * "Foobar", without CheckBasenameMatch, mod_speling won't find it,
         * because it won't find anything matching that spelling.
         * With the extension-munging, it would locate "foobar.html".
         */
        else if ((cfg->check_case_only == 0) &&
                 (cfg->check_basename_match == 1)) {
            /*
             * Okay... we didn't find anything. Now we take out the hard-core
             * power tools. There are several cases here. Someone might have
             * entered a wrong extension (.htm instead of .html or vice
             * versa) or the document could be negotiated. At any rate, now
             * we just compare stuff before the first dot. If it matches, we
             * figure we got us a match. This can result in wrong things if
             * there are files of different content types but the same prefix
             * (e.g. foo.gif and foo.html) This code will pick the first one
             * it finds. Better than a Not Found, though.
             */
            int entloc = ap_ind(dirent.name, '.');
            if (entloc == -1) {
                entloc = strlen(dirent.name);
            }

            if ((dotloc == entloc)
                && !strncasecmp(bad, dirent.name, dotloc)) {
                misspelled_file *sp_new;

                sp_new = (misspelled_file *) apr_array_push(candidates);
                sp_new->name = apr_pstrdup(r->pool, dirent.name);
                sp_new->quality = SP_VERYDIFFERENT;
            }
        }
    }
    apr_dir_close(dir);

    if (candidates->nelts != 0) {
        /* Wow... we found us a mispelling. Construct a fixed url */
        char *nuri;
        const char *ref;
        misspelled_file *variant = (misspelled_file *) candidates->elts;
        int i;

        ref = apr_table_get(r->headers_in, "Referer");

        qsort((void *) candidates->elts, candidates->nelts,
              sizeof(misspelled_file), sort_by_quality);

        /*
         * Conditions for immediate redirection:
         *     a) the first candidate was not found by stripping the suffix
         * AND b) there exists only one candidate OR the best match is not
         *        ambiguous
         * then return a redirection right away.
         */
        if (variant[0].quality != SP_VERYDIFFERENT
            && (candidates->nelts == 1
                || variant[0].quality != variant[1].quality)) {

            nuri = ap_escape_uri(r->pool, apr_pstrcat(r->pool, url,
                                                     variant[0].name,
                                                     r->path_info, NULL));
            if (r->parsed_uri.query)
                nuri = apr_pstrcat(r->pool, nuri, "?", r->parsed_uri.query, NULL);

            apr_table_setn(r->headers_out, "Location",
                          ap_construct_url(r->pool, nuri, r));

            ap_log_rerror(APLOG_MARK, APLOG_INFO, APR_SUCCESS,
                          r,
                          ref ? "Fixed spelling: %s to %s from %s"
                              : "Fixed spelling: %s to %s%s",
                          r->uri, nuri,
                          (ref ? ref : ""));

            return HTTP_MOVED_PERMANENTLY;
        }
        /*
         * Otherwise, a "[300] Multiple Choices" list with the variants is
         * returned.
         */
        else {
            apr_pool_t *p;
            apr_table_t *notes;
            apr_pool_t *sub_pool;
            apr_array_header_t *t;
            apr_array_header_t *v;


            if (r->main == NULL) {
                p = r->pool;
                notes = r->notes;
            }
            else {
                p = r->main->pool;
                notes = r->main->notes;
            }

            if (apr_pool_create(&sub_pool, p) != APR_SUCCESS)
                return DECLINED;

            t = apr_array_make(sub_pool, candidates->nelts * 8 + 8,
                              sizeof(char *));
            v = apr_array_make(sub_pool, candidates->nelts * 5,
                              sizeof(char *));

            /* Generate the response text. */

            *(const char **)apr_array_push(t) =
                          "The document name you requested (<code>";
            *(const char **)apr_array_push(t) = ap_escape_html(sub_pool, r->uri);
            *(const char **)apr_array_push(t) =
                           "</code>) could not be found on this server.\n"
                           "However, we found documents with names similar "
                           "to the one you requested.<p>"
                           "Available documents:\n<ul>\n";

            for (i = 0; i < candidates->nelts; ++i) {
                char *vuri;
                const char *reason;

                reason = sp_reason_str[(int) (variant[i].quality)];
                /* The format isn't very neat... */
                vuri = apr_pstrcat(sub_pool, url, variant[i].name, r->path_info,
                                  (r->parsed_uri.query != NULL) ? "?" : "",
                                  (r->parsed_uri.query != NULL)
                                      ? r->parsed_uri.query : "",
                                  NULL);
                *(const char **)apr_array_push(v) = "\"";
                *(const char **)apr_array_push(v) = ap_escape_uri(sub_pool, vuri);
                *(const char **)apr_array_push(v) = "\";\"";
                *(const char **)apr_array_push(v) = reason;
                *(const char **)apr_array_push(v) = "\"";

                *(const char **)apr_array_push(t) = "<li><a href=\"";
                *(const char **)apr_array_push(t) = ap_escape_uri(sub_pool, vuri);
                *(const char **)apr_array_push(t) = "\">";
                *(const char **)apr_array_push(t) = ap_escape_html(sub_pool, vuri);
                *(const char **)apr_array_push(t) = "</a> (";
                *(const char **)apr_array_push(t) = reason;
                *(const char **)apr_array_push(t) = ")\n";

                /*
                 * when we have printed the "close matches" and there are
                 * more "distant matches" (matched by stripping the suffix),
                 * then we insert an additional separator text to suggest
                 * that the user LOOK CLOSELY whether these are really the
                 * files she wanted.
                 */
                if (i > 0 && i < candidates->nelts - 1
                    && variant[i].quality != SP_VERYDIFFERENT
                    && variant[i + 1].quality == SP_VERYDIFFERENT) {
                    *(const char **)apr_array_push(t) =
                                   "</ul>\nFurthermore, the following related "
                                   "documents were found:\n<ul>\n";
                }
            }
            *(const char **)apr_array_push(t) = "</ul>\n";

            /* If we know there was a referring page, add a note: */
            if (ref != NULL) {
                *(const char **)apr_array_push(t) =
                               "Please consider informing the owner of the "
                               "<a href=\"";
                *(const char **)apr_array_push(t) = ap_escape_uri(sub_pool, ref);
                *(const char **)apr_array_push(t) = "\">referring page</a> "
                               "about the broken link.\n";
            }


            /* Pass our apr_table_t to http_protocol.c (see mod_negotiation): */
            apr_table_setn(notes, "variant-list", apr_array_pstrcat(p, t, 0));

            apr_table_mergen(r->subprocess_env, "VARIANTS",
                            apr_array_pstrcat(p, v, ','));

            apr_pool_destroy(sub_pool);

            ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
                         ref ? "Spelling fix: %s: %d candidates from %s"
                             : "Spelling fix: %s: %d candidates%s",
                         r->uri, candidates->nelts,
                         (ref ? ref : ""));

            return HTTP_MULTIPLE_CHOICES;
        }
    }

    return OK;
}
예제 #29
0
	virtual ~Path() {
		if (dir != NULL) check_apr(apr_dir_close(dir));
	}
예제 #30
0
파일: add.c 프로젝트: vocho/openqnx
/* Schedule directory DIRNAME, and some of the tree under it, for
 * addition with access baton ADM_ACCESS.  DEPTH is the depth at this
 * point in the descent (it may be changed for recursive calls).
 *
 * If DIRNAME (or any item below directory DIRNAME) is already scheduled for
 * addition, add will fail and return an error unless FORCE is TRUE.
 *
 * Files and directories that match ignore patterns will not be added unless
 * NO_IGNORE is TRUE.
 *
 * If CTX->CANCEL_FUNC is non-null, call it with CTX->CANCEL_BATON to allow
 * the user to cancel the operation
 */
static svn_error_t *
add_dir_recursive(const char *dirname,
                  svn_wc_adm_access_t *adm_access,
                  svn_depth_t depth,
                  svn_boolean_t force,
                  svn_boolean_t no_ignore,
                  svn_client_ctx_t *ctx,
                  apr_pool_t *pool)
{
  apr_dir_t *dir;
  apr_finfo_t this_entry;
  svn_error_t *err;
  apr_pool_t *subpool;
  apr_int32_t flags = APR_FINFO_TYPE | APR_FINFO_NAME;
  svn_wc_adm_access_t *dir_access;
  apr_array_header_t *ignores;

  /* Check cancellation; note that this catches recursive calls too. */
  if (ctx->cancel_func)
    SVN_ERR(ctx->cancel_func(ctx->cancel_baton));

  /* Add this directory to revision control. */
  err = svn_wc_add2(dirname, adm_access,
                    NULL, SVN_INVALID_REVNUM,
                    ctx->cancel_func, ctx->cancel_baton,
                    ctx->notify_func2, ctx->notify_baton2, pool);
  if (err && err->apr_err == SVN_ERR_ENTRY_EXISTS && force)
    svn_error_clear(err);
  else if (err)
    return err;

  SVN_ERR(svn_wc_adm_retrieve(&dir_access, adm_access, dirname, pool));

  if (!no_ignore)
    SVN_ERR(svn_wc_get_ignores(&ignores, ctx->config, dir_access, pool));

  subpool = svn_pool_create(pool);

  SVN_ERR(svn_io_dir_open(&dir, dirname, pool));

  /* Read the directory entries one by one and add those things to
     version control. */
  while (1)
    {
      const char *fullpath;

      svn_pool_clear(subpool);

      err = svn_io_dir_read(&this_entry, flags, dir, subpool);

      if (err)
        {
          /* Check if we're done reading the dir's entries. */
          if (APR_STATUS_IS_ENOENT(err->apr_err))
            {
              apr_status_t apr_err;

              svn_error_clear(err);
              apr_err = apr_dir_close(dir);
              if (apr_err)
                return svn_error_wrap_apr
                  (apr_err, _("Can't close directory '%s'"),
                   svn_path_local_style(dirname, subpool));
              break;
            }
          else
            {
              return svn_error_createf
                (err->apr_err, err,
                 _("Error during add of '%s'"),
                 svn_path_local_style(dirname, subpool));
            }
        }

      /* Skip entries for this dir and its parent.  */
      if (this_entry.name[0] == '.'
          && (this_entry.name[1] == '\0'
              || (this_entry.name[1] == '.' && this_entry.name[2] == '\0')))
        continue;

      /* Check cancellation so you can cancel during an
       * add of a directory with lots of files. */
      if (ctx->cancel_func)
        SVN_ERR(ctx->cancel_func(ctx->cancel_baton));

      /* Skip over SVN admin directories. */
      if (svn_wc_is_adm_dir(this_entry.name, subpool))
        continue;

      if ((!no_ignore) && svn_wc_match_ignore_list(this_entry.name,
                                                   ignores, subpool))
        continue;

      /* Construct the full path of the entry. */
      fullpath = svn_path_join(dirname, this_entry.name, subpool);

      /* Recurse on directories; add files; ignore the rest. */
      if (this_entry.filetype == APR_DIR && depth >= svn_depth_immediates)
        {
          svn_depth_t depth_below_here = depth;
          if (depth == svn_depth_immediates)
            depth_below_here = svn_depth_empty;

          SVN_ERR(add_dir_recursive(fullpath, dir_access, depth_below_here,
                                    force, no_ignore, ctx, subpool));
        }
      else if (this_entry.filetype != APR_UNKFILE
               && this_entry.filetype != APR_DIR
               && depth >= svn_depth_files)
        {
          err = add_file(fullpath, ctx, dir_access, subpool);
          if (err && err->apr_err == SVN_ERR_ENTRY_EXISTS && force)
            svn_error_clear(err);
          else if (err)
            return err;
        }
    }

  /* Opened by svn_wc_add */
  SVN_ERR(svn_wc_adm_close(dir_access));

  /* Destroy the per-iteration pool. */
  svn_pool_destroy(subpool);

  return SVN_NO_ERROR;
}