char* full_path;
char* filename;
char* path;
+ long id;
};
G_LOCK_DEFINE (LOCK_FIL);
G_LOCK_DEFINE (LOCK_OTH);
+GCond cond_pri;
+GCond cond_fil;
+GCond cond_oth;
+
void
dumper_thread(gpointer data, gpointer user_data)
}
+int
+fill_pool(GThreadPool *pool,
+ gchar *in_dir,
+ struct CmdOptions *cmd_options,
+ GSList **current_pkglist,
+ FILE *output_pkg_list)
+{
+ int package_count = 0;
+
+ if (!(cmd_options->include_pkgs)) {
+ // --pkglist (or --includepkg) is not supplied -> do dir walk
+
+ g_message("Directory walk started");
+
+ size_t in_dir_len = strlen(in_dir);
+ GStringChunk *sub_dirs_chunk = g_string_chunk_new(1024);
+ GQueue *sub_dirs = g_queue_new();
+ gchar *input_dir_stripped;
+
+ input_dir_stripped = g_string_chunk_insert_len(sub_dirs_chunk,
+ in_dir,
+ in_dir_len-1);
+ g_queue_push_head(sub_dirs, input_dir_stripped);
+
+ char *dirname;
+ while ((dirname = g_queue_pop_head(sub_dirs))) {
+ // Open dir
+ GDir *dirp;
+ dirp = g_dir_open (dirname, 0, NULL);
+ if (!dirp) {
+ g_warning("Cannot open directory: %s", dirname);
+ continue;
+ }
+
+ const gchar *filename;
+ while ((filename = g_dir_read_name(dirp))) {
+
+ gchar *full_path = g_strconcat(dirname, "/", filename, NULL);
+
+ // Non .rpm files
+ if (!g_str_has_suffix (filename, ".rpm")) {
+ if (!g_file_test(full_path, G_FILE_TEST_IS_REGULAR) &&
+ g_file_test(full_path, G_FILE_TEST_IS_DIR))
+ {
+ // Directory
+ gchar *sub_dir_in_chunk;
+ sub_dir_in_chunk = g_string_chunk_insert(sub_dirs_chunk,
+ full_path);
+ g_queue_push_head(sub_dirs, sub_dir_in_chunk);
+ g_debug("Dir to scan: %s", sub_dir_in_chunk);
+ }
+ g_free(full_path);
+ continue;
+ }
+
+ // Skip symbolic links if --skip-symlinks arg is used
+ if (cmd_options->skip_symlinks
+ && g_file_test(full_path, G_FILE_TEST_IS_SYMLINK))
+ {
+ g_debug("Skipped symlink: %s", full_path);
+ g_free(full_path);
+ continue;
+ }
+
+ // Check filename against exclude glob masks
+ const gchar *repo_relative_path = filename;
+ if (in_dir_len < strlen(full_path))
+ // This probably should be always true
+ repo_relative_path = full_path + in_dir_len;
+
+ if (allowed_file(repo_relative_path, cmd_options)) {
+ // FINALLY! Add file into pool
+ g_debug("Adding pkg: %s", full_path);
+ struct PoolTask *task = g_malloc(sizeof(struct PoolTask));
+ task->full_path = full_path;
+ task->filename = g_strdup(filename);
+ task->path = g_strdup(dirname);
+ if (output_pkg_list)
+ fprintf(output_pkg_list, "%s\n", repo_relative_path);
+ *current_pkglist = g_slist_prepend(*current_pkglist, task->filename);
+ // TODO: One common path for all tasks with the same path?
+ g_thread_pool_push(pool, task, NULL);
+ package_count++;
+ } else
+ g_free(full_path);
+ }
+
+ // Cleanup
+ g_dir_close (dirp);
+ }
+
+ g_string_chunk_free (sub_dirs_chunk);
+ g_queue_free(sub_dirs);
+ } else {
+ // pkglist is supplied - use only files in pkglist
+
+ g_debug("Skipping dir walk - using pkglist");
+
+ GSList *element = cmd_options->include_pkgs;
+ for (; element; element=g_slist_next(element)) {
+ gchar *relative_path = (gchar *) element->data;
+ // ^^^ path from pkglist e.g. packages/i386/foobar.rpm
+ gchar *filename; // foobar.rpm
+
+ // Get index of last '/'
+ int rel_path_len = strlen(relative_path);
+ int x = rel_path_len;
+ for (; x > 0; x--)
+ if (relative_path[x] == '/')
+ break;
+
+ if (!x) {
+ // There was no '/' in path
+ filename = relative_path;
+ } else {
+ filename = relative_path + x + 1;
+ }
+
+ if (allowed_file(filename, cmd_options)) {
+ // Check filename against exclude glob masks
+ gchar *full_path = g_strconcat(in_dir, relative_path, NULL);
+ // ^^^ /path/to/in_repo/packages/i386/foobar.rpm
+ g_debug("Adding pkg: %s", full_path);
+ struct PoolTask *task = g_malloc(sizeof(struct PoolTask));
+ task->full_path = full_path;
+ task->filename = g_strdup(filename); // foobar.rpm
+ task->path = strndup(relative_path, x); // packages/i386/
+ if (output_pkg_list)
+ fprintf(output_pkg_list, "%s\n", relative_path);
+ *current_pkglist = g_slist_prepend(*current_pkglist, task->filename);
+ g_thread_pool_push(pool, task, NULL);
+ package_count++;
+ }
+ }
+ }
+
+ return package_count;
+}
+
int
main(int argc, char **argv)
NULL);
g_debug("Thread pool ready");
-
- // Recursive walk
-
+ int package_count;
GSList *current_pkglist = NULL;
/* ^^^ List with basenames of files which will be processed */
- int package_count = 0;
- if (!(cmd_options->include_pkgs)) {
- // --pkglist (or --includepkg) is not supplied -> do dir walk
- g_message("Directory walk started");
-
- size_t in_dir_len = strlen(in_dir);
- GStringChunk *sub_dirs_chunk = g_string_chunk_new(1024);
- GQueue *sub_dirs = g_queue_new();
- gchar *input_dir_stripped;
-
- input_dir_stripped = g_string_chunk_insert_len(sub_dirs_chunk,
- in_dir,
- in_dir_len-1);
- g_queue_push_head(sub_dirs, input_dir_stripped);
-
- char *dirname;
- while ((dirname = g_queue_pop_head(sub_dirs))) {
- // Open dir
- GDir *dirp;
- dirp = g_dir_open (dirname, 0, NULL);
- if (!dirp) {
- g_warning("Cannot open directory: %s", dirname);
- continue;
- }
-
- const gchar *filename;
- while ((filename = g_dir_read_name(dirp))) {
+ // Thread pool - Fill with tasks
- gchar *full_path = g_strconcat(dirname, "/", filename, NULL);
-
- // Non .rpm files
- if (!g_str_has_suffix (filename, ".rpm")) {
- if (!g_file_test(full_path, G_FILE_TEST_IS_REGULAR) &&
- g_file_test(full_path, G_FILE_TEST_IS_DIR))
- {
- // Directory
- gchar *sub_dir_in_chunk;
- sub_dir_in_chunk = g_string_chunk_insert(sub_dirs_chunk,
- full_path);
- g_queue_push_head(sub_dirs, sub_dir_in_chunk);
- g_debug("Dir to scan: %s", sub_dir_in_chunk);
- }
- g_free(full_path);
- continue;
- }
-
- // Skip symbolic links if --skip-symlinks arg is used
- if (cmd_options->skip_symlinks
- && g_file_test(full_path, G_FILE_TEST_IS_SYMLINK))
- {
- g_debug("Skipped symlink: %s", full_path);
- g_free(full_path);
- continue;
- }
-
- // Check filename against exclude glob masks
- const gchar *repo_relative_path = filename;
- if (in_dir_len < strlen(full_path))
- // This probably should be always true
- repo_relative_path = full_path + in_dir_len;
-
- if (allowed_file(repo_relative_path, cmd_options)) {
- // FINALLY! Add file into pool
- g_debug("Adding pkg: %s", full_path);
- struct PoolTask *task = g_malloc(sizeof(struct PoolTask));
- task->full_path = full_path;
- task->filename = g_strdup(filename);
- task->path = g_strdup(dirname);
- if (output_pkg_list)
- fprintf(output_pkg_list, "%s\n", repo_relative_path);
- current_pkglist = g_slist_prepend(current_pkglist, task->filename);
- // TODO: One common path for all tasks with the same path?
- g_thread_pool_push(pool, task, NULL);
- package_count++;
- } else
- g_free(full_path);
- }
-
- // Cleanup
- g_dir_close (dirp);
- }
-
- g_string_chunk_free (sub_dirs_chunk);
- g_queue_free(sub_dirs);
- } else {
- // pkglist is supplied - use only files in pkglist
-
- g_debug("Skipping dir walk - using pkglist");
-
- GSList *element = cmd_options->include_pkgs;
- for (; element; element=g_slist_next(element)) {
- gchar *relative_path = (gchar *) element->data;
- // ^^^ path from pkglist e.g. packages/i386/foobar.rpm
- gchar *filename; // foobar.rpm
-
- // Get index of last '/'
- int rel_path_len = strlen(relative_path);
- int x = rel_path_len;
- for (; x > 0; x--)
- if (relative_path[x] == '/')
- break;
-
- if (!x) {
- // There was no '/' in path
- filename = relative_path;
- } else {
- filename = relative_path + x + 1;
- }
-
- if (allowed_file(filename, cmd_options)) {
- // Check filename against exclude glob masks
- gchar *full_path = g_strconcat(in_dir, relative_path, NULL);
- // ^^^ /path/to/in_repo/packages/i386/foobar.rpm
- g_debug("Adding pkg: %s", full_path);
- struct PoolTask *task = g_malloc(sizeof(struct PoolTask));
- task->full_path = full_path;
- task->filename = g_strdup(filename); // foobar.rpm
- task->path = strndup(relative_path, x); // packages/i386/
- if (output_pkg_list)
- fprintf(output_pkg_list, "%s\n", relative_path);
- current_pkglist = g_slist_prepend(current_pkglist, task->filename);
- g_thread_pool_push(pool, task, NULL);
- package_count++;
- }
- }
- }
+ package_count = fill_pool(pool,
+ in_dir,
+ cmd_options,
+ ¤t_pkglist,
+ output_pkg_list);
g_debug("Package count: %d", package_count);
g_message("Directory walk done - %d packages", package_count);