static void breaks_check_one(struct varbuf *aemsgs, enum dep_check *ok, struct deppossi *breaks, struct pkginfo *broken, struct pkginfo *breaker, struct deppossi *virtbroken) { struct varbuf depmsg = VARBUF_INIT; debug(dbg_depcondetail, " checking breaker %s virtbroken %s", pkg_name(breaker, pnaw_always), virtbroken ? virtbroken->ed->name : "<none>"); if (breaker->status == PKG_STAT_NOTINSTALLED || breaker->status == PKG_STAT_CONFIGFILES) return; if (broken == breaker) return; if (!versionsatisfied(&broken->installed, breaks)) return; /* The test below can only trigger if dep_breaks start having * arch qualifiers different from “any”. */ if (!archsatisfied(&broken->installed, breaks)) return; if (ignore_depends(breaker)) return; if (virtbroken && ignore_depends(&virtbroken->ed->pkg)) return; if (virtbroken && !pkg_virtual_deppossi_satisfied(breaks, virtbroken)) return; varbufdependency(&depmsg, breaks->up); varbuf_end_str(&depmsg); varbuf_printf(aemsgs, _(" %s (%s) breaks %s and is %s.\n"), pkg_name(breaker, pnaw_nonambig), versiondescribe(&breaker->installed.version, vdew_nonambig), depmsg.buf, gettext(statusstrings[breaker->status])); varbuf_destroy(&depmsg); if (virtbroken) { varbuf_printf(aemsgs, _(" %s (%s) provides %s.\n"), pkg_name(broken, pnaw_nonambig), versiondescribe(&broken->installed.version, vdew_nonambig), virtbroken->ed->name); } else if (breaks->verrel != DPKG_RELATION_NONE) { varbuf_printf(aemsgs, _(" Version of %s to be configured is %s.\n"), pkg_name(broken, pnaw_nonambig), versiondescribe(&broken->installed.version, vdew_nonambig)); if (in_force(FORCE_DEPENDS_VERSION)) return; } if (force_breaks(breaks)) return; *ok = DEP_CHECK_HALT; }
void varbufversion (struct varbuf *vb, const struct dpkg_version *version, enum versiondisplayepochwhen vdew) { switch (vdew) { case vdew_never: break; case vdew_nonambig: if (!version->epoch && (!version->version || !strchr(version->version,':')) && (!version->revision || !strchr(version->revision,':'))) break; /* Fall through. */ case vdew_always: varbuf_printf(vb, "%u:", version->epoch); break; default: internerr("unknown versiondisplayepochwhen '%d'", vdew); } if (version->version) varbuf_add_str(vb, version->version); if (str_is_set(version->revision)) { varbuf_add_char(vb, '-'); varbuf_add_str(vb, version->revision); } }
/** * Read a filename from the file descriptor and create a file_info struct. * * @return A file_info struct or NULL if there is nothing to read. */ static struct file_info * file_info_get(const char *root, int fd) { static struct varbuf fn = VARBUF_INIT; struct file_info *fi; size_t root_len; varbuf_reset(&fn); root_len = varbuf_printf(&fn, "%s/", root); while (1) { int res; varbuf_grow(&fn, 1); res = fd_read(fd, (fn.buf + fn.used), 1); if (res < 0) return NULL; if (res == 0) /* EOF -> parent died. */ return NULL; if (fn.buf[fn.used] == '\0') break; varbuf_trunc(&fn, fn.used + 1); if (fn.used >= MAXFILENAME) ohshit(_("file name '%.50s...' is too long"), fn.buf + root_len); } fi = file_info_new(fn.buf + root_len); if (lstat(fn.buf, &(fi->st)) != 0) ohshite(_("unable to stat file name '%.250s'"), fn.buf); return fi; }
static void info_spew(const char *debar, const char *dir, const char *const *argv) { struct dpkg_error err; const char *component; struct varbuf controlfile = VARBUF_INIT; int fd; int re= 0; while ((component = *argv++) != NULL) { varbuf_reset(&controlfile); varbuf_printf(&controlfile, "%s/%s", dir, component); fd = open(controlfile.buf, O_RDONLY); if (fd >= 0) { if (fd_fd_copy(fd, 1, -1, &err) < 0) ohshit(_("cannot extract control file '%s' from '%s': %s"), controlfile.buf, debar, err.str); close(fd); } else if (errno == ENOENT) { notice(_("'%.255s' contains no control component '%.255s'"), debar, component); re++; } else { ohshite(_("open component `%.255s' (in %.255s) failed in an unexpected way"), component, dir); } } varbuf_destroy(&controlfile); if (re > 0) ohshit(P_("%d requested control component is missing", "%d requested control components are missing", re), re); }
static void breaks_check_one(struct varbuf *aemsgs, enum dep_check *ok, struct deppossi *breaks, struct pkginfo *broken, struct pkginfo *breaker, struct pkgset *virtbroken) { struct varbuf depmsg = VARBUF_INIT; debug(dbg_depcondetail, " checking breaker %s virtbroken %s", pkg_name(breaker, pnaw_always), virtbroken ? virtbroken->name : "<none>"); if (breaker->status == stat_notinstalled || breaker->status == stat_configfiles) return; if (broken == breaker) return; if (!versionsatisfied(&broken->installed, breaks)) return; /* The test below can only trigger if dep_breaks start having * arch qualifiers different from “any”. */ if (!archsatisfied(&broken->installed, breaks)) return; if (ignore_depends(breaker)) return; if (virtbroken && ignore_depends(&virtbroken->pkg)) return; varbufdependency(&depmsg, breaks->up); varbuf_end_str(&depmsg); varbuf_printf(aemsgs, _(" %s (%s) breaks %s and is %s.\n"), pkg_name(breaker, pnaw_nonambig), versiondescribe(&breaker->installed.version, vdew_nonambig), depmsg.buf, gettext(statusstrings[breaker->status])); varbuf_destroy(&depmsg); if (virtbroken) { varbuf_printf(aemsgs, _(" %s (%s) provides %s.\n"), pkg_name(broken, pnaw_nonambig), versiondescribe(&broken->installed.version, vdew_nonambig), virtbroken->name); } else if (breaks->verrel != dpkg_relation_none) { varbuf_printf(aemsgs, _(" Version of %s to be configured is %s.\n"), pkg_name(broken, pnaw_nonambig), versiondescribe(&broken->installed.version, vdew_nonambig)); if (fc_dependsversion) return; } if (force_breaks(breaks)) return; *ok = dep_check_halt; }
static const char * diversion_current(const char *filename) { static struct varbuf str = VARBUF_INIT; if (opt_pkgname_match_any) { varbuf_reset(&str); if (opt_divertto == NULL) varbuf_printf(&str, _("any diversion of %s"), filename); else varbuf_printf(&str, _("any diversion of %s to %s"), filename, opt_divertto); } else { return varbuf_diversion(&str, opt_pkgname, filename, opt_divertto); } return str.buf; }
static const char * varbuf_diversion(struct varbuf *str, const char *pkgname, const char *filename, const char *divertto) { varbuf_reset(str); if (pkgname == NULL) { if (divertto == NULL) varbuf_printf(str, _("local diversion of %s"), filename); else varbuf_printf(str, _("local diversion of %s to %s"), filename, divertto); } else { if (divertto == NULL) varbuf_printf(str, _("diversion of %s by %s"), filename, pkgname); else varbuf_printf(str, _("diversion of %s to %s by %s"), filename, divertto, pkgname); } return str->buf; }
/** * Check control directory and file permissions. */ static void check_file_perms(const char *ctrldir) { struct varbuf path = VARBUF_INIT; const char *const *mscriptp; struct stat mscriptstab; varbuf_printf(&path, "%s/", ctrldir); if (lstat(path.buf, &mscriptstab)) ohshite(_("unable to stat control directory")); if (!S_ISDIR(mscriptstab.st_mode)) ohshit(_("control directory is not a directory")); if ((mscriptstab.st_mode & 07757) != 0755) ohshit(_("control directory has bad permissions %03lo " "(must be >=0755 and <=0775)"), (unsigned long)(mscriptstab.st_mode & 07777)); for (mscriptp = maintainerscripts; *mscriptp; mscriptp++) { varbuf_reset(&path); varbuf_printf(&path, "%s/%s", ctrldir, *mscriptp); if (!lstat(path.buf, &mscriptstab)) { if (S_ISLNK(mscriptstab.st_mode)) continue; if (!S_ISREG(mscriptstab.st_mode)) ohshit(_("maintainer script '%.50s' is not a plain file or symlink"), *mscriptp); if ((mscriptstab.st_mode & 07557) != 0555) ohshit(_("maintainer script '%.50s' has bad permissions %03lo " "(must be >=0555 and <=0775)"), *mscriptp, (unsigned long)(mscriptstab.st_mode & 07777)); } else if (errno != ENOENT) { ohshite(_("maintainer script '%.50s' is not stattable"), *mscriptp); } } varbuf_destroy(&path); }
static void test_varbuf_printf(void) { struct varbuf vb; varbuf_init(&vb, 5); /* Test normal format printing. */ varbuf_printf(&vb, "format %s number %d", "string", 10); test_pass(vb.used == strlen("format string number 10")); test_pass(vb.size >= vb.used); test_str(vb.buf, ==, "format string number 10"); varbuf_reset(&vb); /* Test concatenated format printing. */ varbuf_printf(&vb, "format %s number %d", "string", 10); varbuf_printf(&vb, " extra %s", "string"); test_pass(vb.used == strlen("format string number 10 extra string")); test_pass(vb.size >= vb.used); test_str(vb.buf, ==, "format string number 10 extra string"); varbuf_destroy(&vb); }
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 describedepcon(struct varbuf *addto, struct dependency *dep) { const char *fmt; struct varbuf depstr = VARBUF_INIT; switch (dep->type) { case dep_depends: fmt = _("%s depends on %s"); break; case dep_predepends: fmt = _("%s pre-depends on %s"); break; case dep_recommends: fmt = _("%s recommends %s"); break; case dep_suggests: fmt = _("%s suggests %s"); break; case dep_breaks: fmt = _("%s breaks %s"); break; case dep_conflicts: fmt = _("%s conflicts with %s"); break; case dep_enhances: fmt = _("%s enhances %s"); break; default: internerr("unknown deptype '%d'", dep->type); } varbufdependency(&depstr, dep); varbuf_end_str(&depstr); varbuf_printf(addto, fmt, pkg_name(dep->up, pnaw_nonambig), depstr.buf); varbuf_destroy(&depstr); }
/* * Return values: * 0: cannot be satisfied. * 1: defer: may be satisfied later, when other packages are better or * at higher dependtry due to --force * will set *fixbytrig to package whose trigger processing would help * if applicable (and leave it alone otherwise). * 2: not satisfied but forcing * (*interestingwarnings >= 0 on exit? caller is to print oemsgs). * 3: satisfied now. */ static enum found_status deppossi_ok_found(struct pkginfo *possdependee, struct pkginfo *requiredby, struct pkginfo *removing, struct pkgset *providing, struct pkginfo **fixbytrig, bool *matched, struct deppossi *checkversion, int *interestingwarnings, struct varbuf *oemsgs) { enum found_status thisf; if (ignore_depends(possdependee)) { debug(dbg_depcondetail," ignoring depended package so ok and found"); return found_ok; } thisf = found_none; if (possdependee == removing) { if (providing) { varbuf_printf(oemsgs, _(" Package %s which provides %s is to be removed.\n"), pkg_name(possdependee, pnaw_nonambig), providing->name); } else { varbuf_printf(oemsgs, _(" Package %s is to be removed.\n"), pkg_name(possdependee, pnaw_nonambig)); } *matched = true; debug(dbg_depcondetail," removing possdependee, returning %d",thisf); return thisf; } switch (possdependee->status) { case stat_unpacked: case stat_halfconfigured: case stat_triggersawaited: case stat_triggerspending: case stat_installed: if (checkversion && !versionsatisfied(&possdependee->installed,checkversion)) { varbuf_printf(oemsgs, _(" Version of %s on system is %s.\n"), pkg_name(possdependee, pnaw_nonambig), versiondescribe(&possdependee->installed.version, vdew_nonambig)); assert(checkversion->verrel != dpkg_relation_none); if (fc_dependsversion) thisf = (dependtry >= 3) ? found_forced : found_defer; debug(dbg_depcondetail," bad version, returning %d",thisf); (*interestingwarnings)++; return thisf; } if (possdependee->status == stat_installed || possdependee->status == stat_triggerspending) { debug(dbg_depcondetail," is installed, ok and found"); return found_ok; } if (possdependee->status == stat_triggersawaited) { assert(possdependee->trigaw.head); if (removing || !(f_triggers || possdependee->clientdata->istobe == itb_installnew)) { if (providing) { varbuf_printf(oemsgs, _(" Package %s which provides %s awaits trigger processing.\n"), pkg_name(possdependee, pnaw_nonambig), providing->name); } else { varbuf_printf(oemsgs, _(" Package %s awaits trigger processing.\n"), pkg_name(possdependee, pnaw_nonambig)); } debug(dbg_depcondetail, " triggers-awaited, no fixbytrig"); goto unsuitable; } /* We don't check the status of trigaw.head->pend here, just in case * we get into the pathological situation where Triggers-Awaited but * the named package doesn't actually have any pending triggers. In * that case we queue the non-pending package for trigger processing * anyway, and that trigger processing will be a noop except for * sorting out all of the packages which name it in Triggers-Awaited. * * (This situation can only arise if modstatdb_note success in * clearing the triggers-pending status of the pending package * but then fails to go on to update the awaiters.) */ *fixbytrig = possdependee->trigaw.head->pend; debug(dbg_depcondetail, " triggers-awaited, fixbytrig '%s', defer", pkg_name(*fixbytrig, pnaw_always)); return found_defer; } if (possdependee->clientdata && possdependee->clientdata->istobe == itb_installnew) { debug(dbg_depcondetail," unpacked/halfconfigured, defer"); return found_defer; } else if (!removing && fc_configureany && !skip_due_to_hold(possdependee) && !(possdependee->status == stat_halfconfigured)) { notice(_("also configuring '%s' (required by '%s')"), pkg_name(possdependee, pnaw_nonambig), pkg_name(requiredby, pnaw_nonambig)); enqueue_package(possdependee); sincenothing = 0; return found_defer; } else { if (providing) { varbuf_printf(oemsgs, _(" Package %s which provides %s is not configured yet.\n"), pkg_name(possdependee, pnaw_nonambig), providing->name); } else { varbuf_printf(oemsgs, _(" Package %s is not configured yet.\n"), pkg_name(possdependee, pnaw_nonambig)); } debug(dbg_depcondetail, " not configured/able"); goto unsuitable; } default: if (providing) { varbuf_printf(oemsgs, _(" Package %s which provides %s is not installed.\n"), pkg_name(possdependee, pnaw_nonambig), providing->name); } else { varbuf_printf(oemsgs, _(" Package %s is not installed.\n"), pkg_name(possdependee, pnaw_nonambig)); } debug(dbg_depcondetail, " not installed"); goto unsuitable; } unsuitable: debug(dbg_depcondetail, " returning %d", thisf); (*interestingwarnings)++; return thisf; }
static void info_list(const char *debar, const char *dir) { char interpreter[INTERPRETER_MAX+1], *p; int il, lines; struct varbuf controlfile = VARBUF_INIT; struct dirent **cdlist, *cdep; int cdn, n; FILE *cc; struct stat stab; int c; cdn = scandir(dir, &cdlist, &ilist_select, alphasort); if (cdn == -1) ohshite(_("cannot scan directory `%.255s'"), dir); for (n = 0; n < cdn; n++) { cdep = cdlist[n]; varbuf_reset(&controlfile); varbuf_printf(&controlfile, "%s/%s", dir, cdep->d_name); if (stat(controlfile.buf, &stab)) ohshite(_("cannot stat `%.255s' (in `%.255s')"), cdep->d_name, dir); if (S_ISREG(stab.st_mode)) { cc = fopen(controlfile.buf, "r"); if (!cc) ohshite(_("cannot open `%.255s' (in `%.255s')"), cdep->d_name, dir); lines = 0; interpreter[0] = '\0'; if (getc(cc) == '#') { if (getc(cc) == '!') { while ((c= getc(cc))== ' '); p=interpreter; *p++='#'; *p++='!'; il=2; while (il<INTERPRETER_MAX && !isspace(c) && c!=EOF) { *p++= c; il++; c= getc(cc); } *p = '\0'; if (c=='\n') lines++; } } while ((c= getc(cc))!= EOF) { if (c == '\n') lines++; } if (ferror(cc)) ohshite(_("failed to read `%.255s' (in `%.255s')"), cdep->d_name, dir); fclose(cc); printf(_(" %7jd bytes, %5d lines %c %-20.127s %.127s\n"), (intmax_t)stab.st_size, lines, S_IXUSR & stab.st_mode ? '*' : ' ', cdep->d_name, interpreter); } else { printf(_(" not a plain file %.255s\n"), cdep->d_name); } free(cdep); } free(cdlist); varbuf_reset(&controlfile); varbuf_printf(&controlfile, "%s/%s", dir, CONTROLFILE); cc = fopen(controlfile.buf, "r"); if (!cc) { if (errno != ENOENT) ohshite(_("failed to read `%.255s' (in `%.255s')"), CONTROLFILE, dir); fputs(_("(no `control' file in control archive!)\n"), stdout); } else { lines= 1; while ((c= getc(cc))!= EOF) { if (lines) putc(' ', stdout); putc(c, stdout); lines= c=='\n'; } if (!lines) putc('\n', stdout); if (ferror(cc)) ohshite(_("failed to read `%.255s' (in `%.255s')"), CONTROLFILE, dir); fclose(cc); } m_output(stdout, _("<standard output>")); varbuf_destroy(&controlfile); }
void pkg_format_show(const struct pkg_format_node *head, struct pkginfo *pkg, struct pkgbin *pkgbin) { struct varbuf vb = VARBUF_INIT, fb = VARBUF_INIT, wb = VARBUF_INIT; while (head) { bool ok; char fmt[16]; ok = false; if (head->width > 0) snprintf(fmt, 16, "%%%s%zus", ((head->pad) ? "-" : ""), head->width); else strcpy(fmt, "%s"); if (head->type == PKG_FORMAT_STRING) { varbuf_printf(&fb, fmt, head->data); ok = true; } else if (head->type == PKG_FORMAT_FIELD) { const struct fieldinfo *fip; fip = find_field_info(fieldinfos, head); if (fip->name == NULL) fip = find_field_info(virtinfos, head); if (fip->name) { fip->wcall(&wb, pkg, pkgbin, 0, fip); varbuf_end_str(&wb); varbuf_printf(&fb, fmt, wb.buf); varbuf_reset(&wb); ok = true; } else { const struct arbitraryfield *afp; for (afp = pkgbin->arbs; afp; afp = afp->next) if (strcasecmp(head->data, afp->name) == 0) { varbuf_printf(&fb, fmt, afp->value); ok = true; break; } } } if (ok) { size_t len = strlen(fb.buf); if ((head->width > 0) && (len > head->width)) len = head->width; varbuf_add_buf(&vb, fb.buf, len); } varbuf_reset(&fb); head = head->next; } if (vb.buf) { varbuf_end_str(&vb); fputs(vb.buf, stdout); } varbuf_destroy(&wb); varbuf_destroy(&fb); varbuf_destroy(&vb); }
/** * Check if conffiles contains sane information. */ static void check_conffiles(const char *ctrldir, const char *rootdir) { FILE *cf; struct varbuf controlfile = VARBUF_INIT; char conffilename[MAXCONFFILENAME + 1]; struct file_info *conffiles_head = NULL; struct file_info *conffiles_tail = NULL; varbuf_printf(&controlfile, "%s/%s", ctrldir, CONFFILESFILE); cf = fopen(controlfile.buf, "r"); if (cf == NULL) { if (errno == ENOENT) return; ohshite(_("error opening conffiles file")); } while (fgets(conffilename, MAXCONFFILENAME + 1, cf)) { struct stat controlstab; int n; n = strlen(conffilename); if (!n) ohshite(_("empty string from fgets reading conffiles")); if (conffilename[n - 1] != '\n') ohshit(_("conffile name '%s' is too long, or missing final newline"), conffilename); conffilename[n - 1] = '\0'; varbuf_reset(&controlfile); varbuf_printf(&controlfile, "%s/%s", rootdir, conffilename); if (lstat(controlfile.buf, &controlstab)) { if (errno == ENOENT) { if ((n > 1) && c_isspace(conffilename[n - 2])) warning(_("conffile filename '%s' contains trailing white spaces"), conffilename); ohshit(_("conffile '%.250s' does not appear in package"), conffilename); } else ohshite(_("conffile '%.250s' is not stattable"), conffilename); } else if (!S_ISREG(controlstab.st_mode)) { warning(_("conffile '%s' is not a plain file"), conffilename); } if (file_info_find_name(conffiles_head, conffilename)) { warning(_("conffile name '%s' is duplicated"), conffilename); } else { struct file_info *conffile; conffile = file_info_new(conffilename); file_info_list_append(&conffiles_head, &conffiles_tail, conffile); } } file_info_list_free(conffiles_head); varbuf_destroy(&controlfile); if (ferror(cf)) ohshite(_("error reading conffiles file")); fclose(cf); }
/* * Return values: * 0: cannot be satisfied. * 1: defer: may be satisfied later, when other packages are better or * at higher dependtry due to --force * will set *fixbytrig to package whose trigger processing would help * if applicable (and leave it alone otherwise). * 2: not satisfied but forcing * (*interestingwarnings >= 0 on exit? caller is to print oemsgs). * 3: satisfied now. */ static enum found_status deppossi_ok_found(struct pkginfo *possdependee, struct pkginfo *requiredby, struct pkginfo *removing, struct deppossi *provider, struct pkginfo **fixbytrig, bool *matched, struct deppossi *checkversion, int *interestingwarnings, struct varbuf *oemsgs) { enum found_status thisf; if (ignore_depends(possdependee)) { debug(dbg_depcondetail," ignoring depended package so ok and found"); return FOUND_OK; } thisf = FOUND_NONE; if (possdependee == removing) { if (provider) { varbuf_printf(oemsgs, _(" Package %s which provides %s is to be removed.\n"), pkg_name(possdependee, pnaw_nonambig), provider->ed->name); } else { varbuf_printf(oemsgs, _(" Package %s is to be removed.\n"), pkg_name(possdependee, pnaw_nonambig)); } *matched = true; debug(dbg_depcondetail," removing possdependee, returning %d",thisf); return thisf; } switch (possdependee->status) { case PKG_STAT_UNPACKED: case PKG_STAT_HALFCONFIGURED: case PKG_STAT_TRIGGERSAWAITED: case PKG_STAT_TRIGGERSPENDING: case PKG_STAT_INSTALLED: if (checkversion) { if (provider) { debug(dbg_depcondetail, " checking package %s provided by pkg %s", checkversion->ed->name, pkg_name(possdependee, pnaw_always)); if (!pkg_virtual_deppossi_satisfied(checkversion, provider)) { varbuf_printf(oemsgs, _(" Version of %s on system, provided by %s, is %s.\n"), checkversion->ed->name, pkg_name(possdependee, pnaw_always), versiondescribe(&provider->version, vdew_nonambig)); if (in_force(FORCE_DEPENDS_VERSION)) thisf = found_forced_on(DEPEND_TRY_FORCE_DEPENDS_VERSION); debug(dbg_depcondetail, " bad version"); goto unsuitable; } } else { debug(dbg_depcondetail, " checking non-provided pkg %s", pkg_name(possdependee, pnaw_always)); if (!versionsatisfied(&possdependee->installed, checkversion)) { varbuf_printf(oemsgs, _(" Version of %s on system is %s.\n"), pkg_name(possdependee, pnaw_nonambig), versiondescribe(&possdependee->installed.version, vdew_nonambig)); if (in_force(FORCE_DEPENDS_VERSION)) thisf = found_forced_on(DEPEND_TRY_FORCE_DEPENDS_VERSION); debug(dbg_depcondetail, " bad version"); goto unsuitable; } } } if (possdependee->status == PKG_STAT_INSTALLED || possdependee->status == PKG_STAT_TRIGGERSPENDING) { debug(dbg_depcondetail," is installed, ok and found"); return FOUND_OK; } if (possdependee->status == PKG_STAT_TRIGGERSAWAITED) { if (possdependee->trigaw.head == NULL) internerr("package %s in state %s, has no awaited triggers", pkg_name(possdependee, pnaw_always), pkg_status_name(possdependee)); if (removing || !(f_triggers || (possdependee->clientdata && possdependee->clientdata->istobe == PKG_ISTOBE_INSTALLNEW))) { if (provider) { varbuf_printf(oemsgs, _(" Package %s which provides %s awaits trigger processing.\n"), pkg_name(possdependee, pnaw_nonambig), provider->ed->name); } else { varbuf_printf(oemsgs, _(" Package %s awaits trigger processing.\n"), pkg_name(possdependee, pnaw_nonambig)); } debug(dbg_depcondetail, " triggers-awaited, no fixbytrig"); goto unsuitable; } /* We don't check the status of trigaw.head->pend here, just in case * we get into the pathological situation where Triggers-Awaited but * the named package doesn't actually have any pending triggers. In * that case we queue the non-pending package for trigger processing * anyway, and that trigger processing will be a noop except for * sorting out all of the packages which name it in Triggers-Awaited. * * (This situation can only arise if modstatdb_note success in * clearing the triggers-pending status of the pending package * but then fails to go on to update the awaiters.) */ *fixbytrig = possdependee->trigaw.head->pend; debug(dbg_depcondetail, " triggers-awaited, fixbytrig '%s', defer", pkg_name(*fixbytrig, pnaw_always)); return FOUND_DEFER; } if (possdependee->clientdata && possdependee->clientdata->istobe == PKG_ISTOBE_INSTALLNEW) { debug(dbg_depcondetail," unpacked/halfconfigured, defer"); return FOUND_DEFER; } else if (!removing && in_force(FORCE_CONFIGURE_ANY) && !skip_due_to_hold(possdependee) && !(possdependee->status == PKG_STAT_HALFCONFIGURED)) { notice(_("also configuring '%s' (required by '%s')"), pkg_name(possdependee, pnaw_nonambig), pkg_name(requiredby, pnaw_nonambig)); enqueue_package(possdependee); sincenothing = 0; return FOUND_DEFER; } else { if (provider) { varbuf_printf(oemsgs, _(" Package %s which provides %s is not configured yet.\n"), pkg_name(possdependee, pnaw_nonambig), provider->ed->name); } else { varbuf_printf(oemsgs, _(" Package %s is not configured yet.\n"), pkg_name(possdependee, pnaw_nonambig)); } debug(dbg_depcondetail, " not configured/able"); goto unsuitable; } default: if (provider) { varbuf_printf(oemsgs, _(" Package %s which provides %s is not installed.\n"), pkg_name(possdependee, pnaw_nonambig), provider->ed->name); } else { varbuf_printf(oemsgs, _(" Package %s is not installed.\n"), pkg_name(possdependee, pnaw_nonambig)); } debug(dbg_depcondetail, " not installed"); goto unsuitable; } unsuitable: debug(dbg_depcondetail, " returning %d", thisf); (*interestingwarnings)++; return thisf; }
static int mksplit(const char *file_src, const char *prefix, off_t maxpartsize, bool msdos) { int fd_src; struct stat st; char hash[MD5HASHLEN + 1]; char *package, *version, *arch; int nparts, curpart; off_t partsize; off_t cur_partsize, last_partsize; char *prefixdir = NULL, *msdos_prefix = NULL; struct varbuf file_dst = VARBUF_INIT; struct varbuf partmagic = VARBUF_INIT; struct varbuf partname = VARBUF_INIT; fd_src = open(file_src, O_RDONLY); if (fd_src < 0) ohshite(_("unable to open source file `%.250s'"), file_src); if (fstat(fd_src, &st)) ohshite(_("unable to fstat source file")); if (!S_ISREG(st.st_mode)) ohshit(_("source file `%.250s' not a plain file"), file_src); fd_md5(fd_src, hash, -1, "md5hash"); lseek(fd_src, 0, SEEK_SET); /* FIXME: Use libdpkg-deb. */ package = deb_field(file_src, "Package"); version = deb_field(file_src, "Version"); arch = deb_field(file_src, "Architecture"); partsize = maxpartsize - HEADERALLOWANCE; last_partsize = st.st_size % partsize; if (last_partsize == 0) last_partsize = partsize; nparts = (st.st_size + partsize - 1) / partsize; setvbuf(stdout, NULL, _IONBF, 0); printf(P_("Splitting package %s into %d part: ", "Splitting package %s into %d parts: ", nparts), package, nparts); if (msdos) { char *t; t = m_strdup(prefix); prefixdir = m_strdup(dirname(t)); free(t); msdos_prefix = m_strdup(path_basename(prefix)); prefix = clean_msdos_filename(msdos_prefix); } for (curpart = 1; curpart <= nparts; curpart++) { int fd_dst; varbuf_reset(&file_dst); /* Generate output filename. */ if (msdos) { char *refname; int prefix_max; m_asprintf(&refname, "%dof%d", curpart, nparts); prefix_max = max(8 - strlen(refname), 0); varbuf_printf(&file_dst, "%s/%.*s%.8s.deb", prefixdir, prefix_max, prefix, refname); free(refname); } else { varbuf_printf(&file_dst, "%s.%dof%d.deb", prefix, curpart, nparts); } if (curpart == nparts) cur_partsize = last_partsize; else cur_partsize = partsize; if (cur_partsize > maxpartsize) { ohshit(_("Header is too long, making part too long. " "Your package name or version\n" "numbers must be extraordinarily long, " "or something. Giving up.\n")); } /* Split the data. */ fd_dst = creat(file_dst.buf, 0644); if (fd_dst < 0) ohshite(_("unable to open file '%s'"), file_dst.buf); /* Write the ar header. */ dpkg_ar_put_magic(file_dst.buf, fd_dst); /* Write the debian-split part. */ varbuf_printf(&partmagic, "%s\n%s\n%s\n%s\n%jd\n%jd\n%d/%d\n%s\n", SPLITVERSION, package, version, hash, (intmax_t)st.st_size, (intmax_t)partsize, curpart, nparts, arch); dpkg_ar_member_put_mem(file_dst.buf, fd_dst, PARTMAGIC, partmagic.buf, partmagic.used); varbuf_reset(&partmagic); /* Write the data part. */ varbuf_printf(&partname, "data.%d", curpart); dpkg_ar_member_put_file(file_dst.buf, fd_dst, partname.buf, fd_src, cur_partsize); varbuf_reset(&partname); close(fd_dst); printf("%d ", curpart); } varbuf_destroy(&file_dst); varbuf_destroy(&partname); varbuf_destroy(&partmagic); free(prefixdir); free(msdos_prefix); close(fd_src); printf(_("done\n")); return 0; }