Пример #1
0
int DB_init()
{
    apr_pool_t *p = NULL;
    apr_pool_initialize();
    apr_pool_create(&p, NULL);

    if (access(DB_DIR, W_OK | X_OK) == -1) {
        apr_status_t rc = apr_dir_make_recursive(DB_DIR,
            APR_UREAD | APR_UWRITE | APR_UEXECUTE |
            APR_GREAD | APR_GWRITE | APR_GEXECUTE, p);
        check(rc == APR_SUCCESS, "Failed to make database dir: %s", DB_DIR);
    }

    if (access(DB_FILE, W_OK) == -1) {
        FILE *db = DB_open(DB_FILE, "w");
        check(db, "Cannot open database: %s", DB_FILE);
        DB_close(db);
    }

    apr_pool_destroy(p);
    return 0;

error:
    apr_pool_destroy(p);
    return -1;
}
Пример #2
0
int DB_init()
{
	apr_pool_t *p = NULL;
	apr_pool_initialize();
	apr_pool_create(&p, NULL);

	if(access(DB_DIR, W_OK|X_OK) == -1){
		apr_status_t rc = apr_dir_make_recursive(DB_DIR,
				APR_UREAD|APR_UWRITE|APR_UEXECUTE |
				APR_GREAD|APR_GWRITE|APR_GEXECUTE, p);
		check(rc == APR_SUCCESS, "Could not open %s.", DB_DIR);
	} else {
		debug("Access to %s is okay", DB_DIR);
	}

	if(access(DB_FILE, W_OK) == -1){
		FILE *db = DB_open(DB_FILE, "w");
		check(db, "Could not open %s.", DB_FILE);
		DB_close(db);
	} else {
		debug("No need to create db file %s", DB_FILE);
	}

	apr_pool_destroy(p);
	return 0;

error:
	apr_pool_destroy(p);
	return -1;
}
Пример #3
0
int DB_init()
{

	apr_pool_t *p = NULL;// apr_pool_t被封装了,只能通过API对其进行操作
	apr_pool_initialize();
	apr_pool_create(&p, NULL); // 创建memory pool,返回apr_status_t类型的状态码

	// 确定DB_DIR是否存在、是否有写和执行权限,成功返回0,否则-1
	if(access(DB_DIR, W_OK | X_OK) == -1)
	{
		// 权限测试失败,可能是DB_DIR不存在,尝试创建
		apr_status_t rc = 
			apr_dir_make_recursive(DB_DIR,
								   APR_UREAD | APR_UWRITE | APR_UEXECUTE |
								   APR_GREAD | APR_GWRITE | APR_GEXECUTE, p);
		check(rc == APR_SUCCESS, "Failed to make database dir: %s", DB_DIR);
	}
	// 确定DB_FILE是否存在、是否有写权限
	if(access(DB_FILE, W_OK) == -1)
	{
		// 权限测试失败,可能是DB_FILE不存在,尝试创建
		FILE *db = DB_open(DB_FILE, "w");
		check(db, "Cannot open database: %s", DB_FILE);
		DB_close(db);
	}

	apr_pool_destroy(p);
	return 0;

  error:
	apr_pool_destroy(p);
	return -1;
}
Пример #4
0
/*
 * Sets into the saved_request the designated filename, according to configured base
 * directory and request data (URI, headers, etc). Also creates the base directory if it
 * doesn't exist
 */
