home *** CD-ROM | disk | FTP | other *** search
/ DOS/V Power Report 2003 May / VPR0305.ISO / OLS / TAR32223 / tar32223.lzh / tar32_2 / src / rpm.cpp < prev    next >
C/C++ Source or Header  |  2003-01-17  |  3KB  |  125 lines

  1. #include "rpm.h"
  2. #include <fstream>
  3. using namespace std;
  4.  
  5. /* Reference: lib/rpmlib.h of rpm package. */
  6. struct rpmlead{
  7.     unsigned char magic[4];
  8.     unsigned char major;    /* not supported  ver1, only support 2,3 and lator */
  9.     unsigned char minor;
  10.     short type;
  11.     short archnum;
  12.     char name[66];
  13.     short osnum;
  14.     short signature_type;
  15.     char reserved[16];    /* pad to 96 bytes -- 8 byte aligned */
  16.     int magic_check(){
  17.         return magic[0] == 0xed && magic[1] == 0xab && magic[2] == 0xee && magic[3] == 0xdb;
  18.     };
  19.     short my_htons(short s){
  20.         unsigned char *p = (unsigned char*)&s;
  21.         return (p[0] << 8) + (p[1]);
  22.     };
  23.     void hton(){
  24.         type = my_htons(type);
  25.         archnum = my_htons(archnum);
  26.         osnum = my_htons(osnum);
  27.         signature_type = my_htons(signature_type);
  28.     };
  29. };
  30.  
  31. /* Reference: lib/header.c of rpm package. */
  32. struct rpm_entryInfo{
  33.     int tag;
  34.     int type;
  35.     int offset;    /* Offset from beginning of data segment, only defined on disk */
  36.     int count;
  37. };
  38.  
  39. /* case: signature_type == RPMSIG_HEADERSIG */
  40. struct rpmsig_headersig{
  41.     unsigned char magic[4];
  42.     int reserved;
  43.     int index_len;    /* count of index entries */
  44.     int data_len;        /* number of bytes */
  45.     int magic_check(){
  46.         return magic[0] == 0x8e && magic[1] == 0xad && magic[2] == 0xe8 && magic[3]==0x01;
  47.     };
  48.     int get_lostheaderlen(){
  49.         return index_len * sizeof(rpm_entryInfo) + data_len;  
  50.     };
  51.     long my_htonl(long s){
  52.         unsigned char *p = (unsigned char*)&s;
  53.         return (p[0] << 24) + (p[1]<<16) + (p[2]<<8) + p[3];
  54.     };
  55.     void hton(){
  56.         index_len = my_htonl(index_len);
  57.         data_len = my_htonl(data_len);
  58.     };
  59. };
  60.  
  61.  
  62. /* Reference: lib/signature.h of rpm package */
  63. #define RPMSIG_NONE         0  /* Do not change! */
  64. /* The following types are no longer generated */
  65. #define RPMSIG_PGP262_1024  1  /* No longer generated */ /* 256 byte */
  66. /* These are the new-style signatures.  They are Header structures.    */
  67. /* Inside them we can put any number of any type of signature we like. */
  68.  
  69. #define RPMSIG_HEADERSIG    5  /* New Header style signature */
  70.  
  71. int rpm_getheadersize(const char *arcfile)
  72. {
  73.     rpmlead lead;
  74.     rpmsig_headersig sigheader,header;
  75.     
  76.     ifstream fs;
  77.     fs.open(arcfile, ios::in|ios::binary);
  78.     if(fs.fail()){return false;}
  79.     
  80.     fs.read((char*)&lead, sizeof(lead));
  81.     if(fs.gcount() != sizeof(lead)){return -1;}
  82.     if(! lead.magic_check()){return -1;}
  83.     lead.hton();
  84.  
  85.     if(lead.signature_type == RPMSIG_NONE){
  86.         ;
  87.     }else if(lead.signature_type == RPMSIG_PGP262_1024){
  88.         fs.seekg(256, ios::cur);
  89.         if(fs.fail()){return false;}
  90.     }else if(lead.signature_type == RPMSIG_HEADERSIG){
  91.         fs.read((char*)&sigheader,sizeof(sigheader));
  92.         if(fs.gcount() != sizeof(sigheader)){return -1;}
  93.         if(!sigheader.magic_check()){return -1;}
  94.         sigheader.hton();
  95.  
  96.         int siglen = sigheader.get_lostheaderlen();
  97.         fs.seekg(siglen, ios::cur);
  98.         if(fs.fail()){return -1;}
  99.  
  100.         int pos = fs.tellg();
  101.         if(pos == -1){return -1;}
  102.         if((pos%8) != 0){
  103.             /* 8 byte padding */
  104.             // int pad = pos - (pos/8)*8;
  105.             int pad = (pos/8 + 1) * 8 - pos ;  // fix by tsuneo 2001.05.14
  106.             fs.seekg(pad, ios::cur);
  107.             if(fs.fail()){return -1;}
  108.         }
  109.     }else{
  110.         return -1;
  111.     }
  112.  
  113.     fs.read((char*)&header, sizeof(header));
  114.     if(fs.gcount() != sizeof(header)){return -1;}
  115.     if(!header.magic_check()){return -1;}
  116.     header.hton();
  117.     int hdrlen = header.get_lostheaderlen();
  118.     if(hdrlen == -1){return -1;}
  119.     fs.seekg(hdrlen, ios::cur);
  120.     if(fs.fail()){return -1;}
  121.     
  122.     int size = fs.tellg();
  123.     return size;
  124.  
  125. }