00001 #include "system.h"
00002 const char *__progname;
00003
00004 #include <rpmlib.h>
00005 #include <rpmmacro.h>
00006 #include <rpmurl.h>
00007
00008 #include "rpmdb.h"
00009 #include "rpmps.h"
00010 #include "rpmte.h"
00011 #include "rpmts.h"
00012
00013 #include "manifest.h"
00014 #include "misc.h"
00015 #include "debug.h"
00016
00017 static int _depends_debug;
00018
00019 static int noAvailable = 1;
00020 static const char * avdbpath =
00021 "/usr/lib/rpmdb/%{_arch}-%{_vendor}-%{_os}/redhat";
00022 static int noDeps = 0;
00023
00024 static inline const char * const identifyDepend(int_32 f)
00025
00026 {
00027 if (isLegacyPreReq(f))
00028 return "PreReq:";
00029 f = _notpre(f);
00030 if (f & RPMSENSE_SCRIPT_PRE)
00031 return "Requires(pre):";
00032 if (f & RPMSENSE_SCRIPT_POST)
00033 return "Requires(post):";
00034 if (f & RPMSENSE_SCRIPT_PREUN)
00035 return "Requires(preun):";
00036 if (f & RPMSENSE_SCRIPT_POSTUN)
00037 return "Requires(postun):";
00038 if (f & RPMSENSE_SCRIPT_VERIFY)
00039 return "Requires(verify):";
00040 if (f & RPMSENSE_FIND_REQUIRES)
00041 return "Requires(auto):";
00042 return "Requires:";
00043 }
00044
00045 static int
00046 do_tsort(const char *fileArgv[])
00047 {
00048 rpmts ts = NULL;
00049 const char ** pkgURL = NULL;
00050 char * pkgState = NULL;
00051 const char ** fnp;
00052 const char * fileURL = NULL;
00053 int numPkgs = 0;
00054 int numFailed = 0;
00055 int prevx;
00056 int pkgx;
00057 const char ** argv = NULL;
00058 int argc = 0;
00059 const char ** av = NULL;
00060 int ac = 0;
00061 Header h;
00062 int rc = 0;
00063 int i;
00064
00065 if (fileArgv == NULL)
00066 return 0;
00067
00068 ts = rpmtsCreate();
00069
00070 rc = rpmtsOpenDB(ts, O_RDONLY);
00071 if (rc) {
00072 rpmMessage(RPMMESS_ERROR, _("cannot open Packages database\n"));
00073 rc = -1;
00074 goto exit;
00075 }
00076
00077 #ifdef DYING
00078
00079 if (!(noDeps || noAvailable)) {
00080 rpmdbMatchIterator mi = NULL;
00081 struct rpmdb_s * avdb = NULL;
00082 const char * rootdir = "/";
00083
00084 addMacro(NULL, "_dbpath", NULL, avdbpath, RMIL_CMDLINE);
00085 rc = rpmdbOpen(rootdir, &avdb, O_RDONLY, 0644);
00086 delMacro(NULL, "_dbpath");
00087 if (rc) {
00088 rpmMessage(RPMMESS_ERROR, _("cannot open Available database\n"));
00089 goto endavail;
00090 }
00091 mi = rpmdbInitIterator(avdb, RPMDBI_PACKAGES, NULL, 0);
00092 while ((h = rpmdbNextIterator(mi)) != NULL) {
00093 rpmtsAvailablePackage(ts, h, NULL);
00094 }
00095
00096 endavail:
00097 if (mi) rpmdbFreeIterator(mi);
00098 if (avdb) rpmdbClose(avdb);
00099 }
00100 #endif
00101
00102
00103 for (fnp = fileArgv; *fnp; fnp++) {
00104 av = _free(av);
00105 ac = 0;
00106 rc = rpmGlob(*fnp, &ac, &av);
00107 if (rc || ac == 0) continue;
00108
00109 argv = (argc == 0)
00110 ? xmalloc((argc+2) * sizeof(*argv))
00111 : xrealloc(argv, (argc+2) * sizeof(*argv));
00112 memcpy(argv+argc, av, ac * sizeof(*av));
00113 argc += ac;
00114 argv[argc] = NULL;
00115 }
00116 av = _free(av);
00117
00118 numPkgs = 0;
00119 prevx = 0;
00120 pkgx = 0;
00121
00122 restart:
00123
00124 if (pkgx >= numPkgs) {
00125 numPkgs = pkgx + argc;
00126 pkgURL = (pkgURL == NULL)
00127 ? xmalloc( (numPkgs + 1) * sizeof(*pkgURL))
00128 : xrealloc(pkgURL, (numPkgs + 1) * sizeof(*pkgURL));
00129 memset(pkgURL + pkgx, 0, ((argc + 1) * sizeof(*pkgURL)));
00130 pkgState = (pkgState == NULL)
00131 ? xmalloc( (numPkgs + 1) * sizeof(*pkgState))
00132 : xrealloc(pkgState, (numPkgs + 1) * sizeof(*pkgState));
00133 memset(pkgState + pkgx, 0, ((argc + 1) * sizeof(*pkgState)));
00134 }
00135
00136
00137 for (i = 0; i < argc; i++) {
00138 fileURL = _free(fileURL);
00139 fileURL = argv[i];
00140 argv[i] = NULL;
00141 pkgURL[pkgx] = fileURL;
00142 fileURL = NULL;
00143 pkgx++;
00144 }
00145 fileURL = _free(fileURL);
00146
00147
00148 for (fnp = pkgURL+prevx; *fnp; fnp++, prevx++) {
00149 const char * fileName;
00150 FD_t fd;
00151
00152 (void) urlPath(*fnp, &fileName);
00153
00154
00155 fd = Fopen(*fnp, "r.ufdio");
00156 if (fd == NULL || Ferror(fd)) {
00157 rpmError(RPMERR_OPEN, _("open of %s failed: %s\n"), *fnp,
00158 Fstrerror(fd));
00159 if (fd) Fclose(fd);
00160 numFailed++; *fnp = NULL;
00161 continue;
00162 }
00163
00164 rc = rpmReadPackageFile(ts, fd, *fnp, &h);
00165 Fclose(fd);
00166
00167 if (rc == RPMRC_OK) {
00168 rc = rpmtsAddInstallElement(ts, h, (fnpyKey)fileName, 0, NULL);
00169 h = headerFree(h);
00170 continue;
00171 }
00172
00173 if (rc != RPMRC_NOTFOUND) {
00174 rpmMessage(RPMMESS_ERROR, _("%s cannot be installed\n"), *fnp);
00175 numFailed++; *fnp = NULL;
00176 break;
00177 }
00178
00179
00180 fd = Fopen(*fnp, "r.fpio");
00181 if (fd == NULL || Ferror(fd)) {
00182 rpmError(RPMERR_OPEN, _("open of %s failed: %s\n"), *fnp,
00183 Fstrerror(fd));
00184 if (fd) Fclose(fd);
00185 numFailed++; *fnp = NULL;
00186 break;
00187 }
00188
00189
00190 rc = rpmReadPackageManifest(fd, &argc, &argv);
00191 if (rc)
00192 rpmError(RPMERR_MANIFEST, _("%s: read manifest failed: %s\n"),
00193 fileURL, Fstrerror(fd));
00194 Fclose(fd);
00195
00196
00197 if (rc == 0) {
00198 prevx++;
00199 goto restart;
00200 }
00201
00202 numFailed++; *fnp = NULL;
00203 break;
00204 }
00205
00206 if (numFailed) goto exit;
00207
00208 if (!noDeps) {
00209 rpmps ps;
00210
00211 rc = rpmtsCheck(ts);
00212
00213 ps = rpmtsProblems(ts);
00214 if (ps) {
00215 rpmMessage(RPMMESS_ERROR, _("Failed dependencies:\n"));
00216 rpmpsPrint(NULL, ps);
00217 ps = rpmpsFree(ps);
00218 rc = -1;
00219 goto exit;
00220 }
00221 ps = rpmpsFree(ps);
00222 }
00223
00224 rc = rpmtsOrder(ts);
00225 if (rc)
00226 goto exit;
00227
00228 { rpmtsi pi;
00229 rpmte p;
00230 rpmte q;
00231 unsigned char * selected =
00232 alloca(sizeof(*selected) * (rpmtsNElements(ts) + 1));
00233 int oType = TR_ADDED;
00234
00235 fprintf(stdout, "digraph XXX {\n");
00236
00237 fprintf(stdout, " rankdir=LR\n");
00238
00239 fprintf(stdout, "//===== Packages:\n");
00240 pi = rpmtsiInit(ts);
00241 while ((p = rpmtsiNext(pi, oType)) != NULL) {
00242 fprintf(stdout, "//%5d%5d %s\n", rpmteTree(p), rpmteDepth(p), rpmteN(p));
00243 q = rpmteParent(p);
00244 if (q != NULL)
00245 fprintf(stdout, " \"%s\" -> \"%s\"\n", rpmteN(p), rpmteN(q));
00246 else {
00247 fprintf(stdout, " \"%s\"\n", rpmteN(p));
00248 fprintf(stdout, " { rank=max ; \"%s\" }\n", rpmteN(p));
00249 }
00250 }
00251 pi = rpmtsiFree(pi);
00252
00253 fprintf(stdout, "}\n");
00254
00255 }
00256
00257 rc = 0;
00258
00259 exit:
00260 for (i = 0; i < numPkgs; i++) {
00261 pkgURL[i] = _free(pkgURL[i]);
00262 }
00263 pkgState = _free(pkgState);
00264 pkgURL = _free(pkgURL);
00265 argv = _free(argv);
00266
00267 ts = rpmtsFree(ts);
00268 return rc;
00269 }
00270
00271 static struct poptOption optionsTable[] = {
00272 { "noavailable", '\0', 0, &noAvailable, 0, NULL, NULL},
00273 { "nodeps", '\0', 0, &noDeps, 0, NULL, NULL},
00274 { "verbose", 'v', 0, 0, 'v', NULL, NULL},
00275 { NULL, 0, 0, 0, 0, NULL, NULL}
00276 };
00277
00278 int
00279 main(int argc, const char *argv[])
00280 {
00281 poptContext optCon;
00282 const char * optArg;
00283 int arg;
00284 int ec = 0;
00285
00286 #if HAVE_MCHECK_H && HAVE_MTRACE
00287 mtrace();
00288 #endif
00289 setprogname(argv[0]);
00290 (void)setlocale(LC_ALL, "" );
00291
00292 #ifdef __LCLINT__
00293 #define LOCALEDIR "/usr/share/locale"
00294 #endif
00295 (void)bindtextdomain(PACKAGE, LOCALEDIR);
00296 (void)textdomain(PACKAGE);
00297
00298 _depends_debug = 1;
00299
00300 optCon = poptGetContext("rpmsort", argc, argv, optionsTable, 0);
00301 poptReadDefaultConfig(optCon, 1);
00302
00303 while ((arg = poptGetNextOpt(optCon)) > 0) {
00304 optArg = poptGetOptArg(optCon);
00305 switch (arg) {
00306 case 'v':
00307 rpmIncreaseVerbosity();
00308 break;
00309 default:
00310 fprintf(stderr, _("unknown popt return (%d)"), arg);
00311 exit(EXIT_FAILURE);
00312 break;
00313 }
00314 }
00315
00316 rpmReadConfigFiles(NULL, NULL);
00317
00318 ec = do_tsort(poptGetArgs(optCon));
00319
00320 optCon = poptFreeContext(optCon);
00321
00322 return ec;
00323 }