static int set_filename(tee_saved_request *sr)
{
	apr_time_exp_t t;
	apr_time_exp_gmt(&t, sr->time_enqueued);

	// Obtaining directory name
	const char *dir;
	dir = apr_psprintf(sr->pool, "%s/%04d%02d%02d/%02d",
			sr->base_dir, 1900 + t.tm_year, t.tm_mon + 1, t.tm_mday, t.tm_hour);

	// Creating directory if needed
	apr_status_t rc = apr_dir_make_recursive(dir, APR_FPROT_OS_DEFAULT, sr->pool);
	if (rc != APR_SUCCESS) {
		ap_log_error(APLOG_MARK, APLOG_ERR, 0, sr->server, "tee: Cannot create directory %s: %s",
				dir, tee_get_error_string(rc, sr->pool));
		return 1;
	}

	// Setting file name
	unsigned long file_id = ((unsigned long) t.tm_min * 60 + t.tm_sec) * 1000000 + t.tm_usec; // usec in hour
	char b[MAX_FILENAME_LEN]; // Filename is cut in case the URI is too long
	const char *rec_id = get_header_value(sr, sr->id_header, "");
	const char *host = get_header_value(sr, "Host", "");
	apr_snprintf(b, MAX_FILENAME_LEN, "%010lu_%s_%s_%s%s", file_id, rec_id, sr->method, host, sr->uri);
	tee_replace(b, "/", '_'); // Replace the slash (invalid character in file names)
	sr->filename = apr_psprintf(sr->pool, "%s/%s_%d", dir, b, sr->status);
	return 0;
}
Пример #5
0
apr_status_t kahanaIOMakeDir( apr_pool_t *p, apr_fileperms_t perm, ... )
{
	apr_status_t rc = APR_SUCCESS;
	const char *path = NULL;
	va_list args;
	
	va_start( args, perm );
	while( ( path = va_arg( args, const char* ) ) )
	{
		// check dir
		if( ( rc = kahanaIOPathTypeIs( p, path, APR_DIR, 0 ) ) && 
			rc != APR_NOTFOUND && rc != APR_ENOENT ){
			break;
		}
		else if( rc == APR_ENOENT )
		{
			if( ( rc = apr_dir_make_recursive( path, perm, p ) ) ){
				kahanaLogPut( NULL, NULL, "failed to apr_dir_make_recursive(): %s", STRERROR_APR( rc ) );
				break;
			}
		}
	}
	va_end(args);
	
	return rc;
}
Пример #6
0
int DB_init()
{
    apr_status_t rv;
    apr_pool_t *mp;

    rv = apr_initialize();
    assert(rv == APR_SUCCESS);

    apr_pool_create(&mp, NULL);

    if (access(DB_DIR, W_OK | X_OK) == -1) {
        apr_status_t rc = apr_dir_make_recursive(
            DB_DIR,
            APR_UREAD | APR_UWRITE | APR_UEXECUTE | APR_GREAD | APR_GWRITE | APR_GEXECUTE, 
            mp
        );

        assert(rc == APR_SUCCESS);
    }
    
    if (access(DB_FILE, W_OK) == -1) {
        FILE *db = DB_open(DB_FILE, "w");
        assert(db != NULL);
        DB_close(db);
    }
    
    apr_pool_destroy(mp);
    apr_terminate();

    return 0;
}
	bool make(const std::string& path, int perms, bool recursive){

	 	apr_fileperms_t apr_perms = APR_FPROT_UREAD | APR_FPROT_UWRITE | APR_FPROT_UEXECUTE;

		if(recursive){
			return APR_SUCCESS == check_apr(apr_dir_make_recursive(path.c_str(), apr_perms, mPool));
		}
		else {
			return APR_SUCCESS == check_apr(apr_dir_make(path.c_str(), apr_perms, mPool));
		}
	}
