#include #include #include #include "managerpm.h" #include #include <../../libmodules/filesystem/filesystem.h> #include #include "managerpm.m" static PACKAGES *installed; // Installed package static time_t install_loaded; static int nbuser; // How many owner of the object /* Load the information about the installed packages Reload it if the database has been updated since the last load Return NULL if the packages can't be loaded. */ PACKAGES *api_loadinstalled() { if (installed == NULL){ installed = new PACKAGES; install_loaded = 0; } char oldpath[PATH_MAX],newpath[PATH_MAX]; mngrpm_setpath ("/var/lib/rpm/Packages",newpath,PATH_MAX); mngrpm_setpath ("/var/lib/rpm/packages.rpm",oldpath,PATH_MAX); struct stat st; if (stat(newpath,&st)!=-1 || stat(oldpath,&st)!=-1){ if (st.st_mtime > install_loaded){ installed->remove_all(); installed->loadinstall(); install_loaded = st.st_mtime; } }else{ delete installed; installed = NULL; } nbuser++; return installed; } void api_freeinstalled() { nbuser--; if (nbuser == 0){ delete installed; installed = NULL; }else if (nbuser < 0){ xconf_notice ("api_freeinstalled(): nbuser = %d",nbuser); } } class PACKAGE_API_PRIV: public PACKAGE_API{ public: char *root; PACKAGES *installed; PACKAGE_API_PRIV(){ root = NULL; installed = NULL; } ~PACKAGE_API_PRIV(){ free (root); if (installed != NULL) api_freeinstalled(); } PACKAGES *loadinstalled(); }; /* Load the information about the installed packages Reload it if the database has been updated since the last load Return NULL if the packages can't be loaded. */ PACKAGES *PACKAGE_API_PRIV::loadinstalled() { if (installed == NULL) installed = api_loadinstalled(); return installed; } // A simple object to set/unset the context class ROOTOBJ { public: ROOTOBJ(PACKAGE_API *api){ PACKAGE_API_PRIV *priv = (PACKAGE_API_PRIV*)api; mngrpm_setfsroot (priv->root); }; ~ROOTOBJ(){ mngrpm_setfsroot (NULL); }; }; /* Find one package. ctl is a printf like control string, and arg is its unique %s argument Return NULL if not found. */ static PACKAGE *api_findpkg ( PACKAGES &pkgs, const char *ctl, const char *arg) { char args[PATH_MAX]; snprintf (args,sizeof(args)-1,ctl,arg); pkgs.load (args,true,-1,MSG_R(T_LOADINGPKG)); PACKAGE *ret = NULL; if (pkgs.getnb()==1){ ret = pkgs.getitem(0); } return ret; } static void api_copyversion ( PACKAGE_VERSION &res, PACKAGE *p) { snprintf (res.str,sizeof(res.str)-1,"%s-%s",p->version.get() ,p->release.get()); res.nbelm = p->v.nb; for (int i=0; iv.nb; i++){ res.tb[i].val = p->v.tb[i].num; strcpy (res.tb[i].suffix,p->v.tb[i].suffix); } } /* Return the version of a package. Return -1 if the package is not installed */ static int api_getver ( PACKAGE_API *api, const char *package, PACKAGE_VERSION &res) { ROOTOBJ obj (api); PACKAGES pkgs; PACKAGE *p = api_findpkg (pkgs,"-q %s 2>/dev/null",package); int ret = -1; if (p != NULL){ api_copyversion (res,p); ret = 0; } return ret; } /* Return true if a package is installed */ bool package_is_installed(const char *package) { PACKAGES pkgs; return api_findpkg (pkgs,"-q %s",package) != NULL; } /* Return the version of the RPM utility (300, for 3.0) */ int rpm_version () { static int ret = -1; if (ret == -1){ ret = 300; PACKAGES pkgs; PACKAGE *p = api_findpkg (pkgs,"-q %s","rpm"); if (p != NULL){ ret = p->v.tb[0].num*100 + p->v.tb[1].num; } } return ret; } /* Return 1 if a given package is newer (or equal) than a specific version Return -1 if the package is not installed Return 0 is the package is older. */ static int api_is_newer ( PACKAGE_API *api, const char *package, const char *version) { int ret = -1; ROOTOBJ obj (api); PACKAGES pkgs; PACKAGE *p = api_findpkg (pkgs,"-q %s",package); if (p != NULL){ VERSION_ITEMS ver; mngrpm_parsever (version,ver); ret = package_cmpver (p->v,ver); ret = ret >= 0 ? 1 : 0; } return ret; } /* Identify a package from one of its component (a file path) Return -1 if no package correspond. */ static int api_path2pkg ( PACKAGE_API *api, const char *path, SSTRING &name, PACKAGE_VERSION &res) { ROOTOBJ obj (api); PACKAGES pkgs; PACKAGE *p = api_findpkg (pkgs,"-qf %s",path); int ret = -1; if (p != NULL){ name.setfrom(p->name.get()); api_copyversion (res,p); ret = 0; } return ret; } /* Present some information about a package */ static int api_showinfo ( PACKAGE_API *api, const char *pkg) { ROOTOBJ obj (api); PACKAGES pkgs; PACKAGE *p = api_findpkg (pkgs,"-q %s",pkg); int ret = -1; if (p != NULL){ p->showinfo(); ret = 0; } return ret; } static int api_listfiles ( PACKAGE_API *api, const char *pkg, SSTRINGS &lst) { ROOTOBJ obj (api); SSTRING args; args.setfromf ("-ql %s",pkg); int ret = mngrpm_execrpm (args,lst); if (ret == 0){ ret = lst.getnb(); for (int i=0; istrip_end(); } } return ret; } /* Extract the list of installed packages Return the number of name placed in lst. */ static int api_listinstalled ( PACKAGE_API *api, SSTRINGS &lst) { ROOTOBJ obj(api); PACKAGES *pkgs = ((PACKAGE_API_PRIV*)api)->loadinstalled(); for (int i=0; igetnb(); i++){ PACKAGE *p = pkgs->getitem(i); lst.add (new SSTRING(p->name)); } return pkgs->getnb(); } static int api_installpkgs ( PACKAGE_API *api, const SSTRINGS &names, // Packages to install const char *dir, // Directory where we find these // packages and others (potentially needed) const char *cdtitle) // CD title (ex: rh binary cd number 1) { int ret = -1; SSTRING mpoint; if (filesystem_ismounted(dir,mpoint,cdtitle)){ ROOTOBJ obj (api); PACKAGES *installed = ((PACKAGE_API_PRIV*)api)->loadinstalled(); PACKAGES pkgs; if (installed != NULL && pkgs.loadfromdir (dir,"*.rpm") != -1){ pkgs.unselectall(); SSTRING notfound; for (int i=0; iget(); PACKAGE *p = pkgs.locate(name); if (p == NULL){ notfound.appendf ("%s\n",name); }else{ p->selected = 1; } } if (!notfound.is_empty()){ xconf_error (MSG_U(E_MISSINGPKGS ,"Some packages are missing. Here is the list\n\n%s") ,notfound.get()); }else{ RPM_OPTIONS options; int nbsel = mngrpm_setdefaultupd (*installed,pkgs,false,false,true); #if 0 for (int i=0; iis_selected()) fprintf (stderr,"Selectupd :%s:\n",p->name.get()); } #endif if (nbsel == 0){ ret = 0; xconf_notice (MSG_U(N_NOPKGINST,"No package to install")); }else{ ret = mngrpm_doupdate (pkgs,options,true); } } } filesystem_unmountif(mpoint); } return ret; } static void api_setroot (PACKAGE_API *api, const char *dir) { PACKAGE_API_PRIV *priv = (PACKAGE_API_PRIV*)api; free (priv->root); priv->root = NULL; if (dir != NULL){ priv->root = strdup(dir); } } void *managerpm_api_get () { PACKAGE_API *api = new PACKAGE_API_PRIV; api->getver = api_getver; api->is_newer = api_is_newer; api->path2pkg = api_path2pkg; api->showinfo = api_showinfo; api->installpkgs = api_installpkgs; api->setroot = api_setroot; api->listinstalled = api_listinstalled; api->listfiles = api_listfiles; return api; } void managerpm_api_release (void *obj) { PACKAGE_API *api = (PACKAGE_API*)obj; PACKAGE_API_PRIV *priv = (PACKAGE_API_PRIV*)api; delete priv; }