Exemplo n.º 1
0
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;
}
Exemplo n.º 2
0
/* 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;
}
Exemplo n.º 3
0
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;
}
Exemplo n.º 4
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);
}
Exemplo n.º 5
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;
}
Exemplo n.º 6
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;
}
Exemplo n.º 7
0
SWITCH_DECLARE(switch_status_t) switch_dir_open(switch_dir_t ** new_dir, const char *dirname, switch_memory_pool_t *pool)
{
	switch_status_t status;
	switch_dir_t *dir = malloc(sizeof(*dir));

	if (!dir) {
		*new_dir = NULL;
		return SWITCH_STATUS_FALSE;
	}

	memset(dir, 0, sizeof(*dir));
	if ((status = apr_dir_open(&(dir->dir_handle), dirname, pool)) == APR_SUCCESS) {
		*new_dir = dir;
	} else {
		free(dir);
		*new_dir = NULL;
	}

	return status;
}
Exemplo n.º 8
0
	bool find(const std::string& name, FilePath& result, bool recursive=true) {
		bool found = false;
		if (dir && APR_SUCCESS == check_apr(apr_dir_open(&dir, dirname.c_str(), mPool))) {
			// iterate over directory:
			while ((!found) && APR_SUCCESS == (apr_dir_read(&dirent, APR_FINFO_TYPE|APR_FINFO_NAME, dir))) {
				//printf("test %s %s\n", dirname.c_str(), dirent.name);
				if (dirent.filetype == APR_REG && dirent.name && std::string(dirent.name) == name) {
					result.file(dirent.name);
					result.path(dirname);
					found = true;
					break;
				} else if (recursive && dirent.filetype == APR_DIR && dirent.name && dirent.name[0] != '.') {
					Path path(dirname + dirent.name + AL_FILE_DELIMITER);
					found = path.find(name, result, true);
				}
			}
		} else {
			printf("couldn't open directory %s\n", dirname.c_str());
		}
		return found;
	}
Exemplo n.º 9
0
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;
}
	int glob(const std::string& regex, FileList& result, bool recursive=true) {
		std::regex e(regex);
		if (dir && APR_SUCCESS == check_apr(apr_dir_open(&dir, dirname.c_str(), mPool))) {
			// iterate over directory:
			while (APR_SUCCESS == (apr_dir_read(&dirent, APR_FINFO_TYPE|APR_FINFO_NAME, dir))) {
				//printf("test %s %s\n", dirname.c_str(), dirent.name);
				if (dirent.filetype == APR_REG && dirent.name && std::regex_match(dirname+dirent.name,e) ) {
					FilePath res;
					res.file(dirent.name);
					res.path(dirname);
					result.add(res);
				} else if (recursive && dirent.filetype == APR_DIR && dirent.name && dirent.name[0] != '.') {
					Path path(dirname + dirent.name + AL_FILE_DELIMITER);
					path.glob(regex, result, true);
				}
			}
		} else {
			AL_WARN("couldn't open directory %s", dirname.c_str());
		}
		return result.count();
	}
Exemplo n.º 11
0
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;
}
Exemplo n.º 12
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;
}
Exemplo n.º 13
0
/* Update cursor to point to next top-level directory to search, if any. */
static int next_directory(vtab_cursor *p_cur)
{
    vtab *p_vt = (vtab*)((sqlite3_vtab_cursor*)p_cur)->pVtab;

    /* Get the next path name in the search list. If there isn't next_path()
     * will return 0, as do we. */
    if (next_path(p_cur) == 0)
    {
        /* No more directories to search. End of result set. */
        p_cur->eof = 1;

        return SQLITE_OK;
    }

    /* Now try to open the directory. If it can be opended, set up the dirent to
    ** return as a row in the rowset.
    */

    /* ZERO-FILL DIRENT: Very important to zero-fill here, otherwise we may have
    ** dirent.fname and/or dirent.name members pointing to invalid addresses
    ** after apr_stat(). Our code depends in being able to check NULL status of
    ** these members, so all pointers must be NULL by default.
    */
    memset(&p_cur->current_node->dirent, 0, sizeof(apr_finfo_t));

    /* Check to see if the directory exists */
    p_cur->status = apr_stat( &p_cur->current_node->dirent, 
                              p_cur->current_node->path, 
                              APR_FINFO_TYPE, p_cur->pool );

    if (p_cur->status != APR_SUCCESS)
    {
        /* Directory does not exist */
        p_cur->eof = 1;

        if (p_vt->base.zErrMsg != NULL)
        {
            sqlite3_free(p_vt->base.zErrMsg);
        }

        printf( "Invalid directory: %s\n", p_cur->current_node->path );

        p_vt->base.zErrMsg = sqlite3_mprintf( "Invalid directory: %s", 
                                              p_cur->current_node->path );

        return SQLITE_ERROR;
    }
    else 
    {
        /* If this entry is a directory, then open it */
        if (p_cur->current_node->dirent.filetype == APR_DIR)
        {
            p_cur->status = apr_dir_open( &p_cur->current_node->dir, 
                                          p_cur->current_node->path, p_cur->pool);

            if (p_cur->status != APR_SUCCESS)
            {
                /* Could not open directory */
                p_cur->eof = 1;
                
                if (p_vt->base.zErrMsg != NULL)
                {
                    sqlite3_free(p_vt->base.zErrMsg);
                }
                
                printf("Could not open directory: %s\n", p_cur->current_node->path );
                
                p_vt->base.zErrMsg = sqlite3_mprintf( "Could not open directory: %s", 
                                                      p_cur->current_node->path );
                
                return SQLITE_ERROR;
            }
        }
        else
        {
            /** Set dir to NULL to indicate that this entry is NOT a
             *  directory. In this case, we have a top-level file, not a
             *  top-level directory. vt_next() will pick up on this and do the
             *  Right Thing.
             */
            p_cur->current_node->dir = NULL;
        }
    }

    /** Move cursor to first row: get the directory information on the top level
     *  directory. 
     */
    apr_stat( &p_cur->current_node->dirent, 
              p_cur->current_node->path, 
              APR_FINFO_DIRENT|APR_FINFO_TYPE|APR_FINFO_NAME, p_cur->pool );

    return SQLITE_OK;
}
Exemplo n.º 14
0
const char *fcgi_config_make_dynamic_dir(pool *p, const int wax)
{
    const char *err;
    pool *tp;

    fcgi_dynamic_dir = ap_pstrcat(p, fcgi_socket_dir, "/dynamic", NULL);

    if ((err = fcgi_config_make_dir(p, fcgi_dynamic_dir)))
        return ap_psprintf(p, "can't create dynamic directory \"%s\": %s", fcgi_dynamic_dir, err);

    /* Don't step on a running server unless its OK. */
    if (!wax)
        return NULL;

#ifdef APACHE2
    {
        apr_dir_t * dir;
        apr_finfo_t finfo;

        if (apr_pool_create(&tp, p))
            return "apr_pool_create() failed";

        if (apr_dir_open(&dir, fcgi_dynamic_dir, tp))
            return "apr_dir_open() failed";

        /* delete the contents */

        while (apr_dir_read(&finfo, APR_FINFO_NAME, dir) == APR_SUCCESS)
        {
            if (strcmp(finfo.name, ".") == 0 || strcmp(finfo.name, "..") == 0)
                continue;

            apr_file_remove(finfo.name, tp);
        }
    }

#else /* !APACHE2 */
    {
        DIR *dp;
        struct dirent *dirp = NULL;

        tp = ap_make_sub_pool(p);

        dp = ap_popendir(tp, fcgi_dynamic_dir);
        if (dp == NULL) {
            ap_destroy_pool(tp);
            return ap_psprintf(p, "can't open dynamic directory \"%s\": %s",
                fcgi_dynamic_dir, strerror(errno));
        }

        /* delete the contents */

        while ((dirp = readdir(dp)) != NULL) 
        {
            if (strcmp(dirp->d_name, ".") == 0 || strcmp(dirp->d_name, "..") == 0)
                continue;

            unlink(ap_pstrcat(tp, fcgi_dynamic_dir, "/", dirp->d_name, NULL));
        }
    }

#endif /* !APACHE2 */

    ap_destroy_pool(tp);

    return NULL;
}
Exemplo n.º 15
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;
}
Exemplo n.º 16
0
static int vt_next(sqlite3_vtab_cursor *cur)
{
    vtab_cursor *p_cur = (vtab_cursor*)cur;
    vtab* p_vt         = (vtab*)cur->pVtab;

    /** This is a rather involved function. It is the core of this virtual
     *  table. This function recursively reads down into a directory. It
     *  automatically decends into a directory when it finds one, and
     *  automatically ascends out of it when it has read all of its entries.

     *  The logic is as follows:

     *  The p_cur->current_node (a filenode struct) points to the current file
     *  entry (given by the APR handle p_cur->current_node->dirent) and its
     *  associated directory (given by the APR handle
     *  p_cur->current_node->dirent)

     *  We attempt to read the next entry in p_cur->current_node->dir, filling
     *  the p_cur->current_node->dirent. If we succeed, then we have either a
     *  file or a directory. If we have a directory, then we descend into it. If
     *  we have a file, we proceed as usual. In either case, the dirent entry
     *  will consitute a row in the result set, as we have done as much as we
     *  have to and can exit the function. Our only job is to get to the next
     *  valid file or directory entry to return as the current row in the
     *  rowset.

     *  If there are no more entries in the current directory, then we
     *  deallocate p_cur->current_node and proceed up one directory (given by
     *  p_cur->current_node->parent). We thus set p_cur->current_node to
     *  p_cur->current_node->parent, and start over again.
     */

read_next_entry:

    /** First, check for a special case where the top level directory is
     *  actually a top-level file. In this case, we rely that
     *  p_cur->current_node->dir == NULL (set by next_directory()). If this is
     *  true, resort to next_directory().
     */

    if (p_cur->current_node->dir == NULL)
    {
        return next_directory(p_cur);
    }

    /* Read the next directory entry. */

    /* Increment the current row count. */
    p_cur->count += 1;

    struct filenode* d = p_cur->current_node;
    struct filenode* prev_d = d;

reread_next_entry:

    /* Read the next entry in the directory (d->dir). Fills the d->dirent member. */
    if ( apr_dir_read( &d->dirent, 
                      APR_FINFO_DIRENT|APR_FINFO_PROT|APR_FINFO_TYPE|
                      APR_FINFO_NAME|APR_FINFO_SIZE, 
                      d->dir) != APR_SUCCESS )
    {
        /** If we get here, the call failed. There are no more entries in
         *  directory. 
         */

        /** If we are at the top level directory */
        if (d->parent == NULL)
        {
            /** We are done with this directory. See if there is another
             *  top-level directory to search.
             *
             *  If there is not another directory, next_directory() will have set
             *  eof=1. We are at the end of the result set. If there is another
             *  directory to search, then it will load the next dirent for
             *  us. Either way, we have nothing left to do here.
             */
            return next_directory(p_cur);
        }
        else
        {
            /** There is a parent directory that we still have to search
             *  through. Free this filenode and resume iterating through the
             *  parent.
             */ 
            d = move_up_directory(p_cur);

            /* Start over, reading the next entry from parent. */
            goto read_next_entry;
        }        
    }

    /* If the current dirent is a directory, then descend into it. */
    if (d->dirent.filetype == APR_DIR)
    {     
        /* Skip . and .. entries */
        if (d->dirent.name != NULL)
        {
            if (strcmp(d->dirent.name, ".") == 0 || strcmp(d->dirent.name, "..") == 0)
            {
                goto read_next_entry;
            }
        }

        /* Create a new child directory node */

        /* Combine the path and file names to get full path */

        char path[1024];
        sprintf(&path[0], "%s/%s", d->path, d->dirent.name);

        /* Allocate space for new filenode and initlialize members. */
        d              = malloc(sizeof(struct filenode));
        d->path        = strdup(path);
        d->parent      = p_cur->current_node;

        /* See note ZERO-FILL DIRENT below. */
        memset(&d->dirent, 0, sizeof(apr_finfo_t));

        /* Set current pointer to it. */
        p_cur->current_node = d;

        /* Clear the pool memory associated with the path string allocated above. */
        apr_pool_clear(p_cur->tmp_pool);
        
        /* Open the directory */
        if ((p_cur->status = apr_dir_open(&d->dir, d->path, p_cur->pool)) != APR_SUCCESS)
        {
            /* Problem. Couldn't open directory. */

            fprintf( stderr, "Failed to open directory: %s\n", 
                     p_cur->current_node->path );

            /* Set this to null to move_up_directory() doesn't try to
             * apr_close() it (->core dump) */
            p_cur->current_node->dir = NULL;

            /* Skip to next entry */
            deallocate_filenode(d);
            p_cur->current_node = d = prev_d;
            goto reread_next_entry;
        }

        /* Else we were able to open directory. Update the currnet dirent info
        ** to that of the opened directory. This is our next row in the result
        ** set.
        */
        apr_stat( &d->dirent, d->path, 
                  APR_FINFO_DIRENT|APR_FINFO_TYPE|APR_FINFO_NAME, 
                  p_cur->pool );
    }

    return SQLITE_OK;
}
Exemplo n.º 17
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;
}
void nx_expr_proc__xm_fileop_file_remove(nx_expr_eval_ctx_t *eval_ctx,
					 nx_module_t *module,
					 nx_expr_arg_list_t *args)
{
    nx_expr_arg_t *arg;
    nx_value_t file;
    apr_status_t rv;
    apr_pool_t *pool = NULL;
    apr_dir_t *dir;
    nx_exception_t e;
    nx_string_t *dirname = NULL;
    nx_string_t *fname = NULL;
    char *filename;
    char *idx;
    int flags = 0;
    apr_finfo_t finfo;
    nx_expr_arg_t *older;
    nx_value_t olderval;
    apr_time_t older_time = 0LL;

    ASSERT(module != NULL);

    ASSERT(args != NULL);
    arg = NX_DLIST_FIRST(args);
    ASSERT(arg != NULL);
    ASSERT(arg->expr != NULL);

    nx_expr_evaluate(eval_ctx, &file, arg->expr);

    if ( file.defined != TRUE )
    {
	throw_msg("'file' is undef");
    }

    try
    {
	if ( file.type != NX_VALUE_TYPE_STRING )
	{
	    throw_msg("string type required for 'file'");
	}

	older = NX_DLIST_NEXT(arg, link);
	if ( older != NULL )
	{
	    ASSERT(older->expr != NULL);
	    nx_expr_evaluate(eval_ctx, &olderval, older->expr);
	    if ( olderval.type != NX_VALUE_TYPE_DATETIME )
	    {
		nx_value_kill(&olderval);
		throw_msg("datetime type required for 'older'");
	    }
	    if ( olderval.defined == TRUE )
	    {
		older_time = olderval.datetime;
	    }
	}

	if ( apr_fnmatch_test(file.string->buf) != 0 )
	{ // we have wildcards, expand it
	    pool = nx_pool_create_core();

	    filename = file.string->buf;
	    idx = strrchr(filename, '/');
#ifndef WIN32
	    flags = APR_FNM_CASE_BLIND;
	    if ( idx == NULL ) 
	    {
		idx = strrchr(filename, '\\');
	    }
#endif
	    if ( idx == NULL )
	    {
		dirname = nx_string_create("."NX_DIR_SEPARATOR, -1);
	    }
	    else
	    {
		dirname = nx_string_create(filename, (int) (idx + 1 - filename));
		filename = idx + 1;
	    }

	    CHECKERR_MSG(apr_dir_open(&dir, dirname->buf, pool),
			 "failed to open directory: %s", dirname->buf);
	    fname = nx_string_new();

	    while ( apr_dir_read(&finfo, APR_FINFO_NAME | APR_FINFO_TYPE | APR_FINFO_CTIME,
				 dir) == APR_SUCCESS )
	    {
		if ( finfo.filetype == APR_REG )
		{
		    log_debug("checking '%s' against wildcard '%s':", finfo.name, filename);
		    if ( apr_fnmatch(filename, finfo.name, flags) == APR_SUCCESS )
		    {
			nx_string_sprintf(fname, "%s%s", dirname->buf, finfo.name);

			if ( (older_time == 0) ||
			     ((older_time != 0) && (finfo.ctime < older_time)) )
			{
			    log_debug("'%s' matches wildcard '%s' and is 'older', removing",
				      fname->buf, file.string->buf);
			    log_info("removing file %s", fname->buf);
			    rv = apr_file_remove(fname->buf, NULL);
			    if ( APR_STATUS_IS_ENOENT(rv) )
			    {
			    }
			    else if ( rv == APR_SUCCESS )
			    {
			    }
			    else
			    {
				log_aprerror(rv, "failed to remove file '%s'", fname->buf);
			    }
			    _reopen_logfile(fname->buf);
			}
		    }
		}
	    }
	    nx_string_free(fname);
	    apr_pool_destroy(pool);
	}
	else
	{
	    CHECKERR_MSG(apr_file_remove(file.string->buf, NULL), 
			 "failed to remove file '%s'", file.string->buf);
	}
    }
    catch(e)
    {
	nx_value_kill(&file);
	if ( pool != NULL )
	{
	    apr_pool_destroy(pool);
	}
	if ( dirname != NULL )
	{
	    nx_string_free(dirname);
	}
	log_exception(e);
    }
}
	bool open(const std::string& dirName){
		return APR_SUCCESS ==
			check_apr(apr_dir_open(&dir, dirName.c_str(), mPool));
	}