Пример #8
0
Файл: db.c Проект: xihh87/lcthw
int DB_init()
{
	apr_pool_t *p = NULL;
	apr_pool_initialize();
	apr_pool_create(&p, NULL);

	if (access(DB_DIR, W_OK | X_OK) == -1) {
		apr_status_t rc = apr_dir_make_recursive(DB_DIR,
				APR_UREAD | APR_UWRITE | APR_UEXECUTE |
				APR_GREAD | APR_GWRITE | APR_GEXECUTE, p);
		check(rc == APR_SUCCESS, "Failed to make database dir: %s", DB_DIR)
	}
Пример #9
0
int lua_apr_dir_make_recursive(lua_State *L)
{
  apr_status_t status;
  apr_pool_t *memory_pool;
  const char *filepath;
  apr_fileperms_t permissions;

  memory_pool = to_pool(L);
  filepath = luaL_checkstring(L, 1);
  permissions = check_permissions(L, 2, 0);
  status = apr_dir_make_recursive(filepath, permissions, memory_pool);

  return push_status(L, status);
}
Пример #10
0
static void test_mkdir_recurs(abts_case *tc, void *data)
{
    apr_status_t rv;
    apr_finfo_t finfo;

    rv = apr_dir_make_recursive("data/one/two/three", 
                                APR_UREAD | APR_UWRITE | APR_UEXECUTE, p);
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);

    rv = apr_stat(&finfo, "data/one", APR_FINFO_TYPE, p);
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
    ABTS_INT_EQUAL(tc, APR_DIR, finfo.filetype);

    rv = apr_stat(&finfo, "data/one/two", APR_FINFO_TYPE, p);
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
    ABTS_INT_EQUAL(tc, APR_DIR, finfo.filetype);

    rv = apr_stat(&finfo, "data/one/two/three", APR_FINFO_TYPE, p);
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
    ABTS_INT_EQUAL(tc, APR_DIR, finfo.filetype);
}
void nx_expr_proc__xm_fileop_dir_make(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 path;
    apr_status_t rv;
    apr_pool_t *pool;

    ASSERT(module != NULL);

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

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

    if ( path.defined != TRUE )
    {
	throw_msg("'path' is undef");
    }
    if ( path.type != NX_VALUE_TYPE_STRING )
    {
	nx_value_kill(&path);
	throw_msg("string type required for 'path'");
    }

    pool = nx_pool_create_core();
    if ( (rv = apr_dir_make_recursive(path.string->buf, APR_OS_DEFAULT, pool)) != APR_SUCCESS )
    {
	log_aprerror(rv, "failed to create directory '%s'", path.string->buf);
    }
    apr_pool_destroy(pool);
    nx_value_kill(&path);
}
Пример #12
0
/**
 * \brief write tile data to disk
 *
 * writes the content of mapcache_tile::data to disk.
 * \returns MAPCACHE_FAILURE if there is no data to write, or if the tile isn't locked
 * \returns MAPCACHE_SUCCESS if the tile has been successfully written to disk
 * \private \memberof mapcache_cache_disk
 * \sa mapcache_cache::tile_set()
 */
