int dpkg_psys_unregister(const char *vendor, const char *name, psys_err_t *err) { int ret; jmp_buf buf; char *dpkgname; struct pkginfo *dpkg; init_error_handler(err, buf, out); modstatdb_init(ADMINDIR, msdbrw_needsuperuser); dpkgname = dpkg_name(vendor, name); dpkg = findpackage(dpkgname); if (ensure_installed(dpkg, err)) { ret = -1; goto out; } remove_info_files(dpkg); dpkg->want = want_purge; dpkg->status = stat_notinstalled; blankpackageperfile(&dpkg->installed); modstatdb_note(dpkg); ret = 0; out: modstatdb_shutdown(); cleanup(); return ret; }
void getselections(const char *const *argv) { struct pkg_array array; struct pkginfo *pkg; const char *thisarg; int i, found; modstatdb_init(admindir,msdbrw_readonly); pkg_array_init_from_db(&array); pkg_array_sort(&array, pkg_sorter_by_name); if (!*argv) { for (i = 0; i < array.n_pkgs; i++) { pkg = array.pkgs[i]; if (pkg->status == stat_notinstalled) continue; getsel1package(pkg); } } else { while ((thisarg= *argv++)) { found= 0; for (i = 0; i < array.n_pkgs; i++) { pkg = array.pkgs[i]; if (fnmatch(thisarg,pkg->name,0)) continue; getsel1package(pkg); found++; } if (!found) fprintf(stderr,_("No packages found matching %s.\n"),thisarg); } } m_output(stdout, _("<standard output>")); m_output(stderr, _("<standard error>")); pkg_array_destroy(&array); }
static void assert_version_support(const char *const *argv, struct versionrevision *version, const char *feature_name) { struct pkginfo *pkg; if (*argv) badusage(_("--%s takes no arguments"), cipaction->olong); modstatdb_init(admindir,msdbrw_readonly|msdbrw_noavail); pkg = pkg_db_find("dpkg"); switch (pkg->status) { case stat_installed: case stat_triggerspending: break; case stat_unpacked: case stat_halfconfigured: case stat_halfinstalled: case stat_triggersawaited: if (versionsatisfied3(&pkg->configversion, version, dvr_laterequal)) break; printf(_("Version of dpkg with working %s support not yet configured.\n" " Please use 'dpkg --configure dpkg', and then try again.\n"), feature_name); exit(1); default: printf(_("dpkg not recorded as installed, cannot check for %s support!\n"), feature_name); exit(1); } }
enum modstatdb_rw modstatdb_open(enum modstatdb_rw readwritereq) { modstatdb_init(); cflags = readwritereq & msdbrw_available_mask; readwritereq &= ~msdbrw_available_mask; switch (readwritereq) { case msdbrw_needsuperuser: case msdbrw_needsuperuserlockonly: if (getuid() || geteuid()) ohshit(_("requested operation requires superuser privilege")); /* Fall through. */ case msdbrw_write: case msdbrw_writeifposs: if (access(dpkg_db_get_dir(), W_OK)) { if (errno != EACCES) ohshite(_("unable to access dpkg status area")); else if (readwritereq == msdbrw_write) ohshit(_("operation requires read/write access to dpkg status area")); cstatus= msdbrw_readonly; } else { modstatdb_lock(); cstatus= (readwritereq == msdbrw_needsuperuserlockonly ? msdbrw_needsuperuserlockonly : msdbrw_write); } break; case msdbrw_readonly: cstatus= msdbrw_readonly; break; default: internerr("unknown modstatdb_rw '%d'", readwritereq); } dpkg_arch_load_list(); if (cstatus != msdbrw_needsuperuserlockonly) { cleanupdates(); if (cflags >= msdbrw_available_readonly) parsedb(availablefile, pdb_parse_available, NULL); } if (cstatus >= msdbrw_write) { createimptmp(); varbuf_init(&uvb, 10240); } trig_fixup_awaiters(cstatus); trig_incorporate(cstatus); return cstatus; }
/** * @brief Initialize dpkg and load packages into memory */ void dpkg_setup(struct pkg_array *packages) { dpkg_set_progname("osquery"); push_error_context(); dpkg_db_set_dir("/var/lib/dpkg/"); modstatdb_init(); modstatdb_open(msdbrw_readonly); pkg_array_init_from_db(packages); pkg_array_sort(packages, pkg_sorter); }
void clearselections(const char *const *argv) { struct pkgiterator *it; struct pkginfo *pkg; if (*argv) badusage(_("--%s takes no arguments"), cipaction->olong); modstatdb_init(admindir, msdbrw_write); it = pkg_db_iter_new(); while ((pkg = pkg_db_iter_next(it))) { if (!pkg->installed.essential) pkg->want = want_deinstall; } pkg_db_iter_free(it); modstatdb_shutdown(); }
int dpkg_psys_announce(psys_pkg_t pkg, psys_err_t *err) { int ret; jmp_buf buf; char *dpkgname = NULL; struct pkginfo *dpkg; pkg = psys_pkg_copy(pkg); if (!pkg) { psys_err_set_nomem(err); return -1; } psys_pkg_assert_valid(pkg); init_error_handler(err, buf, out); modstatdb_init(ADMINDIR, msdbrw_needsuperuser); dpkgname = dpkg_name(psys_pkg_vendor(pkg), psys_pkg_name(pkg)); dpkg = findpackage(dpkgname); if (ensure_not_installed(dpkg, err)) { ret = -1; goto out; } if (ensure_dependencies_met(pkg, err)) { ret = -1; goto out; } if (ensure_no_conflicting_extras(pkg, err)) { ret = -1; goto out; } ret = 0; out: modstatdb_shutdown(); cleanup(); psys_pkg_free(pkg); return ret; }
int dpkg_psys_register(psys_pkg_t pkg, psys_err_t *err) { int ret; jmp_buf buf; pkg = psys_pkg_copy(pkg); if (!pkg) { psys_err_set_nomem(err); return -1; } psys_pkg_assert_valid(pkg); init_error_handler(err, buf, out); modstatdb_init(ADMINDIR, msdbrw_needsuperuser); ret = do_register(pkg, err, &buf); out: modstatdb_shutdown(); cleanup(); psys_pkg_free(pkg); return ret; }
int dpkg_psys_unannounce(const char *vendor, const char *name, psys_err_t *err) { int ret; jmp_buf buf; char *dpkgname; struct pkginfo *dpkg; init_error_handler(err, buf, out); modstatdb_init(ADMINDIR, msdbrw_needsuperuser); dpkgname = dpkg_name(vendor, name); dpkg = findpackage(dpkgname); if (ensure_installed(dpkg, err)) { ret = -1; goto out; } ret = 0; out: modstatdb_shutdown(); cleanup(); return ret; }
int dpkg_psys_register_update(psys_pkg_t pkg, psys_err_t *err) { int ret; jmp_buf buf; char *dpkgname; struct pkginfo *dpkg; pkg = psys_pkg_copy(pkg); if (!pkg) { psys_err_set_nomem(err); return -1; } psys_pkg_assert_valid(pkg); init_error_handler(err, buf, out); modstatdb_init(ADMINDIR, msdbrw_needsuperuser); dpkgname = dpkg_name(psys_pkg_vendor(pkg), psys_pkg_name(pkg)); dpkg = findpackage(dpkgname); if (ensure_installed(dpkg, err)) { ret = -1; goto out; } if (ensure_version_newer(pkg, dpkg, err)) { ret = -1; goto out; } dpkg->status = stat_notinstalled; ret = do_register(pkg, err, &buf); out: modstatdb_shutdown(); cleanup(); psys_pkg_free(pkg); return ret; }
void audit(const char *const *argv) { const struct badstatinfo *bsi; bool head_running = false; if (*argv) badusage(_("--%s takes no arguments"), cipaction->olong); modstatdb_init(admindir,msdbrw_readonly); for (bsi= badstatinfos; bsi->yesno; bsi++) { struct pkgiterator *it; struct pkginfo *pkg; bool head = false; it = pkg_db_iter_new(); while ((pkg = pkg_db_iter_next(it))) { if (!bsi->yesno(pkg,bsi)) continue; if (!head_running) { if (modstatdb_is_locked(admindir)) puts(_( "Another process has locked the database for writing, and might currently be\n" "modifying it, some of the following problems might just be due to that.\n")); head_running = true; } if (!head) { fputs(gettext(bsi->explanation),stdout); head = true; } describebriefly(pkg); } pkg_db_iter_free(it); if (head) putchar('\n'); } m_output(stdout, _("<standard output>")); }
/** * Print a single package which: * (a) is the target of one or more relevant predependencies. * (b) has itself no unsatisfied pre-dependencies. * * If such a package is present output is the Packages file entry, * which can be massaged as appropriate. * * Exit status: * 0 = a package printed, OK * 1 = no suitable package available * 2 = error */ void predeppackage(const char *const *argv) { static struct varbuf vb; struct pkgiterator *it; struct pkginfo *pkg = NULL, *startpkg, *trypkg; struct dependency *dep; struct deppossi *possi, *provider; if (*argv) badusage(_("--%s takes no arguments"), cipaction->olong); modstatdb_init(admindir,msdbrw_readonly); /* We use clientdata->istobe to detect loops. */ clear_istobes(); dep = NULL; it = pkg_db_iter_new(); while (!dep && (pkg = pkg_db_iter_next(it))) { /* Ignore packages user doesn't want. */ if (pkg->want != want_install) continue; /* Ignore packages not available. */ if (!pkg->files) continue; pkg->clientdata->istobe= itb_preinstall; for (dep= pkg->available.depends; dep; dep= dep->next) { if (dep->type != dep_predepends) continue; if (depisok(dep, &vb, NULL, true)) continue; /* This will leave dep non-NULL, and so exit the loop. */ break; } pkg->clientdata->istobe= itb_normal; /* If dep is NULL we go and get the next package. */ } pkg_db_iter_free(it); if (!dep) exit(1); /* Not found. */ assert(pkg); startpkg= pkg; pkg->clientdata->istobe= itb_preinstall; /* OK, we have found an unsatisfied predependency. * Now go and find the first thing we need to install, as a first step * towards satisfying it. */ do { /* We search for a package which would satisfy dep, and put it in pkg. */ for (possi = dep->list, pkg = NULL; !pkg && possi; possi=possi->next) { trypkg= possi->ed; if (trypkg->files && versionsatisfied(&trypkg->available,possi)) { if (trypkg->clientdata->istobe == itb_normal) { pkg= trypkg; break; } } if (possi->verrel != dvr_none) continue; for (provider=possi->ed->available.depended; !pkg && provider; provider=provider->next) { if (provider->up->type != dep_provides) continue; trypkg= provider->up->up; if (!trypkg->files) continue; if (trypkg->clientdata->istobe == itb_normal) { pkg= trypkg; break; } } } if (!pkg) { varbufreset(&vb); describedepcon(&vb,dep); varbufaddc(&vb,0); fprintf(stderr, _("dpkg: cannot see how to satisfy pre-dependency:\n %s\n"),vb.buf); ohshit(_("cannot satisfy pre-dependencies for %.250s (wanted due to %.250s)"), dep->up->name,startpkg->name); } pkg->clientdata->istobe= itb_preinstall; for (dep= pkg->available.depends; dep; dep= dep->next) { if (dep->type != dep_predepends) continue; if (depisok(dep, &vb, NULL, true)) continue; /* This will leave dep non-NULL, and so exit the loop. */ break; } } while (dep); /* OK, we've found it - pkg has no unsatisfied pre-dependencies! */ writerecord(stdout, _("<standard output>"), pkg, &pkg->available); m_output(stdout, _("<standard output>")); }
void unpackchk(const char *const *argv) { int totalcount, sects; struct sectionentry *sectionentries, *se, **sep; struct pkgiterator *it; struct pkginfo *pkg; const char *thissect; char buf[20]; int width; if (*argv) badusage(_("--%s takes no arguments"), cipaction->olong); modstatdb_init(admindir,msdbrw_readonly|msdbrw_noavail); totalcount= 0; sectionentries = NULL; sects= 0; it = pkg_db_iter_new(); while ((pkg = pkg_db_iter_next(it))) { if (!yettobeunpacked(pkg, &thissect)) continue; for (se= sectionentries; se && strcasecmp(thissect,se->name); se= se->next); if (!se) { se= nfmalloc(sizeof(struct sectionentry)); for (sep= §ionentries; *sep && strcasecmp(thissect,(*sep)->name) > 0; sep= &(*sep)->next); se->name= thissect; se->count= 0; se->next= *sep; *sep= se; sects++; } se->count++; totalcount++; } pkg_db_iter_free(it); if (totalcount == 0) exit(0); if (totalcount <= 12) { it = pkg_db_iter_new(); while ((pkg = pkg_db_iter_next(it))) { if (!yettobeunpacked(pkg, NULL)) continue; describebriefly(pkg); } pkg_db_iter_free(it); } else if (sects <= 12) { for (se= sectionentries; se; se= se->next) { sprintf(buf,"%d",se->count); printf(_(" %d in %s: "),se->count,se->name); width= 70-strlen(se->name)-strlen(buf); while (width > 59) { putchar(' '); width--; } it = pkg_db_iter_new(); while ((pkg = pkg_db_iter_next(it))) { if (!yettobeunpacked(pkg,&thissect)) continue; if (strcasecmp(thissect,se->name)) continue; width -= strlen(pkg->name); width--; if (width < 4) { printf(" ..."); break; } printf(" %s",pkg->name); } pkg_db_iter_free(it); putchar('\n'); } } else { printf(P_(" %d package, from the following section:", " %d packages, from the following sections:", totalcount), totalcount); width= 0; for (se= sectionentries; se; se= se->next) { sprintf(buf,"%d",se->count); width -= (6 + strlen(se->name) + strlen(buf)); if (width < 0) { putchar('\n'); width= 73 - strlen(se->name) - strlen(buf); } printf(" %s (%d)",se->name,se->count); } putchar('\n'); } m_output(stdout, _("<standard output>")); }
void archivefiles(const char *const *argv) { const char *volatile thisarg; const char *const *volatile argp; jmp_buf ejbuf; int pi[2], fc, nfiles, c, i, r; FILE *pf; static struct varbuf findoutput; const char **arglist; char *p; trigproc_install_hooks(); modstatdb_init(admindir, f_noact ? msdbrw_readonly : cipaction->arg == act_avail ? msdbrw_write : fc_nonroot ? msdbrw_write : msdbrw_needsuperuser); checkpath(); log_message("startup archives %s", cipaction->olong); if (f_recursive) { if (!*argv) badusage(_("--%s --recursive needs at least one path argument"),cipaction->olong); m_pipe(pi); fc = subproc_fork(); if (!fc) { struct command cmd; const char *const *ap; m_dup2(pi[1],1); close(pi[0]); close(pi[1]); command_init(&cmd, FIND, _("find for dpkg --recursive")); command_add_args(&cmd, FIND, "-L", NULL); for (ap = argv; *ap; ap++) { if (strchr(FIND_EXPRSTARTCHARS,(*ap)[0])) { char *a; a= m_malloc(strlen(*ap)+10); strcpy(a,"./"); strcat(a,*ap); command_add_arg(&cmd, a); } else { command_add_arg(&cmd, (const char *)*ap); } } command_add_args(&cmd, "-name", "*.deb", "-type", "f", "-print0", NULL); command_exec(&cmd); } close(pi[1]); nfiles= 0; pf= fdopen(pi[0],"r"); if (!pf) ohshite(_("failed to fdopen find's pipe")); varbufreset(&findoutput); while ((c= fgetc(pf)) != EOF) { varbufaddc(&findoutput,c); if (!c) nfiles++; } if (ferror(pf)) ohshite(_("error reading find's pipe")); if (fclose(pf)) ohshite(_("error closing find's pipe")); r = subproc_wait_check(fc, "find", PROCNOERR); if (r != 0) ohshit(_("find for --recursive returned unhandled error %i"),r); if (!nfiles) ohshit(_("searched, but found no packages (files matching *.deb)")); varbufaddc(&findoutput,0); varbufaddc(&findoutput,0); arglist= m_malloc(sizeof(char*)*(nfiles+1)); p= findoutput.buf; i=0; while (*p) { arglist[i++]= p; while (*p++ != '\0') ; } arglist[i] = NULL; argp= arglist; } else { if (!*argv) badusage(_("--%s needs at least one package archive file argument"), cipaction->olong); argp= argv; } currenttime = time(NULL); /* Initialize fname variables contents. */ varbufreset(&fnamevb); varbufreset(&fnametmpvb); varbufreset(&fnamenewvb); varbufaddstr(&fnamevb,instdir); varbufaddc(&fnamevb,'/'); varbufaddstr(&fnametmpvb,instdir); varbufaddc(&fnametmpvb,'/'); varbufaddstr(&fnamenewvb,instdir); varbufaddc(&fnamenewvb,'/'); fnameidlu= fnamevb.used; ensure_diversions(); ensure_statoverrides(); while ((thisarg = *argp++) != NULL) { if (setjmp(ejbuf)) { pop_error_context(ehflag_bombout); if (abort_processing) break; continue; } push_error_context_jump(&ejbuf, print_error_perpackage, thisarg); process_archive(thisarg); onerr_abort++; m_output(stdout, _("<standard output>")); m_output(stderr, _("<standard error>")); onerr_abort--; pop_error_context(ehflag_normaltidy); } switch (cipaction->arg) { case act_install: case act_configure: case act_triggers: case act_remove: case act_purge: process_queue(); case act_unpack: case act_avail: break; default: internerr("unknown action '%d'", cipaction->arg); } trigproc_run_deferred(); modstatdb_shutdown(); }
void setselections(const char *const *argv) { const struct namevalue *nvp; struct pkginfo *pkg; const char *e; int c, lno; struct varbuf namevb = VARBUF_INIT; struct varbuf selvb = VARBUF_INIT; if (*argv) badusage(_("--%s takes no arguments"), cipaction->olong); modstatdb_init(admindir,msdbrw_write); lno= 1; for (;;) { varbufreset(&namevb); varbufreset(&selvb); do { c= getchar(); if (c == '\n') lno++; } while (c != EOF && isspace(c)); if (c == EOF) break; if (c == '#') { do { c= getchar(); if (c == '\n') lno++; } while (c != EOF && c != '\n'); continue; } while (!isspace(c)) { varbufaddc(&namevb,c); c= getchar(); if (c == EOF) ohshit(_("unexpected eof in package name at line %d"),lno); if (c == '\n') ohshit(_("unexpected end of line in package name at line %d"),lno); } while (c != EOF && isspace(c)) { c= getchar(); if (c == EOF) ohshit(_("unexpected eof after package name at line %d"),lno); if (c == '\n') ohshit(_("unexpected end of line after package name at line %d"),lno); } while (c != EOF && !isspace(c)) { varbufaddc(&selvb,c); c= getchar(); } while (c != EOF && c != '\n') { c= getchar(); if (!isspace(c)) ohshit(_("unexpected data after package and selection at line %d"),lno); } varbufaddc(&namevb,0); varbufaddc(&selvb,0); e = pkg_name_is_illegal(namevb.buf, NULL); if (e) ohshit(_("illegal package name at line %d: %.250s"),lno,e); nvp = namevalue_find_by_name(wantinfos, selvb.buf); if (nvp == NULL) ohshit(_("unknown wanted status at line %d: %.250s"), lno, selvb.buf); pkg = pkg_db_find(namevb.buf); pkg->want= nvp->value; if (c == EOF) break; lno++; } if (ferror(stdin)) ohshite(_("read error on standard input")); modstatdb_shutdown(); varbuf_destroy(&namevb); varbuf_destroy(&selvb); }
int updateavailable(const char *const *argv) { const char *sourcefile= argv[0]; char *availfile; int count= 0; modstatdb_init(); switch (cipaction->arg_int) { case act_avclear: if (sourcefile) badusage(_("--%s takes no arguments"),cipaction->olong); break; case act_avreplace: case act_avmerge: if (!sourcefile || argv[1]) badusage(_("--%s needs exactly one Packages-file argument"), cipaction->olong); break; default: internerr("unknown action '%d'", cipaction->arg_int); } if (!f_noact) { if (access(dpkg_db_get_dir(), W_OK)) { if (errno != EACCES) ohshite(_("unable to access dpkg status area for bulk available update")); else ohshit(_("bulk available update requires write access to dpkg status area")); } modstatdb_lock(); } switch (cipaction->arg_int) { case act_avreplace: printf(_("Replacing available packages info, using %s.\n"),sourcefile); break; case act_avmerge: printf(_("Updating available packages info, using %s.\n"),sourcefile); break; case act_avclear: break; default: internerr("unknown action '%d'", cipaction->arg_int); } availfile = dpkg_db_get_path(AVAILFILE); if (cipaction->arg_int == act_avmerge) parsedb(availfile, pdb_parse_available, NULL); if (cipaction->arg_int != act_avclear) count += parsedb(sourcefile, pdb_parse_available | pdb_ignoreolder, NULL); if (!f_noact) { writedb(availfile, wdb_dump_available); modstatdb_unlock(); } free(availfile); if (cipaction->arg_int != act_avclear) printf(P_("Information about %d package was updated.\n", "Information about %d packages was updated.\n", count), count); modstatdb_done(); return 0; }