Exemplo n.º 20
0
	Path(const std::string& dirname) : ImplAPR(), dir(NULL), dirname(dirname) {
		if (APR_SUCCESS != check_apr(apr_dir_open(&dir, dirname.c_str(), mPool))) {
			//printf("dir %p\n", dir);
			dir=NULL;
		}
	}
Exemplo n.º 21
0
int main(int argc, char *argv[])
{
  char *outname = NULL;
  FILE *fp;
  FILE *input_file;
  char *input_file_name = NULL;
  char *path_prefix = NULL;
  int index;
  int process_self = 0;
  int verbose = 0;
  int max_build, accum_build;
  int max_year, max_month, max_day;
  int ismodified, filemodified;
  char prefix[MAX_SYMBOLLENGTH], suffix[MAX_SYMBOLLENGTH];
  char modified_suffix[2];
  int write_java = 0;   /* flag for Java output, 0=.h output, 1=.java output */
  /* java package to put revision info in.
   * REVIEW - I assume if you want Java output you will specify a package. */
  char *java_package = NULL;

  if (argc <= 1)
    about();

  /* collect the options */
  prefix[0] = '\0';
  suffix[0] = '\0';
  
  for (index = 1; index < argc; index++) {
    /* check for options */
    if (argv[index][0] == '-'
#if defined __WIN32__ || defined _Win32 || defined _WIN32
     || argv[index][0] == '/'
#endif
    )
    {
      switch (argv[index][1]) {
      case 'f': {
        int len;
        char *ptr = strchr(&argv[index][2], '#');
        len = (ptr != NULL) ? (int)(ptr - &argv[index][2]) : (int)strlen(&argv[index][2]);
        if (len >= MAX_SYMBOLLENGTH)
          len = MAX_SYMBOLLENGTH - 1;
        strncpy(prefix, &argv[index][2], len);
        prefix[len] = '\0';
        ptr = (ptr != NULL) ? ptr + 1 : strchr(argv[index], '\0');
        len = (int)strlen(ptr);
        if (len >= MAX_SYMBOLLENGTH)
          len = MAX_SYMBOLLENGTH - 1;
        strncpy(suffix, ptr, len);        
        suffix[len] = '\0';
        break;
      } /* case */
      case 'i':
        process_self = 1;
        break;
      case 'j':
        write_java=1;
        java_package = &argv[index][2];
        break;
      case 'o':
        outname = &argv[index][2];
        break;
      case 'r':
        input_file_name = &argv[index][2];
        break;
      case 'p':
        path_prefix = &argv[index][2];
        break;
      case 'v':
        verbose = 1;
        break;
      default:
        fprintf(stderr, "Invalid option '%s'\n", argv[index]);
        about();
      } /* switch */
    } /* if */
  } /* for */

  if (outname == NULL)
    outname = write_java ? "SvnRevision.java" : "uni_revision.h";
  if (!process_self && *outname != '\0')
    remove(outname);

  /* phase 1: scan through all files and get the highest build number */

  max_build = 0;
  accum_build = 0;      /* for RCS / CVS */
  max_year = max_month = max_day = 0;
  ismodified = 0;

  if(input_file_name) {
    input_file = fopen(input_file_name, "r");
    if (input_file != NULL) {
      apr_dir_t *dir;
      apr_finfo_t finfo;
      apr_status_t rv;
      apr_pool_t *pool;
      char *file_path;
      char dir_path[256]; /* line */
      int offset = 0;
      if(path_prefix)
        offset = sprintf(dir_path, "%s", path_prefix);
      else
        offset = sprintf(dir_path, "../../");
      
      apr_initialize();
      apr_pool_create(&pool,NULL);
      while (fgets(dir_path + offset, sizeof(dir_path) - offset, input_file) != NULL ) { /* read a line */ 
        size_t len = strlen(dir_path)-1;
        if(dir_path[len] == '\n') 
          dir_path[len] = 0;
        rv = apr_dir_open(&dir,dir_path,pool);
        if(rv == APR_SUCCESS) {
          while (apr_dir_read(&finfo, APR_FINFO_NAME, dir) == APR_SUCCESS) { /* get next file */
            if(finfo.filetype != APR_REG) continue;

            apr_filepath_merge(&file_path,dir_path,finfo.name,0,pool);

            filemodified = 0;
            if (strcasecmp(file_path, outname)!=0)
              processfile(file_path, 0, &max_build, &accum_build, &max_year, &max_month, &max_day, &filemodified);
            if (filemodified && verbose)
              fprintf(stderr, "\tNotice: modified file '%s'\n", file_path);
            ismodified = ismodified || filemodified;
          }
          apr_dir_close(dir);
        }
        else {
          fprintf(stderr, "No such directory '%s'\n", dir_path);
        }
      }
      fclose (input_file);
      apr_pool_destroy(pool);
      apr_terminate();
    }
    else {
      fprintf(stderr, "No such input file '%s'\n", input_file_name);
    }
  }
  else {
    for (index = 1; index < argc; index++) {
      /* skip the options (already handled) */
      if (argv[index][0] == '-'
#if defined __WIN32__ || defined _Win32 || defined _WIN32
       || argv[index][0] == '/'
#endif
      )
        continue;

      filemodified = 0;
      if (strcasecmp(argv[index], outname)!=0)
        processfile(argv[index], 0, &max_build, &accum_build, &max_year, &max_month, &max_day, &filemodified);
      if (filemodified && verbose)
        fprintf(stderr, "\tNotice: modified file '%s'\n", argv[index]);
      ismodified = ismodified || filemodified;
    } /* for */
  }

  /* also run over the existing header file, if any */
  if (process_self && *outname != '\0')
    processfile(outname, 1, &max_build, &accum_build, &max_year, &max_month, &max_day, NULL/*&ismodified*/);

  if (accum_build > max_build)
    max_build = accum_build;
  modified_suffix[0] = ismodified ? 'M' : '\0';
  modified_suffix[1] = '\0';

  /* phase 2: write a file with this highest build number */
  if (*outname == '\0') {
    fp = stdout;
  } else if ((fp = fopen(outname, "w")) == NULL) {
    fprintf(stderr, "Failed to create output file '%s'\n", outname);
    return 2;
  } /* if */
  if (*outname != '\0') {
    /* don't print the comments to stdout */
    fprintf(fp, "/* This file was generated by the \"svnrev\" utility\n"
                " * (http://www.compuphase.com/svnrev.htm).\n"
                " * You should not modify it manually, as it may be re-generated.\n"
                " *\n"
                " * $Revision: %d%s$\n"
                " * $Date: %04d-%02d-%02d$\n"
                " */\n\n", max_build, modified_suffix, max_year, max_month, max_day);
  } /* if */

  fprintf(fp, "#ifndef UNI_REVISION_H\n");
  fprintf(fp, "#define UNI_REVISION_H\n\n");
  fprintf(fp, "#define UNI_REVISION\t\t%d\n", max_build);
  fprintf(fp, "#define UNI_REVISION_STRING\t\"%s%d%s%s\"\n", prefix, max_build, modified_suffix, suffix);
  fprintf(fp, "#define UNI_REVISION_DATE\t\"%04d-%02d-%02d\"\n", max_year, max_month, max_day);
  fprintf(fp, "#define UNI_REVISION_STAMP\t%04d%02d%02dL\n", max_year, max_month, max_day);
  fprintf(fp, "#define UNI_REVISION_MODIFIED\t%d\n", ismodified);
  fprintf(fp, "\n#endif /* UNI_REVISION_H */\n");

  if (*outname != '\0')
    fclose(fp);

  return 0;
}
Exemplo n.º 22
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;
}
Exemplo n.º 23
0
/** Process parsed XML document */
static apt_bool_t unimrcp_client_doc_process(unimrcp_client_loader_t *loader, const char *dir_path, apr_xml_doc *doc, apr_pool_t *pool)
{
	const apr_xml_elem *elem;
	const apr_xml_elem *root;
	const apr_xml_attr *attr;
	const char *version = NULL;
	const char *subfolder = NULL;

	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 ? root->name : "null");
		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 if(strcasecmp(elem->name,"misc") == 0) {
			unimrcp_client_misc_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;
		char *subdir_path;

		if (!dir_path) {
			apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Attempt to Process Subdirectory when "
				"Creating from Config String");
			return TRUE;
		}

		if(apr_filepath_merge(&subdir_path,dir_path,subfolder,APR_FILEPATH_NATIVE,pool) == APR_SUCCESS) {
			apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Enter Directory [%s]",subdir_path);
			rv = apr_dir_open(&dir,subdir_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,subdir_path,finfo.name);
					}
				}
				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;
}
Exemplo n.º 24
0
/*
 * 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;
}
Exemplo n.º 25
0
int lua_apr_dir_remove_recursive(lua_State *L)
{
  apr_status_t status;
  apr_pool_t *outer_pool; /* used to store todo/done arrays and directory pathnames */
  apr_pool_t *middle_pool; /* used to store directory handles (apr_dir_t structs) */
  apr_pool_t *inner_pool; /* used to store pathnames of non-subdirectory entries */
  apr_array_header_t *todo, *done;
  apr_dir_t *directory;
  apr_finfo_t info;
  char **top, *tmp;
  const char *filepath;
  int allocation_counter;

  directory = NULL;
  outer_pool = middle_pool = inner_pool = NULL;
  filepath = luaL_checkstring(L, 1);
  allocation_counter = 0;

  status = apr_pool_create(&outer_pool, NULL);
  if (APR_SUCCESS == status)
    status = apr_pool_create(&middle_pool, NULL);
  if (APR_SUCCESS == status)
    status = apr_pool_create(&inner_pool, NULL);
  if (APR_SUCCESS != status)
    goto cleanup;