static void _mapcache_cache_disk_set(mapcache_context *ctx, mapcache_cache *pcache, mapcache_tile *tile)
{
  apr_size_t bytes;
  apr_file_t *f;
  apr_status_t ret;
  char errmsg[120];
  char *filename, *hackptr1, *hackptr2=NULL;
  mapcache_cache_disk *cache = (mapcache_cache_disk*)pcache;
  const int creation_retry = cache->creation_retry;
  int retry_count_create_file = 0;

#ifdef DEBUG
  /* all this should be checked at a higher level */
  if(!tile->encoded_data && !tile->raw_image) {
    ctx->set_error(ctx,500,"attempting to write empty tile to disk");
    return;
  }
  if(!tile->encoded_data && !tile->tileset->format) {
    ctx->set_error(ctx,500,"received a raw tile image for a tileset with no format");
    return;
  }
#endif

  cache->tile_key(ctx, cache, tile, &filename);
  GC_CHECK_ERROR(ctx);

  /* find the location of the last '/' in the string */
  hackptr1 = filename;
  while(*hackptr1) {
    if(*hackptr1 == '/')
      hackptr2 = hackptr1;
    hackptr1++;
  }
  *hackptr2 = '\0';

  if(APR_SUCCESS != (ret = apr_dir_make_recursive(filename,APR_OS_DEFAULT,ctx->pool))) {
    /*
     * apr_dir_make_recursive sometimes sends back this error, although it should not.
     * ignore this one
     */
    if(!APR_STATUS_IS_EEXIST(ret)) {
      ctx->set_error(ctx, 500, "failed to create directory %s: %s",filename, apr_strerror(ret,errmsg,120));
      return;
    }
  }
  *hackptr2 = '/';

  ret = apr_file_remove(filename,ctx->pool);
  if(ret != APR_SUCCESS && !APR_STATUS_IS_ENOENT(ret)) {
    ctx->set_error(ctx, 500,  "failed to remove file %s: %s",filename, apr_strerror(ret,errmsg,120));
  }


#ifdef HAVE_SYMLINK
  if(cache->symlink_blank) {
    if(!tile->raw_image) {
      tile->raw_image = mapcache_imageio_decode(ctx, tile->encoded_data);
      GC_CHECK_ERROR(ctx);
    }
    if(mapcache_image_blank_color(tile->raw_image) != MAPCACHE_FALSE) {
      char *blankname;
      int retry_count_create_symlink = 0;
      char *blankname_rel = NULL;
      _mapcache_cache_disk_blank_tile_key(ctx,cache,tile,tile->raw_image->data,&blankname);
      if(apr_file_open(&f, blankname, APR_FOPEN_READ, APR_OS_DEFAULT, ctx->pool) != APR_SUCCESS) {
        int isLocked;
        void *lock;
        char *blankdirname;
        if(!tile->encoded_data) {
          tile->encoded_data = tile->tileset->format->write(ctx, tile->raw_image, tile->tileset->format);
          GC_CHECK_ERROR(ctx);
        }
        /* create the blank file */
        blankdirname = apr_psprintf(ctx->pool, "%s/%s/%s/blanks",
                                          cache->base_directory,
                                          tile->tileset->name,
                                          tile->grid_link->grid->name);
        if(APR_SUCCESS != (ret = apr_dir_make_recursive(
                                   blankdirname, APR_OS_DEFAULT,ctx->pool))) {
          if(!APR_STATUS_IS_EEXIST(ret)) {
            ctx->set_error(ctx, 500,  "failed to create directory %s for blank tiles",blankdirname, apr_strerror(ret,errmsg,120));
            return;
          }
        }

        /* aquire a lock on the blank file */
        isLocked = mapcache_lock_or_wait_for_resource(ctx,ctx->config->locker,blankname, &lock);

        if(isLocked == MAPCACHE_TRUE) {

          if((ret = apr_file_open(&f, blankname,
                                  APR_FOPEN_CREATE|APR_FOPEN_WRITE|APR_FOPEN_BUFFERED|APR_FOPEN_BINARY,
                                  APR_OS_DEFAULT, ctx->pool)) != APR_SUCCESS) {
            ctx->set_error(ctx, 500,  "failed to create file %s: %s",blankname, apr_strerror(ret,errmsg,120));
            mapcache_unlock_resource(ctx,ctx->config->locker,blankname, lock);
            return; /* we could not create the file */
          }

          bytes = (apr_size_t)tile->encoded_data->size;
          ret = apr_file_write(f,(void*)tile->encoded_data->buf,&bytes);
          if(ret != APR_SUCCESS) {
            ctx->set_error(ctx, 500,  "failed to write data to file %s (wrote %d of %d bytes): %s",blankname, (int)bytes, (int)tile->encoded_data->size, apr_strerror(ret,errmsg,120));
            mapcache_unlock_resource(ctx,ctx->config->locker,blankname, lock);
            return; /* we could not create the file */
          }

          if(bytes != tile->encoded_data->size) {
            ctx->set_error(ctx, 500,  "failed to write image data to %s, wrote %d of %d bytes", blankname, (int)bytes, (int)tile->encoded_data->size);
            mapcache_unlock_resource(ctx,ctx->config->locker,blankname, lock);
            return;
          }
          apr_file_close(f);
          mapcache_unlock_resource(ctx,ctx->config->locker,blankname, lock);
#ifdef DEBUG
          ctx->log(ctx,MAPCACHE_DEBUG,"created blank tile %s",blankname);
#endif
        }
      } else {
        apr_file_close(f);
      }


      /*
       * compute the relative path between tile and blank tile
       */
      blankname_rel = relative_path(ctx,filename, blankname);
      GC_CHECK_ERROR(ctx);

      /*
       * depending on configuration symlink creation will retry if it fails.
       * this can happen on nfs mounted network storage.
       * the solution is to create the containing directory again and retry the symlink creation.
       */
      while(symlink(blankname_rel, filename) != 0) {
        retry_count_create_symlink++;

        if(retry_count_create_symlink > creation_retry) {
          char *error = strerror(errno);
          ctx->set_error(ctx, 500, "failed to link tile %s to %s: %s",filename, blankname_rel, error);
          return; /* we could not create the file */
        }

        *hackptr2 = '\0';

        if(APR_SUCCESS != (ret = apr_dir_make_recursive(filename,APR_OS_DEFAULT,ctx->pool))) {
          if(!APR_STATUS_IS_EEXIST(ret)) {
            ctx->set_error(ctx, 500, "failed to create symlink, can not create directory %s: %s",filename, apr_strerror(ret,errmsg,120));
            return; /* we could not create the file */
          }
        }

        *hackptr2 = '/';
      }
#ifdef DEBUG
      ctx->log(ctx, MAPCACHE_DEBUG, "linked blank tile %s to %s",filename,blankname);
#endif
      return;
    }
  }
#endif /*HAVE_SYMLINK*/

  /* go the normal way: either we haven't configured blank tile detection, or the tile was not blank */

  if(!tile->encoded_data) {
    tile->encoded_data = tile->tileset->format->write(ctx, tile->raw_image, tile->tileset->format);
    GC_CHECK_ERROR(ctx);
  }

  /*
   * depending on configuration file creation will retry if it fails.
   * this can happen on nfs mounted network storage.
   * the solution is to create the containing directory again and retry the file creation.
   */
  while((ret = apr_file_open(&f, filename,
                             APR_FOPEN_CREATE|APR_FOPEN_WRITE|APR_FOPEN_BUFFERED|APR_FOPEN_BINARY,
                             APR_OS_DEFAULT, ctx->pool)) != APR_SUCCESS) {

    retry_count_create_file++;

    if(retry_count_create_file > creation_retry) {
      ctx->set_error(ctx, 500, "failed to create file %s: %s",filename, apr_strerror(ret,errmsg,120));
      return; /* we could not create the file */
    }

    *hackptr2 = '\0';

    if(APR_SUCCESS != (ret = apr_dir_make_recursive(filename,APR_OS_DEFAULT,ctx->pool))) {
      if(!APR_STATUS_IS_EEXIST(ret)) {
        ctx->set_error(ctx, 500, "failed to create file, can not create directory %s: %s",filename, apr_strerror(ret,errmsg,120));
        return; /* we could not create the file */
      }
    }

    *hackptr2 = '/';
  }

  bytes = (apr_size_t)tile->encoded_data->size;
  ret = apr_file_write(f,(void*)tile->encoded_data->buf,&bytes);
  if(ret != APR_SUCCESS) {
    ctx->set_error(ctx, 500,  "failed to write data to file %s (wrote %d of %d bytes): %s",filename, (int)bytes, (int)tile->encoded_data->size, apr_strerror(ret,errmsg,120));
    return; /* we could not create the file */
  }

  if(bytes != tile->encoded_data->size) {
    ctx->set_error(ctx, 500, "failed to write image data to %s, wrote %d of %d bytes", filename, (int)bytes, (int)tile->encoded_data->size);
  }
  ret = apr_file_close(f);
  if(ret != APR_SUCCESS) {
    ctx->set_error(ctx, 500,  "failed to close file %s:%s",filename, apr_strerror(ret,errmsg,120));
    return; /* we could not create the file */
  }

}
Пример #13
0
SWITCH_DECLARE(switch_status_t) switch_dir_make_recursive(const char *path, switch_fileperms_t perm, switch_memory_pool_t *pool)
{
	return apr_dir_make_recursive(path, perm, pool);
}
Пример #14
0
apr_status_t
procmgr_post_config(server_rec * main_server, apr_pool_t * configpool)
{
    apr_status_t rv;
    apr_finfo_t finfo;
    fcgid_server_conf *sconf = ap_get_module_config(main_server->module_config,
                                                    &fcgid_module);

    /* Calculate procmgr_fetch_cmd wake up interval */
    g_wakeup_timeout = fcgid_min(sconf->error_scan_interval,
                                 sconf->busy_scan_interval);
    g_wakeup_timeout = fcgid_min(sconf->idle_scan_interval,
                                 g_wakeup_timeout);
    if (g_wakeup_timeout == 0)
        g_wakeup_timeout = 1;   /* Make it reasonable */

    rv = apr_stat(&finfo, sconf->sockname_prefix, APR_FINFO_USER,
                  configpool);
    if (rv != APR_SUCCESS) {
        /* Make dir for unix domain socket */
        if ((rv = apr_dir_make_recursive(sconf->sockname_prefix,
                                         APR_UREAD | APR_UWRITE |
                                         APR_UEXECUTE,
                                         configpool)) != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_ERR, rv, main_server,
                         "mod_fcgid: Can't create unix socket dir %s",
                         sconf->sockname_prefix);
            exit(1);
        }

        /* Child processes need to be able to create sockets in the unix
         * socket dir.  Change the ownership to the child user only if
         * running as root and we just successfully created the directory
         * (avoiding any concerns about changing the target of a link
         * created by another user).
         *
         * If the directory already existed and was owned by a different user,
         * FastCGI requests will fail at steady state, and manual intervention
         * will be required.
         */

        if (!geteuid()) {
            if (chown(sconf->sockname_prefix,
                      ap_unixd_config.user_id, -1) < 0) {
                ap_log_error(APLOG_MARK, APLOG_ERR, errno, main_server,
                             "mod_fcgid: Can't set ownership of unix socket dir %s",
                             sconf->sockname_prefix);
                exit(1);
            }
        }
    }

    /* Create pipes to communicate between process manager and apache */
    if ((rv = apr_file_pipe_create(&g_pm_read_pipe, &g_ap_write_pipe,
                                   configpool)) != APR_SUCCESS
        || (rv = apr_file_pipe_create(&g_ap_read_pipe, &g_pm_write_pipe,
                                      configpool))) {
        ap_log_error(APLOG_MARK, APLOG_ERR, rv, main_server,
                     "mod_fcgid: Can't create pipe between PM and stub");
        return rv;
    }

    /* Create mutex for pipe reading and writing */
    rv = fcgid_mutex_create(&g_pipelock, &g_pipelock_name,
                            g_pipelock_mutex_type,
                            main_server->process->pconf, main_server);
    if (rv != APR_SUCCESS) {
        exit(1);
    }

    /* Create process manager process */
    return create_process_manager(main_server, configpool);
}
Пример #15
0
	char* cc_initGlobals(pool* p,cc_globals* globals){
		if(globals->logsDir!=NULL){
			apr_dir_make_recursive(globals->logsDir,APR_OS_DEFAULT,p);
		}
		return NULL;
	}
