rpm 5.3.7
|
00001 #include "system.h" 00002 00003 /* XXX Get rid of the pugly #ifdef's */ 00004 #if defined(WITH_XAR) && defined(HAVE_XAR_H) 00005 00006 #include "xar.h" 00007 00008 #if defined(__LCLINT__) 00009 /*@-incondefs -redecl@*/ 00010 /*@null@*/ 00011 xar_t xar_open(const char *file, int32_t flags) 00012 /*@*/; 00013 int xar_close(/*@only@*/ xar_t x) 00014 /*@globals fileSystem @*/ 00015 /*@modifies x, fileSystem @*/; 00016 /*@null@*/ 00017 xar_iter_t xar_iter_new(void) 00018 /*@*/; 00019 /*@null@*/ 00020 xar_file_t xar_file_first(xar_t x, xar_iter_t i) 00021 /*@modifies x, i @*/; 00022 /*@null@*/ 00023 xar_file_t xar_file_next(xar_iter_t i) 00024 /*@modifies i @*/; 00025 /*@null@*/ 00026 xar_file_t xar_add_frombuffer(xar_t x, /*@null@*/ xar_file_t parent, 00027 const char *name, char *buffer, size_t length) 00028 /*@globals fileSystem @*/ 00029 /*@modifies x, fileSystem @*/; 00030 int32_t xar_extract_tobuffersz(xar_t x, xar_file_t f, 00031 char **buffer, size_t *size) 00032 /*@globals fileSystem @*/ 00033 /*@modifies x, f, *buffer, *size @*/; 00034 /*@only@*/ 00035 char *xar_get_path(xar_file_t f) 00036 /*@*/; 00037 /*@=incondefs =redecl@*/ 00038 00039 #endif /* __LCLINT__ */ 00040 00041 #else /* WITH_XAR */ 00042 #define READ 0 00043 #define WRITE 1 00044 #define xar_open(_fn, _f) (NULL) 00045 #define xar_close(_x) (1) 00046 #define xar_iter_new() (NULL) 00047 #define xar_iter_free(_i) 00048 #define xar_file_first(_x, _i) (NULL) 00049 #define xar_file_next(_i) (NULL) 00050 #define xar_add_frombuffer(_x, _parent, _fn, _b, _bsize) (NULL) 00051 #define xar_extract_tobuffersz(_x, _f, _b, _bsize) (1) 00052 #define xar_get_path(_f) "*No XAR*" 00053 #define xar_opt_set(_a1, _a2, _a3) (1) 00054 #define XAR_OPT_COMPRESSION 0 00055 #define XAR_OPT_VAL_NONE 0 00056 #define XAR_OPT_VAL_GZIP 0 00057 #endif /* WITH_XAR */ 00058 00059 #define _RPMXAR_INTERNAL 00060 #include <rpmxar.h> 00061 #include <rpmio_internal.h> /* for fdGetXAR */ 00062 #include <rpmhash.h> /* hashFunctionString */ 00063 #include <ugid.h> 00064 00065 #include "debug.h" 00066 00067 /*@access FD_t @*/ 00068 00069 /*@unchecked@*/ 00070 int _xar_debug = 0; 00071 00072 /*@unchecked@*/ /*@only@*/ /*@null@*/ 00073 rpmioPool _xarPool; 00074 00075 /*@-globuse -mustmod@*/ 00076 static void rpmxarFini(void * _xar) 00077 /*@globals fileSystem @*/ 00078 /*@modifies _xar, fileSystem @*/ 00079 { 00080 rpmxar xar =_xar; 00081 if (xar->i) { 00082 xar_iter_free(xar->i); 00083 xar->i = NULL; 00084 } 00085 if (xar->x) { 00086 int xx; 00087 xx = xar_close(xar->x); 00088 xar->x = NULL; 00089 } 00090 00091 xar->member = _free(xar->member); 00092 xar->b = _free(xar->b); 00093 } 00094 /*@=globuse =mustmod@*/ 00095 00096 static rpmxar rpmxarGetPool(/*@null@*/ rpmioPool pool) 00097 /*@globals _xarPool, fileSystem @*/ 00098 /*@modifies pool, _xarPool, fileSystem @*/ 00099 { 00100 rpmxar xar; 00101 00102 if (_xarPool == NULL) { 00103 _xarPool = rpmioNewPool("xar", sizeof(*xar), -1, _xar_debug, 00104 NULL, NULL, rpmxarFini); 00105 pool = _xarPool; 00106 } 00107 xar = (rpmxar) rpmioGetPool(pool, sizeof(*xar)); 00108 memset(((char *)xar)+sizeof(xar->_item), 0, sizeof(*xar)-sizeof(xar->_item)); 00109 return xar; 00110 } 00111 00112 rpmxar rpmxarNew(const char * fn, const char * fmode) 00113 { 00114 rpmxar xar = rpmxarGetPool(_xarPool); 00115 int flags = ((fmode && *fmode == 'w') ? WRITE : READ); 00116 00117 assert(fn != NULL); 00118 xar->x = xar_open(fn, flags); 00119 if (flags == READ) { 00120 xar->i = xar_iter_new(); 00121 xar->first = 1; 00122 } 00123 if (_xar_debug) 00124 fprintf(stderr, "<-- %s(%s,%s) xar %p i %p x %p first %d\n", __FUNCTION__, fn, fmode, xar, xar->i, xar->x, xar->first); 00125 return rpmxarLink(xar, __FUNCTION__); 00126 } 00127 00128 int rpmxarNext(rpmxar xar) 00129 { 00130 int rc = 1; /* assume failure */ 00131 00132 if (_xar_debug) 00133 fprintf(stderr, "--> %s(%p) i %p x %p first %d\n", __FUNCTION__, xar, (xar ? xar->i : NULL), (xar ? xar->x : NULL), (xar ? xar->first : -1)); 00134 if (xar && xar->x) { 00135 if (xar->first) { 00136 xar->f = xar_file_first(xar->x, xar->i); 00137 xar->first = 0; 00138 } else 00139 xar->f = xar_file_next(xar->i); 00140 } 00141 00142 rc = (xar && xar->f ? 0 : 1); 00143 if (_xar_debug)fprintf(stderr, "<-- %s(%p) rc %d\n", __FUNCTION__, xar, rc); 00144 return rc; 00145 } 00146 00147 int rpmxarPush(rpmxar xar, const char * fn, unsigned char * b, size_t bsize) 00148 { 00149 int payload = !strcmp(fn, "Payload"); 00150 00151 /*@+charint@*/ 00152 if (_xar_debug) 00153 fprintf(stderr, "--> rpmxarPush(%p, %s) %p[%u] %02x%02x%02x%02x%02x%02x%02x%02x\n", xar, fn, b, (unsigned)bsize, b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7]); 00154 /*@=charint@*/ 00155 00156 if (xar->x && b != NULL) { 00157 if (payload) /* payload is already compressed */ 00158 (void) xar_opt_set(xar->x, XAR_OPT_COMPRESSION, XAR_OPT_VAL_NONE); 00159 xar->f = xar_add_frombuffer(xar->x, NULL, fn, (char *)b, bsize); 00160 if (payload) /* restore default xar compression */ 00161 (void) xar_opt_set(xar->x, XAR_OPT_COMPRESSION, XAR_OPT_VAL_GZIP); 00162 if (xar->f == NULL) 00163 return 2; 00164 } 00165 return 0; 00166 } 00167 00168 int rpmxarPull(rpmxar xar, const char * fn) 00169 { 00170 int rc = 1; 00171 #ifdef WITH_XAR 00172 const char * path = xar_get_path(xar->f); 00173 00174 if (fn != NULL && strcmp(fn, path)) { 00175 path = _free(path); 00176 return rc; 00177 } 00178 xar->member = _free(xar->member); 00179 xar->member = path; 00180 00181 xar->b = _free(xar->b); 00182 xar->bsize = xar->bx = 0; 00183 00184 /*@-nullstate @*/ 00185 rc = (int) xar_extract_tobuffersz(xar->x, xar->f, (char **)&xar->b, &xar->bsize); 00186 /*@=nullstate @*/ 00187 if (rc) 00188 return 1; 00189 00190 /*@+charint -nullpass -nullderef @*/ 00191 if (_xar_debug) { 00192 unsigned char * b = xar->b; 00193 size_t bsize = xar->bsize; 00194 fprintf(stderr, "<-- rpmxarPull(%p, %s) %p[%u] %02x%02x%02x%02x%02x%02x%02x%02x\n", xar, fn, b, (unsigned)bsize, b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7]); 00195 } 00196 /*@=charint =nullpass =nullderef @*/ 00197 rc = 0; 00198 #endif 00199 00200 return rc; 00201 } 00202 00203 int rpmxarSwapBuf(rpmxar xar, unsigned char * b, size_t bsize, 00204 unsigned char ** obp, size_t * obsizep) 00205 { 00206 if (_xar_debug) 00207 fprintf(stderr, "--> rpmxarSwapBuf(%p, %p[%u], %p, %p) %p[%u]\n", xar, b, (unsigned) bsize, obp, obsizep, xar->b, (unsigned) xar->bsize); 00208 00209 if (xar) { 00210 if (obsizep != NULL) 00211 *obsizep = xar->bsize; 00212 if (obp != NULL) { 00213 /*@-onlytrans@*/ 00214 *obp = xar->b; 00215 /*@=onlytrans@*/ 00216 xar->b = NULL; 00217 } 00218 xar->b = _free(xar->b); 00219 /*@-assignexpose -temptrans @*/ 00220 xar->b = b; 00221 /*@=assignexpose =temptrans @*/ 00222 xar->bsize = bsize; 00223 } 00224 /*@-nullstate@*/ 00225 return 0; 00226 /*@=nullstate@*/ 00227 } 00228 00229 ssize_t xarRead(void * cookie, /*@out@*/ char * buf, size_t count) 00230 { 00231 FD_t fd = cookie; 00232 rpmxar xar = fdGetXAR(fd); 00233 ssize_t rc = 0; 00234 00235 assert(xar != NULL); 00236 #if 0 00237 if ((xx = rpmxarNext(xar)) != 0) return RPMRC_FAIL; 00238 if ((xx = rpmxarPull(xar, "Signature")) != 0) return RPMRC_FAIL; 00239 (void) rpmxarSwapBuf(xar, NULL, 0, &b, &nb); 00240 #endif 00241 00242 rc = xar->bsize - xar->bx; 00243 if (rc > 0) { 00244 if (count < (size_t)rc) rc = count; 00245 assert(xar->b != NULL); 00246 memmove(buf, &xar->b[xar->bx], rc); 00247 xar->bx += rc; 00248 } else 00249 if (rc < 0) { 00250 rc = -1; 00251 } else 00252 rc = 0; 00253 00254 if (_xar_debug) 00255 fprintf(stderr, "<-- %s(%p,%p,0x%x) %s %p[%u:%u] rc 0x%x\n", __FUNCTION__, cookie, buf, (unsigned)count, (xar->member ? xar->member : "(nil)"), xar->b, (unsigned)xar->bx, (unsigned)xar->bsize, (unsigned)rc); 00256 00257 return rc; 00258 } 00259 00260 const char * rpmxarPath(rpmxar xar) 00261 { 00262 const char * path = (xar && xar->f ? xar_get_path(xar->f) : NULL); 00263 if (_xar_debug) 00264 fprintf(stderr, "<-- %s(%p) %s\n", __FUNCTION__, xar, path); 00265 return path; 00266 } 00267 00268 static mode_t xarMode(rpmxar xar) 00269 /*@*/ 00270 { 00271 mode_t m = 0; 00272 #ifdef WITH_XAR 00273 const char * t = NULL; 00274 00275 xar_prop_get(xar->f, "mode", &t); 00276 m = (t ? (mode_t) strtoll(t, NULL, 8) : 0); 00277 00278 xar_prop_get(xar->f, "type", &t); 00279 if (!strcmp(t, "file")) 00280 m |= S_IFREG; 00281 else if (!strcmp(t, "hardlink")) 00282 m |= S_IFREG; 00283 else if (!strcmp(t, "directory")) 00284 m |= S_IFDIR; 00285 else if (!strcmp(t, "symlink")) 00286 m |= S_IFLNK; 00287 else if (!strcmp(t, "fifo")) 00288 m |= S_IFIFO; 00289 else if (!strcmp(t, "character special")) 00290 m |= S_IFCHR; 00291 else if (!strcmp(t, "block special")) 00292 m |= S_IFBLK; 00293 else if (!strcmp(t, "socket")) 00294 m |= S_IFSOCK; 00295 #ifdef S_IFWHT 00296 else if (!strcmp(t, "whiteout")) 00297 m |= S_IFWHT; 00298 #endif 00299 #endif 00300 00301 return m; 00302 } 00303 00304 static dev_t xarDev(rpmxar xar) 00305 /*@*/ 00306 { 00307 unsigned major = 0; 00308 unsigned minor = 0; 00309 #ifdef WITH_XAR 00310 const char *t = NULL; 00311 00312 xar_prop_get(xar->f, "device/major", &t); 00313 major = (t ? (unsigned) strtoll(t, NULL, 0) : 0); 00314 xar_prop_get(xar->f, "device/minor", &t); 00315 minor = (t ? (unsigned) strtoll(t, NULL, 0) : 0); 00316 #endif 00317 #ifdef makedev 00318 return makedev(major, minor); 00319 #else 00320 return (major << 8) | minor; 00321 #endif 00322 } 00323 00324 static long long xarSize(rpmxar xar) 00325 /*@*/ 00326 { 00327 long long ll = 0L; 00328 #ifdef WITH_XAR 00329 char * t = NULL; 00330 #if defined(HAVE_XAR_GET_SIZE) 00331 t = xar_get_size(xar->x, xar->f); 00332 ll = strtoll(t, NULL, 0); 00333 t = _free(t); 00334 #else 00335 xar_prop_get(xar->f, "data/size", &t); 00336 if (t) 00337 ll = strtoll(t, NULL, 0); 00338 #endif 00339 #endif 00340 return ll; 00341 } 00342 00343 static uid_t xarUid(rpmxar xar) 00344 /*@*/ 00345 { 00346 uid_t u = 0; 00347 #ifdef WITH_XAR 00348 const char * t = NULL; 00349 00350 xar_prop_get(xar->f, "user", &t); 00351 if (t == NULL || unameToUid(t, &u) < 0) { 00352 xar_prop_get(xar->f, "uid", &t); 00353 u = (t ? (uid_t) strtoll(t, NULL, 0) : getuid()); 00354 } 00355 #endif 00356 return u; 00357 } 00358 00359 static gid_t xarGid(rpmxar xar) 00360 /*@*/ 00361 { 00362 gid_t g = 0; 00363 #ifdef WITH_XAR 00364 const char * t = NULL; 00365 00366 xar_prop_get(xar->f, "group", &t); 00367 if (t == NULL || gnameToGid(t, &g) < 0) { 00368 xar_prop_get(xar->f, "gid", &t); 00369 g = (t ? (gid_t) strtoll(t, NULL, 0) : getgid()); 00370 } 00371 #endif 00372 return g; 00373 } 00374 00375 static void xarTime(rpmxar xar, const char * tprop, struct timeval *tv) 00376 /*@modifies *tvp */ 00377 { 00378 #ifdef WITH_XAR 00379 const char * t = NULL; 00380 00381 xar_prop_get(xar->f, tprop, &t); 00382 if (t) { 00383 struct tm tm; 00384 strptime(t, "%FT%T", &tm); 00385 tv->tv_sec = timegm(&tm); 00386 tv->tv_usec = 0; 00387 } else 00388 #endif 00389 { 00390 tv->tv_sec = time(NULL); 00391 tv->tv_usec = 0; 00392 } 00393 } 00394 00395 int rpmxarStat(rpmxar xar, struct stat * st) 00396 { 00397 int rc = -1; /* assume failure */ 00398 00399 if (xar && xar->f) { 00400 const char * path = rpmxarPath(xar); 00401 memset(st, 0, sizeof(*st)); 00402 st->st_dev = (dev_t)0; 00403 st->st_ino = hashFunctionString(0, path, 0);; 00404 path = _free(path); 00405 st->st_mode = xarMode(xar); 00406 st->st_nlink = (S_ISDIR(st->st_mode) ? 2 : 1); /* XXX FIXME */ 00407 st->st_uid = xarUid(xar); 00408 st->st_gid = xarGid(xar); 00409 st->st_rdev = (S_ISCHR(st->st_mode) || S_ISBLK(st->st_mode)) 00410 ? xarDev(xar) : (dev_t)0; 00411 st->st_size = xarSize(xar); 00412 st->st_blksize = (blksize_t) 0; 00413 st->st_blocks = (blkcnt_t) 0; 00414 xarTime(xar, "atime", (struct timeval *)&st->st_atime); 00415 xarTime(xar, "ctime", (struct timeval *)&st->st_ctime); 00416 xarTime(xar, "mtime", (struct timeval *)&st->st_mtime); 00417 rc = 0; 00418 } 00419 00420 if (_xar_debug) 00421 fprintf(stderr, "<-- %s(%p,%p) rc %d\n", __FUNCTION__, xar, st, rc); 00422 return rc; 00423 }