static void pkg_disappear(struct pkginfo *pkg, struct pkginfo *infavour) { printf(_("(Noting disappearance of %s, which has been completely replaced.)\n"), pkg_name(pkg, pnaw_nonambig)); log_action("disappear", pkg, &pkg->installed); debug(dbg_general, "pkg_disappear disappearing %s", pkg_name(pkg, pnaw_nonambig)); trig_activate_packageprocessing(pkg); maintainer_script_installed(pkg, POSTRMFILE, "post-removal script (for disappearance)", "disappear", infavour->set->name, versiondescribe(&infavour->available.version, vdew_nonambig), NULL); /* OK, now we delete all the stuff in the ‘info’ directory .. */ debug(dbg_general, "pkg_disappear cleaning info directory"); pkg_infodb_foreach(pkg, &pkg->installed, pkg_infodb_remove_file); dir_sync_path(pkgadmindir()); pkg_set_status(pkg, stat_notinstalled); pkg_set_want(pkg, want_unknown); pkg_reset_eflags(pkg); blankversion(&pkg->configversion); pkgbin_blank(&pkg->installed); pkg->clientdata->fileslistvalid = false; modstatdb_note(pkg); }
static void cleanupdates(void) { struct dirent **cdlist; int cdn, i; parsedb(statusfile, pdb_parse_status, NULL); *updatefnrest = '\0'; updateslength= -1; cdn= scandir(updatefnbuf, &cdlist, &ulist_select, alphasort); if (cdn == -1) ohshite(_("cannot scan updates directory `%.255s'"),updatefnbuf); if (cdn) { for (i=0; i<cdn; i++) { strcpy(updatefnrest, cdlist[i]->d_name); parsedb(updatefnbuf, pdb_parse_update, NULL); if (cstatus < msdbrw_write) free(cdlist[i]); } if (cstatus >= msdbrw_write) { writedb(statusfile, wdb_must_sync); for (i=0; i<cdn; i++) { strcpy(updatefnrest, cdlist[i]->d_name); if (unlink(updatefnbuf)) ohshite(_("failed to remove incorporated update file %.255s"),updatefnbuf); free(cdlist[i]); } dir_sync_path(updatesdir); } } free(cdlist); nextupdate= 0; }
static void statdb_write(void) { char *dbname; struct atomic_file *dbfile; struct fileiterator *iter; struct filenamenode *file; dbname = dpkg_db_get_path(STATOVERRIDEFILE); dbfile = atomic_file_new(dbname, aff_backup); atomic_file_open(dbfile); iter = files_db_iter_new(); while ((file = files_db_iter_next(iter))) statdb_node_print(dbfile->fp, file); files_db_iter_free(iter); atomic_file_sync(dbfile); atomic_file_close(dbfile); atomic_file_commit(dbfile); atomic_file_free(dbfile); dir_sync_path(dpkg_db_get_dir()); free(dbname); }
/* * If mask is nonzero, will not write any file whose filenamenode * has any flag bits set in mask. */ void write_filelist_except(struct pkginfo *pkg, struct pkgbin *pkgbin, struct fileinlist *list, enum fnnflags mask) { struct atomic_file *file; const char *listfile; listfile = pkg_infodb_get_file(pkg, pkgbin, LISTFILE); file = atomic_file_new(listfile, 0); atomic_file_open(file); while (list) { if (!(mask && (list->namenode->flags & mask))) { fputs(list->namenode->name, file->fp); putc('\n', file->fp); } list= list->next; } atomic_file_sync(file); atomic_file_close(file); atomic_file_commit(file); atomic_file_free(file); dir_sync_path(pkg_infodb_get_dir()); note_must_reread_files_inpackage(pkg); }
/** * Sync to disk the parent directory of a pathname. * * @param path The child pathname of the directory to sync. */ void dir_sync_path_parent(const char *path) { char *dirname, *slash; dirname = m_strdup(path); slash = strrchr(dirname, '/'); if (slash != NULL) { *slash = '\0'; dir_sync_path(dirname); } free(dirname); }
void trig_file_interests_save(void) { if (filetriggers_edited <= 0) return; if (!filetriggers.head) trig_file_interests_remove(); else trig_file_interests_update(); dir_sync_path(triggersdir); filetriggers_edited = 0; }
/* * If mask is nonzero, will not write any file whose filenamenode * has any flag bits set in mask. */ void write_filelist_except(struct pkginfo *pkg, struct pkgbin *pkgbin, struct fileinlist *list, enum fnnflags mask) { static struct varbuf newvb; const char *listfile; FILE *file; listfile = pkgadminfile(pkg, pkgbin, LISTFILE); varbuf_reset(&newvb); varbuf_add_str(&newvb, listfile); varbuf_add_str(&newvb, NEWDBEXT); varbuf_end_str(&newvb); file= fopen(newvb.buf,"w+"); if (!file) ohshite(_("unable to create updated files list file for package %s"), pkg_describe(pkg, pdo_foreign)); push_cleanup(cu_closestream, ehflag_bombout, NULL, 0, 1, (void *)file); while (list) { if (!(mask && (list->namenode->flags & mask))) { fputs(list->namenode->name,file); putc('\n',file); } list= list->next; } if (ferror(file)) ohshite(_("failed to write to updated files list file for package %s"), pkg_describe(pkg, pdo_foreign)); if (fflush(file)) ohshite(_("failed to flush updated files list file for package %s"), pkg_describe(pkg, pdo_foreign)); if (fsync(fileno(file))) ohshite(_("failed to sync updated files list file for package %s"), pkg_describe(pkg, pdo_foreign)); pop_cleanup(ehflag_normaltidy); /* file = fopen() */ if (fclose(file)) ohshite(_("failed to close updated files list file for package %s"), pkg_describe(pkg, pdo_foreign)); if (rename(newvb.buf, listfile)) ohshite(_("failed to install updated files list file for package %s"), pkg_describe(pkg, pdo_foreign)); dir_sync_path(pkgadmindir()); note_must_reread_files_inpackage(pkg); }
static void trk_explicit_interest_change(const char *trig, struct pkginfo *pkg, int signum, enum trig_options opts) { static struct varbuf newfn; char buf[1024]; FILE *nf; bool empty = true; trk_explicit_start(trig); varbuf_reset(&newfn); varbuf_printf(&newfn, "%s/%s.new", triggersdir, trig); nf = fopen(newfn.buf, "w"); if (!nf) ohshite(_("unable to create new trigger interest file `%.250s'"), newfn.buf); push_cleanup(cu_closestream, ~ehflag_normaltidy, NULL, 0, 1, nf); while (trk_explicit_f && trk_explicit_fgets(buf, sizeof(buf)) >= 0) { int len = strlen(pkg->name); if (strncmp(buf, pkg->name, len) == 0 && (buf[len] == '\0' || buf[len] == '/')) continue; fprintf(nf, "%s\n", buf); empty = false; } if (signum > 0) { fprintf(nf, "%s%s\n", pkg->name, (opts == trig_noawait) ? "/noawait" : ""); empty = false; } if (!empty) trk_explicit_interest_flush(newfn.buf, nf); pop_cleanup(ehflag_normaltidy); if (fclose(nf)) ohshite(_("unable to close new trigger interest file `%.250s'"), newfn.buf); if (empty) trk_explicit_interest_remove(newfn.buf); else trk_explicit_interest_commit(newfn.buf); dir_sync_path(triggersdir); }
void modstatdb_checkpoint(void) { int i; assert(cstatus >= msdbrw_write); writedb(statusfile, wdb_must_sync); for (i=0; i<nextupdate; i++) { sprintf(updatefnrest, IMPORTANTFMT, i); /* Have we made a real mess? */ assert(strlen(updatefnrest) <= IMPORTANTMAXLEN); if (unlink(updatefnbuf)) ohshite(_("failed to remove my own update file %.255s"),updatefnbuf); } dir_sync_path(updatesdir); nextupdate= 0; }
static void trk_explicit_interest_change(const char *trig, struct pkginfo *pkg, struct pkgbin *pkgbin, int signum, enum trig_options opts) { char buf[1024]; struct atomic_file *file; bool empty = true; trk_explicit_start(trig); file = atomic_file_new(trk_explicit_fn.buf, 0); atomic_file_open(file); while (trk_explicit_f && trk_explicit_fgets(buf, sizeof(buf)) >= 0) { const char *pkgname = pkgbin_name(pkg, pkgbin, pnaw_nonambig); size_t len = strlen(pkgname); if (strncmp(buf, pkgname, len) == 0 && len < sizeof(buf) && (buf[len] == '\0' || buf[len] == '/')) continue; fprintf(file->fp, "%s\n", buf); empty = false; } if (signum > 0) { fprintf(file->fp, "%s%s\n", pkgbin_name(pkg, pkgbin, pnaw_nonambig), (opts == TRIG_NOAWAIT) ? "/noawait" : ""); empty = false; } if (!empty) atomic_file_sync(file); atomic_file_close(file); if (empty) atomic_file_remove(file); else atomic_file_commit(file); atomic_file_free(file); dir_sync_path(triggersdir); }
static void modstatdb_note_core(struct pkginfo *pkg) { assert(cstatus >= msdbrw_write); varbuf_reset(&uvb); varbufrecord(&uvb, pkg, &pkg->installed); if (fwrite(uvb.buf, 1, uvb.used, importanttmp) != uvb.used) ohshite(_("unable to write updated status of `%.250s'"), pkg_name(pkg, pnaw_nonambig)); if (fflush(importanttmp)) ohshite(_("unable to flush updated status of `%.250s'"), pkg_name(pkg, pnaw_nonambig)); if (ftruncate(fileno(importanttmp), uvb.used)) ohshite(_("unable to truncate for updated status of `%.250s'"), pkg_name(pkg, pnaw_nonambig)); if (fsync(fileno(importanttmp))) ohshite(_("unable to fsync updated status of `%.250s'"), pkg_name(pkg, pnaw_nonambig)); if (fclose(importanttmp)) ohshite(_("unable to close updated status of `%.250s'"), pkg_name(pkg, pnaw_nonambig)); sprintf(updatefnrest, IMPORTANTFMT, nextupdate); if (rename(importanttmpfile, updatefnbuf)) ohshite(_("unable to install updated status of `%.250s'"), pkg_name(pkg, pnaw_nonambig)); dir_sync_path(updatesdir); /* Have we made a real mess? */ assert(strlen(updatefnrest) <= IMPORTANTMAXLEN); nextupdate++; if (nextupdate > MAXUPDATES) { modstatdb_checkpoint(); nextupdate = 0; } createimptmp(); }
static void pkg_infodb_update(struct pkginfo *pkg, char *cidir, char *cidirrest) { struct match_node *match_node; DIR *dsd; struct dirent *de; /* Deallocate the match list in case we aborted previously. */ while ((match_node = match_head)) { match_head = match_node->next; match_node_free(match_node); } pkg_infodb_foreach(pkg, &pkg->available, pkg_infodb_update_file); while ((match_node = match_head)) { strcpy(cidirrest, match_node->filetype); if (!rename(cidir, match_node->filename)) { debug(dbg_scripts, "process_archive info installed %s as %s", cidir, match_node->filename); } else if (errno == ENOENT) { /* Right, no new version. */ if (unlink(match_node->filename)) ohshite(_("unable to remove obsolete info file `%.250s'"), match_node->filename); debug(dbg_scripts, "process_archive info unlinked %s", match_node->filename); } else { ohshite(_("unable to install (supposed) new info file `%.250s'"), cidir); } match_head = match_node->next; match_node_free(match_node); } /* The control directory itself. */ cidirrest[0] = '\0'; dsd = opendir(cidir); if (!dsd) ohshite(_("unable to open temp control directory")); push_cleanup(cu_closedir, ~0, NULL, 0, 1, (void *)dsd); while ((de = readdir(dsd))) { const char *newinfofilename; if (strchr(de->d_name, '.')) { debug(dbg_scripts,"process_archive tmp.ci script/file `%s' contains dot", de->d_name); continue; } if (strlen(de->d_name) > MAXCONTROLFILENAME) ohshit(_("package contains overly-long control info file name (starting `%.50s')"), de->d_name); strcpy(cidirrest, de->d_name); /* First we check it's not a directory. */ if (rmdir(cidir) == 0) ohshit(_("package control info contained directory `%.250s'"), cidir); else if (errno != ENOTDIR) ohshite(_("package control info rmdir of `%.250s' didn't say not a dir"), de->d_name); /* Ignore the control file. */ if (strcmp(de->d_name, CONTROLFILE) == 0) { debug(dbg_scripts, "process_archive tmp.ci script/file `%s' is control", cidir); continue; } if (strcmp(de->d_name, LISTFILE) == 0) { warning(_("package %s contained list as info file"), pkgbin_name(pkg, &pkg->available, pnaw_nonambig)); continue; } /* Right, install it */ newinfofilename = pkgadminfile(pkg, &pkg->available, de->d_name); if (rename(cidir, newinfofilename)) ohshite(_("unable to install new info file `%.250s' as `%.250s'"), cidir, newinfofilename); debug(dbg_scripts, "process_archive tmp.ci script/file `%s' installed as `%s'", cidir, newinfofilename); } pop_cleanup(ehflag_normaltidy); /* closedir */ dir_sync_path(pkgadmindir()); }
void do_auto(const char *const *argv) { const char *partfile; struct partinfo *pi, *refi, *npi, **partlist, *otherthispart; struct partqueue *pq; unsigned int i; int j, ap; long nr; FILE *part; void *buffer; char *p, *q; if (!opt_outputfile) badusage(_("--auto requires the use of the --output option")); if (!(partfile= *argv++) || *argv) badusage(_("--auto requires exactly one part file argument")); refi= nfmalloc(sizeof(struct partqueue)); part= fopen(partfile,"r"); if (!part) ohshite(_("unable to read part file `%.250s'"),partfile); if (!read_info(part,partfile,refi)) { if (!opt_npquiet) printf(_("File `%.250s' is not part of a multipart archive.\n"),partfile); m_output(stdout, _("<standard output>")); exit(1); } fclose(part); scandepot(); partlist= nfmalloc(sizeof(struct partinfo*)*refi->maxpartn); for (i = 0; i < refi->maxpartn; i++) partlist[i] = NULL; for (pq= queue; pq; pq= pq->nextinqueue) { pi= &pq->info; if (!partmatches(pi,refi)) continue; npi= nfmalloc(sizeof(struct partinfo)); mustgetpartinfo(pi->filename,npi); addtopartlist(partlist,npi,refi); } /* If we already have a copy of this version we ignore it and prefer the * new one, but we still want to delete the one in the depot, so we * save its partinfo (with the filename) for later. This also prevents * us from accidentally deleting the source file. */ otherthispart= partlist[refi->thispartn-1]; partlist[refi->thispartn-1]= refi; for (j=refi->maxpartn-1; j>=0 && partlist[j]; j--); if (j>=0) { part= fopen(partfile,"r"); if (!part) ohshite(_("unable to reopen part file `%.250s'"),partfile); buffer= nfmalloc(refi->filesize); nr= fread(buffer,1,refi->filesize,part); if (nr != refi->filesize) rerreof(part,partfile); if (getc(part) != EOF) ohshit(_("part file `%.250s' has trailing garbage"),partfile); if (ferror(part)) rerr(partfile); fclose(part); p = nfmalloc(strlen(opt_depotdir) + 50); q = nfmalloc(strlen(opt_depotdir) + 200); sprintf(p, "%st.%lx", opt_depotdir, (long)getpid()); sprintf(q, "%s%s.%lx.%x.%x", opt_depotdir, refi->md5sum, refi->maxpartlen,refi->thispartn,refi->maxpartn); part= fopen(p,"w"); if (!part) ohshite(_("unable to open new depot file `%.250s'"),p); nr= fwrite(buffer,1,refi->filesize,part); if (nr != refi->filesize) werr(p); if (fflush(part)) ohshite(_("unable to flush file '%s'"), p); if (fsync(fileno(part))) ohshite(_("unable to sync file '%s'"), p); if (fclose(part)) werr(p); if (rename(p,q)) ohshite(_("unable to rename new depot file `%.250s' to `%.250s'"),p,q); printf(_("Part %d of package %s filed (still want "),refi->thispartn,refi->package); /* There are still some parts missing. */ for (i=0, ap=0; i<refi->maxpartn; i++) if (!partlist[i]) printf("%s%d", !ap++ ? "" : i == (unsigned int)j ? _(" and ") : ", ", i + 1); printf(").\n"); dir_sync_path(opt_depotdir); } else { /* We have all the parts. */ reassemble(partlist, opt_outputfile); /* OK, delete all the parts (except the new one, which we never copied). */ partlist[refi->thispartn-1]= otherthispart; for (i=0; i<refi->maxpartn; i++) if (partlist[i]) if (unlink(partlist[i]->filename)) ohshite(_("unable to delete used-up depot file `%.250s'"),partlist[i]->filename); } m_output(stderr, _("<standard error>")); }
int do_auto(const char *const *argv) { const char *partfile; struct partinfo *refi, **partlist, *otherthispart; struct partqueue *pq; unsigned int i; int j; FILE *part; if (!opt_outputfile) badusage(_("--auto requires the use of the --output option")); if (!(partfile= *argv++) || *argv) badusage(_("--auto requires exactly one part file argument")); refi= nfmalloc(sizeof(struct partqueue)); part= fopen(partfile,"r"); if (!part) ohshite(_("unable to read part file `%.250s'"),partfile); if (!read_info(part,partfile,refi)) { if (!opt_npquiet) printf(_("File `%.250s' is not part of a multipart archive.\n"),partfile); m_output(stdout, _("<standard output>")); return 1; } fclose(part); scandepot(); partlist= nfmalloc(sizeof(struct partinfo*)*refi->maxpartn); for (i = 0; i < refi->maxpartn; i++) partlist[i] = NULL; for (pq= queue; pq; pq= pq->nextinqueue) { struct partinfo *npi, *pi = &pq->info; if (!partmatches(pi,refi)) continue; npi= nfmalloc(sizeof(struct partinfo)); mustgetpartinfo(pi->filename,npi); addtopartlist(partlist,npi,refi); } /* If we already have a copy of this version we ignore it and prefer the * new one, but we still want to delete the one in the depot, so we * save its partinfo (with the filename) for later. This also prevents * us from accidentally deleting the source file. */ otherthispart= partlist[refi->thispartn-1]; partlist[refi->thispartn-1]= refi; for (j=refi->maxpartn-1; j>=0 && partlist[j]; j--); if (j>=0) { int fd_src, fd_dst; int ap; char *p, *q; m_asprintf(&p, "%st.%lx", opt_depotdir, (long)getpid()); m_asprintf(&q, "%s%s.%jx.%x.%x", opt_depotdir, refi->md5sum, (intmax_t)refi->maxpartlen, refi->thispartn, refi->maxpartn); fd_src = open(partfile, O_RDONLY); if (fd_src < 0) ohshite(_("unable to reopen part file `%.250s'"), partfile); fd_dst = creat(p, 0644); if (fd_dst < 0) ohshite(_("unable to open new depot file `%.250s'"), p); fd_fd_copy(fd_src, fd_dst, refi->filesize, _("extracting split part")); if (fsync(fd_dst)) ohshite(_("unable to sync file '%s'"), p); if (close(fd_dst)) ohshite(_("unable to close file '%s'"), p); close(fd_src); if (rename(p,q)) ohshite(_("unable to rename new depot file `%.250s' to `%.250s'"),p,q); free(q); free(p); printf(_("Part %d of package %s filed (still want "),refi->thispartn,refi->package); /* There are still some parts missing. */ for (i=0, ap=0; i<refi->maxpartn; i++) if (!partlist[i]) printf("%s%d", !ap++ ? "" : i == (unsigned int)j ? _(" and ") : ", ", i + 1); printf(").\n"); dir_sync_path(opt_depotdir); } else { /* We have all the parts. */ reassemble(partlist, opt_outputfile); /* OK, delete all the parts (except the new one, which we never copied). */ partlist[refi->thispartn-1]= otherthispart; for (i=0; i<refi->maxpartn; i++) if (partlist[i]) if (unlink(partlist[i]->filename)) ohshite(_("unable to delete used-up depot file `%.250s'"),partlist[i]->filename); } m_output(stderr, _("<standard error>")); return 0; }