Пример #16
0
int Command_fetch(apr_pool_t *p, const char *url, int fetch_only) {
    int rc = 0;
    const char *depends_file = NULL;

    // create the uri as an apr type
    // see https://apr.apache.org/docs/apr-util/0.9/structapr__uri__t.html
    // all you need to know for this program is that:
    //   - port of 0 indicates a default / a port-less url
    //   - path is the url as a string
    //   - scheme is the protocol (e.g. http, ftp, etc). I *think* this allows
    //     us to give plain old file paths if we want to, and then scheme would
    //     be null. The code seems to suggest it, anyway.
    apr_uri_t info = { .port = 0 };
    apr_status_t rv = apr_uri_parse(p, url, &info);
    check(rv = APR_SUCCESS, "Failed to parse URL: %s", url);

    // apr_fnmatch is apr's filename expression matcher. It follows roughly
    // the same rules as filename expansion in bash. The last entry can be
    // used to set flags that modify the pattern matching. 0 leads to defaults.
    //    -> It returns either APR_SUCCESS or APR_FNM_NOMATCH.
    if (apr_fnmatch(GIT_PAT, info.path, 0) == APR_SUCCESS) {
        rc = Shell_exec(GIT_SH, "URL", url, NULL);
        check(rc == 0, "git failed.");
    } else if (apr_fnmatch(DEPEND_PAT, info.path, 0) == APR_SUCCESS) {
        // we want to call Command_depends after downloading.
        check (!fetch_only, "No point in fetching a DEPENDS file");
        // download to depends_file, unless url is a local path.
        if (info.scheme) {
            depends_file = DEPENDS_PATH;
            rc = Shell_exec(CURL_SH, "URL", url, "TARGET", depends_file, NULL);
            check(rc == 0, "Curl failed.");
        } else {
            depends_file = info.path;
        }
        // recursively process the devpkg list
        log_info("Building according to DEPENDS: %s", url);
        rv = Command_depends(p, depends_file);
        check(rv == 0, "Failed to process the DEPENDS: %s", url);
        // return 0 because we don't actually install anything in *this*
        // command .. although we may have in Command_depends. A return code
        // of 1 means that we still need to build/install, which is not the
        // case here.
        return 0;
    } else if (apr_fnmatch(TAR_GZ_PAT, info.path, 0) == APR_SUCCESS) {
        // download if needed
        if (info.scheme) {
            rc = Shell_exec(CURL_SH, "URL", url, "TARGET", TAR_GZ_SRC, NULL);
            check(rc == 0, "Failed to curl source %s", url);
        }
        // build. See db.c for a discussion of the apr call.
        rv = apr_dir_make_recursive(
                BUILD_DIR, APR_UREAD | APR_UWRITE | APR_UEXECUTE, p
        );
        check(rc == APR_SUCCESS, "Failed to make directory %s", BUILD_DIR);
        rc = Shell_exec(TAR_SH, "FILE", TAR_GZ_SRC, NULL);
        check(rc == 0, "Failed to untar %s", TAR_GZ_SRC);
    } else if (apr_fnmatch(TAR_BZ2_PAT, info.path, 0) == APR_SUCCESS) {
        /* (note: this is copy-paste code - C kinda encourages this sometimes)
         * Zed has a small bug in this code: he redefines rc as apr_status_t
         * and then uses it for the output of Shell_exec. It works, but oops. I
         * fixed it by using copy-pasted code from the preceding block. */
        // download if needed
        if (info.scheme) {
            rc = Shell_exec(CURL_SH, "URL", url, "TARGET", TAR_BZ2_SRC, NULL);
            check(rc == 0, "Failed to curl source %s", url);
        }
        // build. See db.c for a discussion of the apr call.
        rv = apr_dir_make_recursive(
                BUILD_DIR, APR_UREAD | APR_UWRITE | APR_UEXECUTE, p
        );
        check(rc == APR_SUCCESS, "Failed to make directory %s", BUILD_DIR);
        rc = Shell_exec(TAR_SH, "FILE", TAR_BZ2_SRC, NULL);
        check(rc == 0, "Failed to untar %s", TAR_BZ2_SRC);
    } else {
        sentinel("Dont know how to handle this type of url: %s", url);
    }

    return 1; // indicates an install was actually run... the only
              // non-error case where we get a different code is DEPEND.
error:
    return -1;
}

