From fa78a9f21ff4fd85fb568232c9bee957b9c83497 Mon Sep 17 00:00:00 2001 From: Sergey Poznyakoff Date: Sun, 3 Jan 2010 19:40:33 +0200 Subject: Improve memory management and optimize function signatures. * src/wydawca.h (file_triplet): New members: relative_dir, obstk. (virt_tab): Remove spool and reldir from argument lists. (triplet_strdup): New prototype. (move_file, archive_file, symlink_file) (rmsymlink_file, dir_move_file, dir_archive_file) (dir_symlink_file, dir_rmsymlink_file) (null_move_file, null_archive_file) (null_symlink_file, null_rmsymlink_file): Remove spool and reldir from argument lists. * src/directive.c (run_check_script): Use trp->obstk to store the program output. (process_directives): Update calls to vtab interfaces. * src/diskio.c (dir_move_file) (dir_archive_file, dir_symlink_file) (dir_rmsymlink_file): Remove spool and reldir arguments. Use the corresponding members of the struct file_triplet. * src/null.c (null_move_file, null_archive_file) (null_symlink_file, null_rmsymlink_file): Likewise. * src/vtab.c (move_file, archive_file) (symlink_file, rmsymlink_file): Likewise. * src/triplet.c (hash_triplet_free): Free obstack and uploader_list. (triplet_strdup): New function. (register_file): Initialize trp->obstck. (fill_project_name): Fill relative_dir as well. (verify_directive_file): Use triplet_strdup to keep string values. --- src/directive.c | 34 +++++++++++--------------------- src/diskio.c | 61 ++++++++++++++++++++++++++++++--------------------------- src/null.c | 22 ++++++++++----------- src/triplet.c | 26 ++++++++++++++++++++---- src/verify.c | 38 ++++++++++++++++++++--------------- src/vtab.c | 29 ++++++++++++--------------- src/wydawca.h | 56 +++++++++++++++++----------------------------------- 7 files changed, 127 insertions(+), 139 deletions(-) diff --git a/src/directive.c b/src/directive.c index 93830b1..34e5feb 100644 --- a/src/directive.c +++ b/src/directive.c @@ -404,7 +404,6 @@ run_check_script (const char *script, struct file_triplet *trp, FILE *fp; char *buf; size_t size, total; - struct obstack stk; if (debug_level > 1) logmsg (LOG_DEBUG, _("prep script: %20.20s%s"), @@ -492,7 +491,6 @@ run_check_script (const char *script, struct file_triplet *trp, fp = fdopen (p[0], "r"); buf = NULL; size = total = 0; - obstack_init (&stk); if (debug_level > 2) logmsg (LOG_DEBUG, _("reading script output...")); while (getline (&buf, &size, fp) > 0) @@ -500,10 +498,10 @@ run_check_script (const char *script, struct file_triplet *trp, size_t len = strlen (buf); if (debug_level > 2) logmsg (LOG_DEBUG, _("read: %s"), buf); - obstack_grow (&stk, buf, len); + obstack_grow (&trp->obstk, buf, len); total += size; } - obstack_1grow (&stk, 0); + obstack_1grow (&trp->obstk, 0); if (debug_level > 2) logmsg (LOG_DEBUG, _("bytes read: %lu"), (unsigned long)total); @@ -513,8 +511,7 @@ run_check_script (const char *script, struct file_triplet *trp, signal (SIGCHLD, oldsig); if (total) - trp->check_diag = xstrdup (obstack_finish (&stk)); - obstack_free (&stk, NULL); + trp->check_diag = obstack_finish (&trp->obstk); trp->check_result = status; if (WIFEXITED (status)) @@ -593,7 +590,6 @@ process_directives (struct file_triplet *trp) { int rc, n; const char *key, *val; - char *relative_dir; const struct spool *spool; ASGN_SPOOL (spool, trp, return 1); @@ -616,14 +612,7 @@ process_directives (struct file_triplet *trp) break; case directory_dir: - /* FIXME: Alloc it in triplet */ - relative_dir = safe_file_name_alloc (val); - if (!relative_dir || relative_dir[0] == '/') - { - logmsg (LOG_ERR, _("%s: invalid directory: %s"), - trp->file[file_directive].name, val); - return 1; - } + /* already processed (see fill_project_name in verify.c */ break; case filename_dir: @@ -632,8 +621,8 @@ process_directives (struct file_triplet *trp) { if (external_check (trp)) return 1; - if (move_file (trp, spool, file_dist, relative_dir) - || move_file (trp, spool, file_signature, relative_dir)) + if (move_file (trp, file_dist) + || move_file (trp, file_signature)) return 1; } else @@ -645,11 +634,12 @@ process_directives (struct file_triplet *trp) break; case version_dir: - /* Already processed */ + /* Already processed. See directive_version_in_range_p, + called by verify_directive_format */ break; case archive_dir: - if (archive_file (trp, spool, relative_dir, val)) + if (archive_file (trp, val)) return 1; break; @@ -673,8 +663,7 @@ process_directives (struct file_triplet *trp) key, val); } else - rc = symlink_file (trp, spool, relative_dir, - ws.ws_wordv[0], ws.ws_wordv[1]); + rc = symlink_file (trp, ws.ws_wordv[0], ws.ws_wordv[1]); wordsplit_free (&ws); if (rc) @@ -683,7 +672,7 @@ process_directives (struct file_triplet *trp) break; case rmsymlink_dir: - if (rmsymlink_file (trp, spool, relative_dir, val)) + if (rmsymlink_file (trp, val)) return 1; } } @@ -694,7 +683,6 @@ process_directives (struct file_triplet *trp) trp->file[file_directive].name, strerror (errno)); } - free (relative_dir); UPDATE_STATS (STAT_TRIPLET_SUCCESS); report_finish (); timer_stop ("triplet"); diff --git a/src/diskio.c b/src/diskio.c index 1760a88..46526d0 100644 --- a/src/diskio.c +++ b/src/diskio.c @@ -108,7 +108,7 @@ create_hierarchy (char *dir, size_t baselen) } /* Create a directory BASE/NAME (with eventual intermediate directories in - NAME). Use UID and GID as owner ids. + NAME). Do nothing if dry_run_mode is set. */ char * create_directory (const char *base, const char *name) @@ -372,19 +372,27 @@ do_archive_file (const char *dst_file, const char *dst_dir, const char *file, const struct archive_descr *archive, const char *reldir) { + int rc = 0; + switch (archive->type) { case archive_none: break; case archive_directory: - return backup_file (dst_file, dst_dir, file, archive, reldir); + if (backup_file (dst_file, dst_dir, file, archive, reldir)) + return 1; + UPDATE_STATS (STAT_ARCHIVES); + break; case archive_tar: if (tar_append_file (archive->name, dst_file)) return 1; + UPDATE_STATS (STAT_ARCHIVES); + break; } - if (!dry_run_mode && unlink (dst_file)) + + if (!dry_run_mode && unlink (dst_file) && errno != ENOENT) { logmsg (LOG_ERR, _("canot unlink file `%s': %s"), dst_file, strerror (errno)); @@ -394,17 +402,17 @@ do_archive_file (const char *dst_file, const char *dst_dir, const char *file, } /* Move the part FILE_ID of the triplet TRP between the directories in - DPAIR. RELDIR gives relative directory (i.e. the directory part of - the file name) for backup purposes. + TRP->SPOOL. TRP->RELATIVE_DIR gives relative directory (i.e. the + directory part of the file name) for backup purposes. Do nothing if dry_run_mode is set. */ int -dir_move_file (struct file_triplet *trp, const struct spool *spool, - enum file_type file_id, const char *reldir) +dir_move_file (struct file_triplet *trp, enum file_type file_id) { char *dst_file; int rc = 0; - char *dst_dir = create_directory (spool->dest_dir, reldir); + const struct spool *spool = trp->spool; + char *dst_dir = create_directory (spool->dest_dir, trp->relative_dir); if (!dst_dir) return 1; @@ -416,7 +424,7 @@ dir_move_file (struct file_triplet *trp, const struct spool *spool, if (access (dst_file, F_OK) == 0) rc = do_archive_file (dst_file, dst_dir, trp->file[file_id].name, - &spool->archive, reldir); + &spool->archive, trp->relative_dir); if (!dry_run_mode && rc == 0) rc = do_move_file (trp->file[file_id].name, dst_file); @@ -433,13 +441,13 @@ dir_move_file (struct file_triplet *trp, const struct spool *spool, Do nothing if dry_run_mode is set. */ int -archive_single_file (struct file_triplet *trp, const struct spool *spool, - const char *file_name, const char *reldir, +archive_single_file (struct file_triplet *trp, const char *file_name, int noentok) { char *dst_file; int rc = 0; - char *dst_dir = create_directory (spool->dest_dir, reldir); + const struct spool *spool = trp->spool; + char *dst_dir = create_directory (spool->dest_dir, trp->relative_dir); if (!dst_dir) return 1; @@ -459,9 +467,7 @@ archive_single_file (struct file_triplet *trp, const struct spool *spool, if (debug_level) logmsg (LOG_DEBUG, _("archiving file `%s'"), dst_file); rc = do_archive_file (dst_file, dst_dir, file_name, &spool->archive, - reldir); - if (rc == 0) - UPDATE_STATS (STAT_ARCHIVES); + trp->relative_dir); } else if (errno == ENOENT) { @@ -502,33 +508,32 @@ make_signame (const char *file_name) Do nothing if dry_run_mode is set. */ int -dir_archive_file (struct file_triplet *trp, const struct spool *spool, - const char *reldir, const char *file_name) +dir_archive_file (struct file_triplet *trp, const char *file_name) { int rc; char *signame; - rc = archive_single_file (trp, spool, file_name, reldir, 0); + rc = archive_single_file (trp, file_name, 0); if (rc == 0 && archive_signatures && (signame = make_signame (file_name))) { - rc = archive_single_file (trp, spool, signame, reldir, 1); + rc = archive_single_file (trp, signame, 1); free (signame); } return rc; } /* Create a symbolic link from WANTED_SRC to WANTED_DST in the subdirectory - RELDIR of DPAIR->dest_dir. Get ownership information from TRP. + TRP->relative_dir of SPOOL->dest_dir. Do nothing if dry_run_mode is set. */ int -dir_symlink_file (struct file_triplet *trp, const struct spool *spool, - const char *reldir, +dir_symlink_file (struct file_triplet *trp, const char *wanted_src, const char *wanted_dst) { int rc = 0; struct saved_cwd cwd; - char *dst_dir = create_directory (spool->dest_dir, reldir); + const struct spool *spool = trp->spool; + char *dst_dir = create_directory (spool->dest_dir, trp->relative_dir); char *src, *dst; if (!dst_dir) @@ -674,19 +679,17 @@ do_rmsymlink_file (const char *dst_file, int noentok) return 0; } -/* Remove the symbolic link DPAIR->dest_dir/RELDIR/FILE_NAME - - Get ownership information from TRP. +/* Remove the symbolic link TRP->spool->dest_dir/TRP->relative_dir/FILE_NAME Do nothing if dry_run_mode is set. */ int -dir_rmsymlink_file (struct file_triplet *trp, const struct spool *spool, - const char *reldir, const char *file_name) +dir_rmsymlink_file (struct file_triplet *trp, const char *file_name) { char *dst_file; int rc = 0; char *signame; - char *dst_dir = create_directory (spool->dest_dir, reldir); + const struct spool *spool = trp->spool; + char *dst_dir = create_directory (spool->dest_dir, trp->relative_dir); if (!dst_dir) return 1; diff --git a/src/null.c b/src/null.c index 4a443e3..c37ade3 100644 --- a/src/null.c +++ b/src/null.c @@ -17,13 +17,13 @@ #include "wydawca.h" int -null_move_file (struct file_triplet *trp, const struct spool *spool, - enum file_type file_id, const char *reldir) +null_move_file (struct file_triplet *trp, enum file_type file_id) { + const struct spool *spool = trp->spool; const char *file_name = trp->file[file_id].name; if (debug_level) logmsg (LOG_DEBUG, _("spool %s: installing file `%s/%s'"), - spool->tag, reldir, file_name); + spool->tag, trp->relative_dir, file_name); UPDATE_STATS (STAT_UPLOADS); if (!dry_run_mode && unlink (file_name)) { @@ -35,34 +35,32 @@ null_move_file (struct file_triplet *trp, const struct spool *spool, } int -null_archive_file (struct file_triplet *trp, const struct spool *spool, - const char *file_name, const char *reldir) +null_archive_file (struct file_triplet *trp, const char *file_name) { if (debug_level) - logmsg (LOG_DEBUG, _("spool %s: archiving `%s'"), spool->tag, file_name); + logmsg (LOG_DEBUG, _("spool %s: archiving `%s'"), + trp->spool->tag, file_name); UPDATE_STATS (STAT_ARCHIVES); return 0; } int -null_symlink_file (struct file_triplet *trp, const struct spool *spool, - const char *reldir, +null_symlink_file (struct file_triplet *trp, const char *wanted_src, const char *wanted_dst) { if (debug_level) logmsg (LOG_DEBUG, _("spool %s: symlinking `%s' to `%s'"), - spool->tag, wanted_src, wanted_dst); + trp->spool->tag, wanted_src, wanted_dst); UPDATE_STATS (STAT_SYMLINKS); return 0; } int -null_rmsymlink_file (struct file_triplet *trp, const struct spool *spool, - const char *reldir, const char *file_name) +null_rmsymlink_file (struct file_triplet *trp, const char *file_name) { if (debug_level) logmsg (LOG_DEBUG, _("spool %s: removing symlink `%s/%s'"), - spool->tag, reldir, file_name); + trp->spool->tag, trp->relative_dir, file_name); UPDATE_STATS (STAT_RMSYMLINKS); return 0; } diff --git a/src/triplet.c b/src/triplet.c index efe4a0b..ea57a08 100644 --- a/src/triplet.c +++ b/src/triplet.c @@ -42,7 +42,8 @@ hash_triplet_free (void *data) { int i; struct file_triplet *tp = data; - + struct uploader_info *up; + for (i = 0; i < FILE_TYPE_COUNT; i++) { if (tp->file[i].name) @@ -52,12 +53,27 @@ hash_triplet_free (void *data) free (tp->directive); free (tp->blurb); free (tp->tmp); - free (tp->check_diag); - /* FIXME: free uploader list */ + obstack_free (&tp->obstk, NULL); + + /* Free uploader list */ + for (up = tp->uploader_list; up; ) + { + struct uploader_info *next = up->next; + free (up); + up = next; + } free (tp); } +char * +triplet_strdup (struct file_triplet *tp, const char *str) +{ + size_t len = strlen (str); + obstack_grow (&tp->obstk, str, len + 1); + return obstack_finish (&tp->obstk); +} + /* Register a file in the triplet table */ void register_file (struct file_info *finfo, const struct spool *spool) @@ -79,7 +95,9 @@ register_file (struct file_info *finfo, const struct spool *spool) && (ret = hash_insert (triplet_table, tp)))) xalloc_die (); - if (ret != tp) + if (ret == tp) + obstack_init (&tp->obstk); + else free (tp); ret->file[finfo->type] = *finfo; } diff --git a/src/verify.c b/src/verify.c index 01c61ea..93fd28b 100644 --- a/src/verify.c +++ b/src/verify.c @@ -93,7 +93,7 @@ fill_project_name (struct file_triplet *trp) char *blurb; size_t size; FILE *fp; - char *project, *p; + char *p; const char *directory; int rc; @@ -150,23 +150,32 @@ fill_project_name (struct file_triplet *trp) trp->file[file_directive].name); return 1; } - p = strchr (directory, '/'); + + trp->relative_dir = safe_file_name (triplet_strdup (trp, directory)); + if (!trp->relative_dir || trp->relative_dir[0] == '/') + { + logmsg (LOG_ERR, _("%s: invalid directory: %s"), + trp->file[file_directive].name, directory); + return 1; + } + + p = strchr (trp->relative_dir, '/'); if (p) { - size_t len = p - directory; + size_t len = p - trp->relative_dir; if (len == 0) { logmsg (LOG_ERR, _("%s: empty `directory' directive"), trp->file[file_directive].name); return 1; } - project = xmalloc (len + 1); - memcpy (project, directory, len); - project[len] = 0; + obstack_grow (&trp->obstk, trp->relative_dir, len); + obstack_1grow (&trp->obstk, 0); + trp->project = obstack_finish (&trp->obstk); } else - project = xstrdup (directory); - trp->project = xstrdup (project); + trp->project = trp->relative_dir; + return 0; } @@ -254,16 +263,16 @@ verify_directive_file (struct file_triplet *trp) memset (&info, 0, sizeof (info)); p = dictionary_result (dict, md, i, 0); if (p) - info.name = xstrdup (p); + info.name = triplet_strdup (trp, p); p = dictionary_result (dict, md, i, 1); if (p) - info.realname = xstrdup (p); + info.realname = triplet_strdup (trp, p); p = dictionary_result (dict, md, i, 2); if (p) - info.email = xstrdup (p); + info.email = triplet_strdup (trp, p); p = dictionary_result (dict, md, i, 3); if (p) - info.gpg_key = xstrdup (p); + info.gpg_key = triplet_strdup (trp, p); if (debug_level > 3) { @@ -278,10 +287,7 @@ verify_directive_file (struct file_triplet *trp) logmsg (LOG_ERR, _("project-uploader dictionary error: malformed row %lu"), (unsigned long) i); - free (info.name); - free (info.realname); - free (info.gpg_key); - free (info.email); + /* FIXME: Memory not reclaimed */ continue; } diff --git a/src/vtab.c b/src/vtab.c index 9854660..918bab3 100644 --- a/src/vtab.c +++ b/src/vtab.c @@ -54,44 +54,39 @@ url_to_vtab (mu_url_t url, struct virt_tab *vtab) int -move_file (struct file_triplet *trp, const struct spool *spool, - enum file_type file_id, const char *reldir) +move_file (struct file_triplet *trp, enum file_type file_id) { - int rc = spool->vtab.move_file (trp, spool, file_id, reldir); - report_add ("Move %s to %s: %s", trp->file[file_id].name, reldir, + int rc = trp->spool->vtab.move_file (trp, file_id); + report_add ("Move %s to %s: %s", trp->file[file_id].name, trp->relative_dir, rc == 0 ? "OK" : "FAILED"); return rc; } int -archive_file (struct file_triplet *trp, const struct spool *spool, - const char *reldir, const char *file_name) +archive_file (struct file_triplet *trp, const char *file_name) { - int rc = spool->vtab.archive_file (trp, spool, reldir, file_name); - report_add ("Archive and remove %s/%s: %s", reldir, file_name, + int rc = trp->spool->vtab.archive_file (trp, file_name); + report_add ("Archive and remove %s/%s: %s", trp->relative_dir, file_name, rc == 0 ? "OK" : "FAILED"); return rc; } int -symlink_file (struct file_triplet *trp, const struct spool *spool, - const char *reldir, +symlink_file (struct file_triplet *trp, const char *wanted_src, const char *wanted_dst) { - int rc = spool->vtab.symlink_file (trp, spool, reldir, - wanted_src, wanted_dst); + int rc = trp->spool->vtab.symlink_file (trp, wanted_src, wanted_dst); report_add ("Symlink %s to %s in %s/: %s", wanted_src, wanted_dst, - reldir, + trp->relative_dir, rc == 0 ? "OK" : "FAILED"); return rc; } int -rmsymlink_file (struct file_triplet *trp, const struct spool *spool, - const char *reldir, const char *file_name) +rmsymlink_file (struct file_triplet *trp, const char *file_name) { - int rc = spool->vtab.rmsymlink_file (trp, spool, reldir, file_name); - report_add ("Remove symlink %s/%s: %s", reldir, file_name, + int rc = trp->spool->vtab.rmsymlink_file (trp, file_name); + report_add ("Remove symlink %s/%s: %s", trp->relative_dir, file_name, rc == 0 ? "OK" : "FAILED"); return rc; } diff --git a/src/wydawca.h b/src/wydawca.h index b44b5d7..da093c3 100644 --- a/src/wydawca.h +++ b/src/wydawca.h @@ -174,10 +174,12 @@ struct file_triplet char *name; /* Triplet base name */ struct file_info file[FILE_TYPE_COUNT]; /* Components */ const struct spool *spool; /* Owning spool */ + char *relative_dir; /* Directory relative to spool->dest_dir */ char **directive; /* Decoded directive pairs (key: value\0) */ char *blurb; /* Block of directives: directive[i] points here */ char *tmp; /* Temporary storage */ size_t tmpsize; /* Size of memory allocated in tmp */ + struct obstack obstk; /* Obstack for string allocation */ /* User data */ size_t uploader_count; struct uploader_info *uploader_list; @@ -199,23 +201,12 @@ struct file_triplet struct virt_tab { int (*test_url) (mu_url_t url, grecs_locus_t *loc); - int (*move_file) (struct file_triplet *trp, - const struct spool *spool, - enum file_type file_id, - const char *reldir); - int (*archive_file) (struct file_triplet *trp, - const struct spool *spool, - const char *reldir, - const char *file_name); + int (*move_file) (struct file_triplet *trp, enum file_type file_id); + int (*archive_file) (struct file_triplet *trp, const char *file_name); int (*symlink_file) (struct file_triplet *trp, - const struct spool *spool, - const char *reldir, const char *wanted_src, const char *wanted_dst); - int (*rmsymlink_file)(struct file_triplet *trp, - const struct spool *spool, - const char *reldir, - const char *file_name); + int (*rmsymlink_file)(struct file_triplet *trp, const char *file_name); }; /* An upload spool. This structure contains all data necessary for releasing @@ -466,6 +457,7 @@ int process_directives (struct file_triplet *trp); int enabled_spool_p (const struct spool *spool); int selected_spools (void); +char *triplet_strdup (struct file_triplet *tp, const char *str); int parse_time_interval (const char *str, time_t *pint, const char **endp); @@ -482,18 +474,14 @@ int assert_string_arg (grecs_locus_t *, enum grecs_callback_command, int url_to_vtab (mu_url_t url, struct virt_tab *vtab); int -move_file (struct file_triplet *trp, const struct spool *spool, - enum file_type file_id, const char *reldir); +move_file (struct file_triplet *trp, enum file_type file_id); int -archive_file (struct file_triplet *trp, const struct spool *spool, - const char *reldir, const char *file_name); +archive_file (struct file_triplet *trp, const char *file_name); int -symlink_file (struct file_triplet *trp, const struct spool *spool, - const char *reldir, +symlink_file (struct file_triplet *trp, const char *wanted_src, const char *wanted_dst); int -rmsymlink_file (struct file_triplet *trp, const struct spool *spool, - const char *reldir, const char *file_name); +rmsymlink_file (struct file_triplet *trp, const char *file_name); /* diskio.c */ @@ -501,26 +489,18 @@ char *concat_dir (const char *base, const char *name, size_t *pbaselen); int copy_file (const char *file, const char *dst_file); int dir_test_url (mu_url_t url, grecs_locus_t *locus); -int dir_move_file (struct file_triplet *trp, const struct spool *spool, - enum file_type file_id, const char *reldir); -int dir_archive_file (struct file_triplet *trp, const struct spool *spool, - const char *file_name, const char *reldir); -int dir_symlink_file (struct file_triplet *trp, const struct spool *spool, - const char *reldir, +int dir_move_file (struct file_triplet *trp, enum file_type file_id); +int dir_archive_file (struct file_triplet *trp, const char *reldir); +int dir_symlink_file (struct file_triplet *trp, const char *wanted_src, const char *wanted_dst); -int dir_rmsymlink_file (struct file_triplet *trp, const struct spool *spool, - const char *reldir, const char *file_name); +int dir_rmsymlink_file (struct file_triplet *trp, const char *file_name); /* null.c */ -int null_move_file (struct file_triplet *trp, const struct spool *spool, - enum file_type file_id, const char *reldir); -int null_archive_file (struct file_triplet *trp, const struct spool *spool, - const char *file_name, const char *reldir); -int null_symlink_file (struct file_triplet *trp, const struct spool *spool, - const char *reldir, +int null_move_file (struct file_triplet *trp, enum file_type file_id); +int null_archive_file (struct file_triplet *trp, const char *file_name); +int null_symlink_file (struct file_triplet *trp, const char *wanted_src, const char *wanted_dst); -int null_rmsymlink_file (struct file_triplet *trp, const struct spool *spool, - const char *reldir, const char *file_name); +int null_rmsymlink_file (struct file_triplet *trp, const char *file_name); /* timer.c */ -- cgit v1.2.1