libzypp  13.10.6
librpmDb.cv3.cc
Go to the documentation of this file.
1 /*---------------------------------------------------------------------\
2 | ____ _ __ __ ___ |
3 | |__ / \ / / . \ . \ |
4 | / / \ V /| _/ _/ |
5 | / /__ | | | | | | |
6 | /_____||_| |_| |_| |
7 | |
8 \---------------------------------------------------------------------*/
12 #if 0
13 #include "librpm.h"
14 extern "C"
15 {
16 #ifdef _RPM_5
17 typedef rpmuint32_t rpm_count_t;
18 #define HGEPtr_t void *
19 #define headerGetEntryMinMemory headerGetEntry
20 #define headerNVR(h,n,v,r) headerNEVRA(h,n,NULL,v,r,NULL)
21 #else
22 #ifdef _RPM_4_4
23 typedef int32_t rpm_count_t;
24 #define HGEPtr_t const void *
25 #endif
26 #endif
27 }
28 
29 #include <iostream>
30 
31 #include "zypp/base/Logger.h"
32 
35 #include "zypp/ZYppCallbacks.h"
36 
37 #define xmalloc malloc
38 #define xstrdup strdup
39 
40 extern "C"
41 {
42 #include <string.h>
43 
44 #define FA_MAGIC 0x02050920
45 
46  struct faFileHeader
47  {
48  unsigned int magic;
49  unsigned int firstFree;
50  };
51 
52  struct faHeader
53  {
54  unsigned int size;
55  unsigned int freeNext; /* offset of the next free block, 0 if none */
56  unsigned int freePrev;
57  unsigned int isFree;
58 
59  /* note that the u16's appear last for alignment/space reasons */
60  };
61 }
62 
63 namespace zypp
64 {
65 namespace target
66 {
67 namespace rpm
68 {
69 static int fadFileSize;
70 
71 static ssize_t Pread(FD_t fd, void * buf, size_t count, off_t offset)
72 {
73  if (Fseek(fd, offset, SEEK_SET) < 0)
74  return -1;
75  return Fread(buf, sizeof(char), count, fd);
76 }
77 
78 static FD_t fadOpen(const char * path)
79 {
80  struct faFileHeader newHdr;
81  FD_t fd;
82  struct stat stb;
83 
84  fd = Fopen(path, "r.fdio");
85  if (!fd || Ferror(fd))
86  return NULL;
87 
88  if (fstat(Fileno(fd), &stb))
89  {
90  Fclose(fd);
91  return NULL;
92  }
93  fadFileSize = stb.st_size;
94 
95  /* is this file brand new? */
96  if (fadFileSize == 0)
97  {
98  Fclose(fd);
99  return NULL;
100  }
101  if (Pread(fd, &newHdr, sizeof(newHdr), 0) != sizeof(newHdr))
102  {
103  Fclose(fd);
104  return NULL;
105  }
106  if (newHdr.magic != FA_MAGIC)
107  {
108  Fclose(fd);
109  return NULL;
110  }
111  /*@-refcounttrans@*/ return fd /*@=refcounttrans@*/ ;
112 }
113 
114 static int fadNextOffset(FD_t fd, unsigned int lastOffset)
115 {
116  struct faHeader header;
117  int offset;
118 
119  offset = (lastOffset)
120  ? (lastOffset - sizeof(header))
121  : sizeof(struct faFileHeader);
122 
123  if (offset >= fadFileSize)
124  return 0;
125 
126  if (Pread(fd, &header, sizeof(header), offset) != sizeof(header))
127  return 0;
128 
129  if (!lastOffset && !header.isFree)
130  return (offset + sizeof(header));
131 
132  do
133  {
134  offset += header.size;
135 
136  if (Pread(fd, &header, sizeof(header), offset) != sizeof(header))
137  return 0;
138 
139  if (!header.isFree) break;
140  }
141  while (offset < fadFileSize && header.isFree);
142 
143  if (offset < fadFileSize)
144  {
145  /* Sanity check this to make sure we're not going in loops */
146  offset += sizeof(header);
147 
148  if (offset < 0 || (unsigned)offset <= lastOffset) return -1;
149 
150  return offset;
151  }
152  else
153  return 0;
154 }
155 
156 static int fadFirstOffset(FD_t fd)
157 {
158  return fadNextOffset(fd, 0);
159 }
160 
161 /*@-boundsread@*/
162 static int dncmp(const void * a, const void * b)
163 /*@*/
164 {
165  const char *const * first = (const char *const *)a;
166  const char *const * second = (const char *const *)b;
167  return strcmp(*first, *second);
168 }
169 /*@=boundsread@*/
170 
171 /*@-bounds@*/
172 #ifndef _RPM_4_X
173 static void compressFilelist(Header h)
174 /*@*/
175 {
176  char ** fileNames;
177  const char ** dirNames;
178  const char ** baseNames;
179  int_32 * dirIndexes;
180  rpmTagType fnt;
181  rpm_count_t count;
182  int xx;
183  int dirIndex = -1;
184 
185  /*
186  * This assumes the file list is already sorted, and begins with a
187  * single '/'. That assumption isn't critical, but it makes things go
188  * a bit faster.
189  */
190 
191  if (headerIsEntry(h, RPMTAG_DIRNAMES))
192  {
193  xx = headerRemoveEntry(h, RPMTAG_OLDFILENAMES);
194  return; /* Already converted. */
195  }
196 
197  HGEPtr_t hgePtr = NULL;
198  if (!headerGetEntryMinMemory(h, RPMTAG_OLDFILENAMES, hTYP_t(&fnt), &hgePtr, &count))
199  return; /* no file list */
200  fileNames = (char **)hgePtr;
201  if (fileNames == NULL || count <= 0)
202  return;
203 
204  dirNames = (const char **)alloca(sizeof(*dirNames) * count); /* worst case */
205  baseNames = (const char **)alloca(sizeof(*dirNames) * count);
206  dirIndexes = (int_32 *)alloca(sizeof(*dirIndexes) * count);
207 
208  if (fileNames[0][0] != '/')
209  {
210  /* HACK. Source RPM, so just do things differently */
211  dirIndex = 0;
212  dirNames[dirIndex] = "";
213  for (rpm_count_t i = 0; i < count; i++)
214  {
215  dirIndexes[i] = dirIndex;
216  baseNames[i] = fileNames[i];
217  }
218  goto exit;
219  }
220 
221  /*@-branchstate@*/
222  for (rpm_count_t i = 0; i < count; i++)
223  {
224  const char ** needle;
225  char savechar;
226  char * baseName;
227  int len;
228 
229  if (fileNames[i] == NULL) /* XXX can't happen */
230  continue;
231  baseName = strrchr(fileNames[i], '/') + 1;
232  len = baseName - fileNames[i];
233  needle = dirNames;
234  savechar = *baseName;
235  *baseName = '\0';
236  /*@-compdef@*/
237  if (dirIndex < 0 ||
238  (needle = (const char **)bsearch(&fileNames[i], dirNames, dirIndex + 1, sizeof(dirNames[0]), dncmp)) == NULL)
239  {
240  char *s = (char *)alloca(len + 1);
241  memcpy(s, fileNames[i], len + 1);
242  s[len] = '\0';
243  dirIndexes[i] = ++dirIndex;
244  dirNames[dirIndex] = s;
245  }
246  else
247  dirIndexes[i] = needle - dirNames;
248  /*@=compdef@*/
249 
250  *baseName = savechar;
251  baseNames[i] = baseName;
252  }
253  /*@=branchstate@*/
254 
255 exit:
256  if (count > 0)
257  {
258  xx = headerAddEntry(h, RPMTAG_DIRINDEXES, RPM_INT32_TYPE, dirIndexes, count);
259  xx = headerAddEntry(h, RPMTAG_BASENAMES, RPM_STRING_ARRAY_TYPE,
260  baseNames, count);
261  xx = headerAddEntry(h, RPMTAG_DIRNAMES, RPM_STRING_ARRAY_TYPE,
262  dirNames, dirIndex + 1);
263  }
264 
265  fileNames = (char**)headerFreeData(fileNames, fnt);
266 
267  xx = headerRemoveEntry(h, RPMTAG_OLDFILENAMES);
268 }
269 /*@=bounds@*/
270 
271 /*
272  * Up to rpm 3.0.4, packages implicitly provided their own name-version-release.
273  * Retrofit an explicit "Provides: name = epoch:version-release".
274  */
275 void providePackageNVR(Header h)
276 {
277  const char *name, *version, *release;
278  HGEPtr_t hgePtr = NULL;
279  int_32 * epoch;
280  const char *pEVR;
281  char *p;
282  int_32 pFlags = RPMSENSE_EQUAL;
283  const char ** provides = NULL;
284  const char ** providesEVR = NULL;
285  rpmTagType pnt, pvt;
286  int_32 * provideFlags = NULL;
287  rpm_count_t providesCount;
288  int xx;
289  int bingo = 1;
290 
291  /* Generate provides for this package name-version-release. */
292  xx = headerNVR(h, &name, &version, &release);
293  if (!(name && version && release))
294  return;
295  pEVR = p = (char *)alloca(21 + strlen(version) + 1 + strlen(release) + 1);
296  *p = '\0';
297  if (headerGetEntryMinMemory(h, RPMTAG_EPOCH, NULL, &hgePtr, NULL))
298  {
299  epoch = (int_32 *)hgePtr;
300  sprintf(p, "%d:", *epoch);
301  while (*p != '\0')
302  p++;
303  }
304  (void) stpcpy( stpcpy( stpcpy(p, version) , "-") , release);
305 
306  /*
307  * Rpm prior to 3.0.3 does not have versioned provides.
308  * If no provides at all are available, we can just add.
309  */
310  if (!headerGetEntryMinMemory(h, RPMTAG_PROVIDENAME, hTYP_t(&pnt), &hgePtr, &providesCount))
311  goto exit;
312  provides = (const char **)hgePtr;
313 
314  /*
315  * Otherwise, fill in entries on legacy packages.
316  */
317  if (!headerGetEntryMinMemory(h, RPMTAG_PROVIDEVERSION, hTYP_t(&pvt), &hgePtr, NULL))
318  {
319  providesEVR = (const char **)hgePtr;
320  for (rpm_count_t i = 0; i < providesCount; i++)
321  {
322  const char * vdummy = "";
323  int_32 fdummy = RPMSENSE_ANY;
324  xx = headerAddOrAppendEntry(h, RPMTAG_PROVIDEVERSION, RPM_STRING_ARRAY_TYPE,
325  &vdummy, 1);
326  xx = headerAddOrAppendEntry(h, RPMTAG_PROVIDEFLAGS, RPM_INT32_TYPE,
327  &fdummy, 1);
328  }
329  goto exit;
330  }
331 
332  xx = headerGetEntryMinMemory(h, RPMTAG_PROVIDEFLAGS, NULL, &hgePtr, NULL);
333  provideFlags = (int_32 *)hgePtr;
334 
335  /*@-nullderef@*/ /* LCL: providesEVR is not NULL */
336  if (provides && providesEVR && provideFlags)
337  for (rpm_count_t i = 0; i < providesCount; i++)
338  {
339  if (!(provides[i] && providesEVR[i]))
340  continue;
341  if (!(provideFlags[i] == RPMSENSE_EQUAL &&
342  !strcmp(name, provides[i]) && !strcmp(pEVR, providesEVR[i])))
343  continue;
344  bingo = 0;
345  break;
346  }
347  /*@=nullderef@*/
348 
349 exit:
350  provides = (const char **)headerFreeData(provides, pnt);
351  providesEVR = (const char **)headerFreeData(providesEVR, pvt);
352 
353  if (bingo)
354  {
355  xx = headerAddOrAppendEntry(h, RPMTAG_PROVIDENAME, RPM_STRING_ARRAY_TYPE,
356  &name, 1);
357  xx = headerAddOrAppendEntry(h, RPMTAG_PROVIDEFLAGS, RPM_INT32_TYPE,
358  &pFlags, 1);
359  xx = headerAddOrAppendEntry(h, RPMTAG_PROVIDEVERSION, RPM_STRING_ARRAY_TYPE,
360  &pEVR, 1);
361  }
362 }
363 #else
364 static void compressFilelist(Header h)
365 {
366  struct rpmtd_s fileNames;
367  char ** dirNames;
368  const char ** baseNames;
369  uint32_t * dirIndexes;
370  rpm_count_t count;
371  int xx, i;
372  int dirIndex = -1;
373 
374  /*
375  * This assumes the file list is already sorted, and begins with a
376  * single '/'. That assumption isn't critical, but it makes things go
377  * a bit faster.
378  */
379 
380  if (headerIsEntry(h, RPMTAG_DIRNAMES)) {
381  xx = headerDel(h, RPMTAG_OLDFILENAMES);
382  return; /* Already converted. */
383  }
384 
385  if (!headerGet(h, RPMTAG_OLDFILENAMES, &fileNames, HEADERGET_MINMEM))
386  return;
387  count = rpmtdCount(&fileNames);
388  if (count < 1)
389  return;
390 
391  dirNames = (char**)malloc(sizeof(*dirNames) * count); /* worst case */
392  baseNames = (const char**)malloc(sizeof(*dirNames) * count);
393  dirIndexes = (uint32_t*)malloc(sizeof(*dirIndexes) * count);
394 
395  /* HACK. Source RPM, so just do things differently */
396  { const char *fn = rpmtdGetString(&fileNames);
397  if (fn && *fn != '/') {
398  dirIndex = 0;
399  dirNames[dirIndex] = xstrdup("");
400  while ((i = rpmtdNext(&fileNames)) >= 0) {
401  dirIndexes[i] = dirIndex;
402  baseNames[i] = rpmtdGetString(&fileNames);
403  }
404  goto exit;
405  }
406  }
407 
408  while ((i = rpmtdNext(&fileNames)) >= 0) {
409  char ** needle;
410  char savechar;
411  char * baseName;
412  size_t len;
413  const char *filename = rpmtdGetString(&fileNames);
414 
415  if (filename == NULL) /* XXX can't happen */
416  continue;
417  baseName = strrchr((char*)filename, '/') + 1;
418  len = baseName - filename;
419  needle = dirNames;
420  savechar = *baseName;
421  *baseName = '\0';
422  if (dirIndex < 0 ||
423  (needle = (char**)bsearch(&filename, dirNames, dirIndex + 1, sizeof(dirNames[0]), dncmp)) == NULL) {
424  char *s = (char*)malloc(len + 1);
425  rstrlcpy(s, filename, len + 1);
426  dirIndexes[i] = ++dirIndex;
427  dirNames[dirIndex] = s;
428  } else
429  dirIndexes[i] = needle - dirNames;
430 
431  *baseName = savechar;
432  baseNames[i] = baseName;
433  }
434 
435 exit:
436  if (count > 0) {
437  headerPutUint32(h, RPMTAG_DIRINDEXES, dirIndexes, count);
438  headerPutStringArray(h, RPMTAG_BASENAMES, baseNames, count);
439  headerPutStringArray(h, RPMTAG_DIRNAMES,
440  (const char **) dirNames, dirIndex + 1);
441  }
442 
443  rpmtdFreeData(&fileNames);
444  for (i = 0; i <= dirIndex; i++) {
445  free(dirNames[i]);
446  }
447  free(dirNames);
448  free(baseNames);
449  free(dirIndexes);
450 
451  xx = headerDel(h, RPMTAG_OLDFILENAMES);
452 }
453 
454 /*
455  * Up to rpm 3.0.4, packages implicitly provided their own name-version-release.
456  * Retrofit an explicit "Provides: name = epoch:version-release.
457  */
458 static void providePackageNVR(Header h)
459 {
460  const char *name;
461  char *pEVR;
462  rpmsenseFlags pFlags = RPMSENSE_EQUAL;
463  int bingo = 1;
464  struct rpmtd_s pnames;
465  rpmds hds, nvrds;
466 
467  /* Generate provides for this package name-version-release. */
468  pEVR = headerGetEVR(h, &name);
469  if (!(name && pEVR))
470  return;
471 
472  /*
473  * Rpm prior to 3.0.3 does not have versioned provides.
474  * If no provides at all are available, we can just add.
475  */
476  if (!headerGet(h, RPMTAG_PROVIDENAME, &pnames, HEADERGET_MINMEM)) {
477  goto exit;
478  }
479 
480  /*
481  * Otherwise, fill in entries on legacy packages.
482  */
483  if (!headerIsEntry(h, RPMTAG_PROVIDEVERSION)) {
484  while (rpmtdNext(&pnames) >= 0) {
485  uint32_t fdummy = RPMSENSE_ANY;
486 
487  headerPutString(h, RPMTAG_PROVIDEVERSION, "");
488  headerPutUint32(h, RPMTAG_PROVIDEFLAGS, &fdummy, 1);
489  }
490  goto exit;
491  }
492 
493  /* see if we already have this provide */
494  hds = rpmdsNew(h, RPMTAG_PROVIDENAME, 0);
495  nvrds = rpmdsSingle(RPMTAG_PROVIDENAME, name, pEVR, pFlags);
496  if (rpmdsFind(hds, nvrds) >= 0) {
497  bingo = 0;
498  }
499  rpmdsFree(hds);
500  rpmdsFree(nvrds);
501 
502 exit:
503  if (bingo) {
504  const char *evr = pEVR;
505  uint32_t fdummy = pFlags;
506  headerPutString(h, RPMTAG_PROVIDENAME, name);
507  headerPutString(h, RPMTAG_PROVIDEVERSION, evr);
508  headerPutUint32(h, RPMTAG_PROVIDEFLAGS, &fdummy, 1);
509  }
510  rpmtdFreeData(&pnames);
511  free(pEVR);
512 }
513 
514 #endif
515 
519 
520 using namespace std;
521 
522 #undef Y2LOG
523 #define Y2LOG "librpmDb"
524 
525 /******************************************************************
526 **
527 **
528 ** FUNCTION NAME : internal_convertV3toV4
529 ** FUNCTION TYPE : int
530 */
531 void internal_convertV3toV4( const Pathname & v3db_r, const librpmDb::constPtr & v4db_r,
532  callback::SendReport<ConvertDBReport> & report )
533 {
534 // Timecount _t( "convert V3 to V4" );
535  MIL << "Convert rpm3 database to rpm4" << endl;
536 
537  // Check arguments
538  FD_t fd = fadOpen( v3db_r.asString().c_str() );
539  if ( fd == 0 )
540  {
541  Fclose( fd );
542  ZYPP_THROW(RpmDbOpenException(Pathname("/"), v3db_r));
543  }
544 
545  if ( ! v4db_r )
546  {
547  Fclose( fd );
548  INT << "NULL rpmV4 database passed as argument!" << endl;
549  ZYPP_THROW(RpmNullDatabaseException());
550  }
551 
552  shared_ptr<RpmException> err = v4db_r->error();
553  if ( err )
554  {
555  Fclose( fd );
556  INT << "Can't access rpmV4 database " << v4db_r << endl;
557  ZYPP_THROW(*err);
558  }
559 
560  // open rpmV4 database for writing. v4db_r is ok so librpm should
561  // be properly initialized.
562  rpmdb db = 0;
563  string rootstr( v4db_r->root().asString() );
564  const char * root = ( rootstr == "/" ? NULL : rootstr.c_str() );
565 
566  int res = ::rpmdbOpen( root, &db, O_RDWR, 0644 );
567  if ( res || ! db )
568  {
569  if ( db )
570  {
571  ::rpmdbClose( db );
572  }
573  Fclose( fd );
574  ZYPP_THROW(RpmDbOpenException(root, v4db_r->dbPath()));
575  }
576 
577  // Check ammount of packages to process.
578  int max = 0;
579  for ( int offset = fadFirstOffset(fd); offset; offset = fadNextOffset(fd, offset) )
580  {
581  ++max;
582  }
583  MIL << "Packages in rpmV3 database " << v3db_r << ": " << max << endl;
584 
585  unsigned failed = 0;
586  unsigned ignored = 0;
587  unsigned alreadyInV4 = 0;
588  report->progress( (100 * (failed + ignored + alreadyInV4) / max), v3db_r );
589 
590  if ( !max )
591  {
592  Fclose( fd );
593  ::rpmdbClose( db );
594  return;
595  }
596 
597  // Start conversion.
598 #warning Add CBSuggest handling if needed, also on lines below
599 // CBSuggest proceed;
600  bool proceed = true;
601  for ( int offset = fadFirstOffset(fd); offset && proceed ;
602  offset = fadNextOffset(fd, offset),
603  report->progress( (100 * (failed + ignored + alreadyInV4) / max), v3db_r ) )
604  {
605 
606  // have to use lseek instead of Fseek because headerRead
607  // uses low level IO
608  if ( lseek( Fileno( fd ), (off_t)offset, SEEK_SET ) == -1 )
609  {
610  ostream * reportAs = &(ERR);
611  /* proceed = report->dbReadError( offset );
612  if ( proceed == CBSuggest::SKIP ) {
613  // ignore this error
614  ++ignored;
615  reportAs = &(WAR << "IGNORED: ");
616  } else {*/
617  // PROCEED will fail after conversion; CANCEL immediately stop loop
618  ++failed;
619 // }
620  (*reportAs) << "rpmV3 database entry: Can't seek to offset " << offset << " (errno " << errno << ")" << endl;
621  continue;
622  }
623  Header h = headerRead(fd, HEADER_MAGIC_NO);
624  if ( ! h )
625  {
626  ostream * reportAs = &(ERR);
627  /* proceed = report->dbReadError( offset );
628  if ( proceed == CBSuggest::SKIP ) {
629  // ignore this error
630  ++ignored;
631  reportAs = &(WAR << "IGNORED: ");
632  } else {*/
633  // PROCEED will fail after conversion; CANCEL immediately stop loop
634  ++failed;
635 // }
636  (*reportAs) << "rpmV3 database entry: No header at offset " << offset << endl;
637  continue;
638  }
639  compressFilelist(h);
640  providePackageNVR(h);
641  const char *name = 0;
642  const char *version = 0;
643  const char *release = 0;
644  headerNVR(h, &name, &version, &release);
645  string nrv( string(name) + "-" + version + "-" + release );
646  rpmdbMatchIterator mi = rpmdbInitIterator(db, RPMTAG_NAME, name, 0);
647  rpmdbSetIteratorRE(mi, RPMTAG_VERSION, RPMMIRE_DEFAULT, version);
648  rpmdbSetIteratorRE(mi, RPMTAG_RELEASE, RPMMIRE_DEFAULT, release);
649  if (rpmdbNextIterator(mi))
650  {
651 // report.dbInV4( nrv );
652  WAR << "SKIP: rpmV3 database entry: " << nrv << " is already in rpmV4 database" << endl;
653  rpmdbFreeIterator(mi);
654  headerFree(h);
655  ++alreadyInV4;
656  continue;
657  }
658  rpmdbFreeIterator(mi);
659 #ifdef _RPM_5
660  if (rpmdbAdd(db, -1, h, 0))
661 #else
662  if (rpmdbAdd(db, -1, h, 0, 0))
663 #endif
664  {
665 // report.dbWriteError( nrv );
666  proceed = false;//CBSuggest::CANCEL; // immediately stop loop
667  ++failed;
668  ERR << "rpmV4 database error: could not add " << nrv << " to rpmV4 database" << endl;
669  headerFree(h);
670  continue;
671  }
672  headerFree(h);
673  }
674 
675  Fclose(fd);
676  ::rpmdbClose(db);
677 
678  if ( failed )
679  {
680  ERR << "Convert rpm3 database to rpm4: Aborted after "
681  << alreadyInV4 << " package(s) and " << (failed+ignored) << " error(s)."
682  << endl;
683  ZYPP_THROW(RpmDbConvertException());
684  }
685  else
686  {
687  MIL << "Convert rpm3 database to rpm4: " << max << " package(s) processed";
688  if ( alreadyInV4 )
689  {
690  MIL << "; " << alreadyInV4 << " already present in rpmV4 database";
691  }
692  if ( ignored )
693  {
694  MIL << "; IGNORED: " << ignored << " unconverted due to error";
695  }
696  MIL << endl;
697  }
698 }
699 #endif
700 
701 #include <iostream>
702 
703 #include "zypp/base/Logger.h"
704 
707 #include "zypp/ZYppCallbacks.h"
708 
709 using namespace std;
710 
711 #undef Y2LOG
712 #define Y2LOG "librpmDb"
713 
714 namespace zypp
715 {
716 namespace target
717 {
718 namespace rpm
719 {
720 /******************************************************************
721 *
722 *
723 * FUNCTION NAME : convertV3toV4
724 *
725 * \throws RpmException
726 *
727 */
728 void convertV3toV4( const Pathname & v3db_r, const librpmDb::constPtr & v4db_r )
729 {
730  // report
732  report->start(v3db_r);
733  try
734  {
735  // Does no longer work with rpm 4.9.
736  // internal_convertV3toV4( v3db_r, v4db_r, report );
737  INT << "Unsupported: Convert rpm3 database to rpm4" << endl;
738  ZYPP_THROW(RpmDbOpenException(Pathname("/"), v3db_r));
739  }
740  catch (RpmException & excpt_r)
741  {
742  report->finish(v3db_r, ConvertDBReport::FAILED,excpt_r.asUserString());
743  ZYPP_RETHROW(excpt_r);
744  }
745  report->finish(v3db_r, ConvertDBReport::NO_ERROR, "");
746 }
747 
748 } // namespace rpm
749 } // namespace target
750 } // namespace zypp
#define MIL
Definition: Logger.h:47
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
Definition: Exception.h:320
#define INT
Definition: Logger.h:51
#define ERR
Definition: Logger.h:49
#define ZYPP_RETHROW(EXCPT)
Drops a logline and rethrows, updating the CodeLocation.
Definition: Exception.h:328
#define WAR
Definition: Logger.h:48
Just inherits Exception to separate media exceptions.
Definition: RpmException.h:37
void convertV3toV4(const Pathname &v3db_r, const librpmDb::constPtr &v4db_r)
callback::SendReport< DownloadProgressReport > * report
Definition: MediaCurl.cc:178
intrusive_ptr< const librpmDb > constPtr
Definition: librpmDb.h:42
std::string asUserString() const
Translated error message as string suitable for the user.
Definition: Exception.cc:66