# define out_of_memory do { \
    status = APR_ENOMEM; \
    goto cleanup; \
  } while (0)

# define push_filepath(stack, filepath) do { \
    const char **p = apr_array_push(stack); \
    if (p != NULL) *p = filepath; else out_of_memory; \
  } while (0)

  todo = apr_array_make(outer_pool, 0, sizeof filepath);
  done = apr_array_make(outer_pool, 0, sizeof filepath);
  if (todo == NULL || done == NULL)
    out_of_memory;

  push_filepath(todo, filepath);

  while ((top = apr_array_pop(todo))) {
    filepath = *(char**)top;
    apr_pool_clear(middle_pool);
    status = apr_dir_open(&directory, filepath, middle_pool);
    if (status != APR_SUCCESS) {
      directory = NULL;
      goto cleanup;
    }
    for (;;) {
      /* This is a compromise between having `inner_pool' grow almost unbounded
       * on very large directories (e.g. ~/Maildir/) and clearing it for every
       * non-subdirectory pathname that's allocated (very inefficient). */
      if (allocation_counter % 1000 == 0)
        apr_pool_clear(inner_pool);
      /* FIXME?! apr_dir_read() uses directory->pool (middle_pool) for allocation */
      status = apr_dir_read(&info, APR_FINFO_NAME|APR_FINFO_TYPE|APR_FINFO_LINK, directory);
      if (APR_STATUS_IS_ENOENT(status))
        break; /* no more entries */
      else if (status != APR_SUCCESS && status != APR_INCOMPLETE)
        goto cleanup; /* something went wrong */
      else if (filename_symbolic(info.name))
        continue; /* bogus entry */
      else if (info.filetype == APR_DIR) {
        /* recurse into subdirectory */
        status = apr_filepath_merge(&tmp, filepath, info.name, 0, outer_pool);
        if (status != APR_SUCCESS)
          goto cleanup;
        push_filepath(todo, tmp);
      } else {
        /* delete non-subdirectory entry */
        status = apr_filepath_merge(&tmp, filepath, info.name, 0, inner_pool);
        allocation_counter++;
        if (APR_SUCCESS == status)
          status = apr_file_remove(tmp, inner_pool);
        if (APR_SUCCESS != status)
          goto cleanup;
      }
    }
    status = apr_dir_close(directory);
    directory = NULL;
    if (status != APR_SUCCESS)
      goto cleanup;
    push_filepath(done, filepath);
  }

# undef out_of_memory
# undef push_filepath

  while ((top = apr_array_pop(done))) {
    filepath = *(char**)top;
    if (allocation_counter++ % 100 == 0)
      apr_pool_clear(middle_pool);
    status = apr_dir_remove(filepath, middle_pool);
    if (status != APR_SUCCESS)
      goto cleanup;
  }

cleanup:

  if (directory != NULL)
    apr_dir_close(directory);
  if (inner_pool != NULL)
    apr_pool_destroy(inner_pool);
  if (middle_pool != NULL)
    apr_pool_destroy(middle_pool);
  if (outer_pool != NULL)
    apr_pool_destroy(outer_pool);

  return push_status(L, status);
}