int Command_build(
        apr_pool_t *p, const char *url, const char *configure_opts,
        const char *make_opts, const char *install_opts
) {
    int rc = 0;
    // check that build dir exists
    check(access(BUILD_DIR, X_OK | R_OK | W_OK) == 0,
          "Build directory doesn't exist: %s", BUILD_DIR);
    // if there's a config script, run it.
    if (access(CONFIG_SCRIPT, X_OK) == 0) {
        log_info("Has config script, running it.");
        rc = Shell_exec(CONFIGURE_SH, "OPTS", configure_opts, NULL);
        check(rc == 0, "Failed to configure.");
    }
    // make
    rc = Shell_exec(MAKE_SH, "OPTS", make_opts, NULL);
    check(rc == 0, "Failed to build.");
    // install. Note that if you pass install options, they have to
    // include the work "install", since we only add it if there aren't any lol
    rc = Shell_exec(
            INSTALL_SH, "TARGET", install_opts? install_opts : "install",
            NULL
    );
    check(rc == 0, "Failed to install.");
    // clean up
    rc = Shell_exec(CLEANUP_SH, NULL);
    check(rc == 0, "Failed to cleanup after build.");
    // update the db
    rc = DB_update(url);
    check(rc == 0, "Failed to add this package to the database.");

    return 0;
error:
    return -1;
}
Пример #17
0
/**
 * Try obtain a cache wide lock on the given cache key.
 *
 * If we return APR_SUCCESS, we obtained the lock, and we are clear to
 * proceed to the backend. If we return APR_EEXIST, then the lock is
 * already locked, someone else has gone to refresh the backend data
 * already, so we must return stale data with a warning in the mean
 * time. If we return anything else, then something has gone pear
 * shaped, and we allow the request through to the backend regardless.
 *
 * This lock is created from the request pool, meaning that should
 * something go wrong and the lock isn't deleted on return of the
 * request headers from the backend for whatever reason, at worst the
 * lock will be cleaned up when the request dies or finishes.
 *
 * If something goes truly bananas and the lock isn't deleted when the
 * request dies, the lock will be trashed when its max-age is reached,
 * or when a request arrives containing a Cache-Control: no-cache. At
 * no point is it possible for this lock to permanently deny access to
 * the backend.
 */
