static void modstatdb_note_core(struct pkginfo *pkg) { assert(cstatus >= msdbrw_write); varbufreset(&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); if (fflush(importanttmp)) ohshite(_("unable to flush updated status of `%.250s'"), pkg->name); if (ftruncate(fileno(importanttmp), uvb.used)) ohshite(_("unable to truncate for updated status of `%.250s'"), pkg->name); if (fsync(fileno(importanttmp))) ohshite(_("unable to fsync updated status of `%.250s'"), pkg->name); if (fclose(importanttmp)) ohshite(_("unable to close updated status of `%.250s'"), pkg->name); sprintf(updatefnrest, IMPORTANTFMT, nextupdate); if (rename(importanttmpfile, updatefnbuf)) ohshite(_("unable to install updated status of `%.250s'"), pkg->name); /* Have we made a real mess? */ assert(strlen(updatefnrest) <= IMPORTANTMAXLEN); nextupdate++; if (nextupdate > MAXUPDATES) { modstatdb_checkpoint(); nextupdate = 0; } createimptmp(); }
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; }
enum modstatdb_rw modstatdb_init(const char *adir, enum modstatdb_rw readwritereq) { const struct fni *fnip; admindir= adir; for (fnip=fnis; fnip->suffix; fnip++) { free(*fnip->store); *fnip->store= m_malloc(strlen(adir)+strlen(fnip->suffix)+2); sprintf(*fnip->store, "%s/%s", adir, fnip->suffix); } cflags= readwritereq & msdbrw_flagsmask; readwritereq &= ~msdbrw_flagsmask; 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(adir,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 { lockdatabase(adir); cstatus= (readwritereq == msdbrw_needsuperuserlockonly ? msdbrw_needsuperuserlockonly : msdbrw_write); } break; case msdbrw_readonly: cstatus= msdbrw_readonly; break; default: internerr("unknown modstatdb_rw '%d'", readwritereq); } updatefnbuf= m_malloc(strlen(adir)+sizeof(UPDATESDIR)+IMPORTANTMAXLEN+5); strcpy(updatefnbuf,adir); strcat(updatefnbuf,"/" UPDATESDIR); updatefnrest= updatefnbuf+strlen(updatefnbuf); if (cstatus != msdbrw_needsuperuserlockonly) { cleanupdates(); if(!(cflags & msdbrw_noavail)) parsedb(availablefile, pdb_recordavailable|pdb_rejectstatus, NULL,NULL,NULL); } if (cstatus >= msdbrw_write) { createimptmp(); varbufinit(&uvb, 10240); } trig_fixup_awaiters(cstatus); trig_incorporate(cstatus, admindir); return cstatus; }