apr_status_t cache_try_lock(cache_server_conf *conf, cache_request_rec *cache,
        request_rec *r)
{
    apr_status_t status;
    const char *lockname;
    const char *path;
    char dir[5];
    apr_time_t now = apr_time_now();
    apr_finfo_t finfo;
    apr_file_t *lockfile;
    void *dummy;

    finfo.mtime = 0;

    if (!conf || !conf->lock || !conf->lockpath) {
        /* no locks configured, leave */
        return APR_SUCCESS;
    }

    /* lock already obtained earlier? if so, success */
    apr_pool_userdata_get(&dummy, CACHE_LOCKFILE_KEY, r->pool);
    if (dummy) {
        return APR_SUCCESS;
    }

    /* create the key if it doesn't exist */
    if (!cache->key) {
        cache_generate_key(r, r->pool, &cache->key);
    }

    /* create a hashed filename from the key, and save it for later */
    lockname = ap_cache_generate_name(r->pool, 0, 0, cache->key);

    /* lock files represent discrete just-went-stale URLs "in flight", so
     * we support a simple two level directory structure, more is overkill.
     */
    dir[0] = '/';
    dir[1] = lockname[0];
    dir[2] = '/';
    dir[3] = lockname[1];
    dir[4] = 0;

    /* make the directories */
    path = apr_pstrcat(r->pool, conf->lockpath, dir, NULL);
    if (APR_SUCCESS != (status = apr_dir_make_recursive(path,
            APR_UREAD|APR_UWRITE|APR_UEXECUTE, r->pool))) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(00778)
                "Could not create a cache lock directory: %s",
                path);
        return status;
    }
    lockname = apr_pstrcat(r->pool, path, "/", lockname, NULL);
    apr_pool_userdata_set(lockname, CACHE_LOCKNAME_KEY, NULL, r->pool);

    /* is an existing lock file too old? */
    status = apr_stat(&finfo, lockname,
                APR_FINFO_MTIME | APR_FINFO_NLINK, r->pool);
    if (!(APR_STATUS_IS_ENOENT(status)) && APR_SUCCESS != status) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, APR_EEXIST, r, APLOGNO(00779)
                "Could not stat a cache lock file: %s",
                lockname);
        return status;
    }
    if ((status == APR_SUCCESS) && (((now - finfo.mtime) > conf->lockmaxage)
                                  || (now < finfo.mtime))) {
        ap_log_rerror(APLOG_MARK, APLOG_INFO, status, r, APLOGNO(00780)
                "Cache lock file for '%s' too old, removing: %s",
                r->uri, lockname);
        apr_file_remove(lockname, r->pool);
    }

    /* try obtain a lock on the file */
    if (APR_SUCCESS == (status = apr_file_open(&lockfile, lockname,
            APR_WRITE | APR_CREATE | APR_EXCL | APR_DELONCLOSE,
            APR_UREAD | APR_UWRITE, r->pool))) {
        apr_pool_userdata_set(lockfile, CACHE_LOCKFILE_KEY, NULL, r->pool);
    }
    return status;

}