rpm  5.4.15
rpmxar.c
Go to the documentation of this file.
1 #include "system.h"
2 
3 /* XXX Get rid of the pugly #ifdef's */
4 #if defined(WITH_XAR) && defined(HAVE_XAR_H)
5 
6 #include "xar.h"
7 
8 #if defined(__LCLINT__)
9 /*@-incondefs -redecl@*/
10 /*@null@*/
11 xar_t xar_open(const char *file, int32_t flags)
12  /*@*/;
13 int xar_close(/*@only@*/ xar_t x)
14  /*@globals fileSystem @*/
15  /*@modifies x, fileSystem @*/;
16 /*@null@*/
17 xar_iter_t xar_iter_new(void)
18  /*@*/;
19 /*@null@*/
20 xar_file_t xar_file_first(xar_t x, xar_iter_t i)
21  /*@modifies x, i @*/;
22 /*@null@*/
23 xar_file_t xar_file_next(xar_iter_t i)
24  /*@modifies i @*/;
25 /*@null@*/
26 xar_file_t xar_add_frombuffer(xar_t x, /*@null@*/ xar_file_t parent,
27  const char *name, char *buffer, size_t length)
28  /*@globals fileSystem @*/
29  /*@modifies x, fileSystem @*/;
30 int32_t xar_extract_tobuffersz(xar_t x, xar_file_t f,
31  char **buffer, size_t *size)
32  /*@globals fileSystem @*/
33  /*@modifies x, f, *buffer, *size @*/;
34 /*@only@*/
35 char *xar_get_path(xar_file_t f)
36  /*@*/;
37 /*@=incondefs =redecl@*/
38 
39 #endif /* __LCLINT__ */
40 
41 #else /* WITH_XAR */
42 #define READ 0
43 #define WRITE 1
44 #define xar_open(_fn, _f) (NULL)
45 #define xar_close(_x) (1)
46 #define xar_iter_new() (NULL)
47 #define xar_iter_free(_i)
48 #define xar_file_first(_x, _i) (NULL)
49 #define xar_file_next(_i) (NULL)
50 #define xar_add_frombuffer(_x, _parent, _fn, _b, _bsize) (NULL)
51 #define xar_extract_tobuffersz(_x, _f, _b, _bsize) (1)
52 #define xar_get_path(_f) "*No XAR*"
53 #define xar_opt_set(_a1, _a2, _a3) (1)
54 #define XAR_OPT_COMPRESSION 0
55 #define XAR_OPT_VAL_NONE 0
56 #define XAR_OPT_VAL_GZIP 0
57 #endif /* WITH_XAR */
58 
59 #define _RPMXAR_INTERNAL
60 #include <rpmxar.h>
61 #include <rpmio_internal.h> /* for fdGetXAR */
62 #include <rpmhash.h> /* hashFunctionString */
63 #include <ugid.h>
64 
65 #include "debug.h"
66 
67 /*@access FD_t @*/
68 
69 /*@unchecked@*/
70 int _xar_debug = 0;
71 
72 /*@unchecked@*/ /*@only@*/ /*@null@*/
74 
75 /*@-globuse -mustmod@*/
76 static void rpmxarFini(void * _xar)
77  /*@globals fileSystem @*/
78  /*@modifies _xar, fileSystem @*/
79 {
80  rpmxar xar = (rpmxar) _xar;
81  if (xar->i) {
82  xar_iter_free(xar->i);
83  xar->i = NULL;
84  }
85  if (xar->x) {
86  int xx;
87  xx = xar_close(xar->x);
88  xar->x = NULL;
89  }
90 
91  xar->member = _free(xar->member);
92  xar->b = _free(xar->b);
93 }
94 /*@=globuse =mustmod@*/
95 
96 static rpmxar rpmxarGetPool(/*@null@*/ rpmioPool pool)
97  /*@globals _xarPool, fileSystem @*/
98  /*@modifies pool, _xarPool, fileSystem @*/
99 {
100  rpmxar xar;
101 
102  if (_xarPool == NULL) {
103  _xarPool = rpmioNewPool("xar", sizeof(*xar), -1, _xar_debug,
104  NULL, NULL, rpmxarFini);
105  pool = _xarPool;
106  }
107  xar = (rpmxar) rpmioGetPool(pool, sizeof(*xar));
108  memset(((char *)xar)+sizeof(xar->_item), 0, sizeof(*xar)-sizeof(xar->_item));
109  return xar;
110 }
111 
112 rpmxar rpmxarNew(const char * fn, const char * fmode)
113 {
114  rpmxar xar = rpmxarGetPool(_xarPool);
115  int flags = ((fmode && *fmode == 'w') ? WRITE : READ);
116 
117 assert(fn != NULL);
118  xar->x = xar_open(fn, flags);
119  if (flags == READ) {
120  xar->i = xar_iter_new();
121  xar->first = 1;
122  }
123 if (_xar_debug)
124 fprintf(stderr, "<-- %s(%s,%s) xar %p i %p x %p first %d\n", __FUNCTION__, fn, fmode, xar, xar->i, xar->x, xar->first);
125  return rpmxarLink(xar, __FUNCTION__);
126 }
127 
129 {
130  int rc = 1; /* assume failure */
131 
132 if (_xar_debug)
133 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));
134  if (xar && xar->x) {
135  if (xar->first) {
136  xar->f = xar_file_first(xar->x, xar->i);
137  xar->first = 0;
138  } else
139  xar->f = xar_file_next(xar->i);
140  }
141 
142  rc = (xar && xar->f ? 0 : 1);
143 if (_xar_debug)fprintf(stderr, "<-- %s(%p) rc %d\n", __FUNCTION__, xar, rc);
144  return rc;
145 }
146 
147 int rpmxarPush(rpmxar xar, const char * fn, unsigned char * b, size_t bsize)
148 {
149  int payload = !strcmp(fn, "Payload");
150 
151 /*@+charint@*/
152 if (_xar_debug)
153 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]);
154 /*@=charint@*/
155 
156  if (xar->x && b != NULL) {
157  if (payload) /* payload is already compressed */
159  xar->f = xar_add_frombuffer(xar->x, NULL, fn, (char *)b, bsize);
160  if (payload) /* restore default xar compression */
162  if (xar->f == NULL)
163  return 2;
164  }
165  return 0;
166 }
167 
168 int rpmxarPull(rpmxar xar, const char * fn)
169 {
170  int rc = 1;
171 #ifdef WITH_XAR
172  const char * path = xar_get_path(xar->f);
173 
174  if (fn != NULL && strcmp(fn, path)) {
175  path = _free(path);
176  return rc;
177  }
178  xar->member = _free(xar->member);
179  xar->member = path;
180 
181  xar->b = _free(xar->b);
182  xar->bsize = xar->bx = 0;
183 
184 /*@-nullstate @*/
185  rc = (int) xar_extract_tobuffersz(xar->x, xar->f, (char **)&xar->b, &xar->bsize);
186 /*@=nullstate @*/
187  if (rc)
188  return 1;
189 
190 /*@+charint -nullpass -nullderef @*/
191 if (_xar_debug) {
192 unsigned char * b = xar->b;
193 size_t bsize = xar->bsize;
194 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]);
195 }
196 /*@=charint =nullpass =nullderef @*/
197  rc = 0;
198 #endif
199 
200  return rc;
201 }
202 
203 int rpmxarSwapBuf(rpmxar xar, unsigned char * b, size_t bsize,
204  unsigned char ** obp, size_t * obsizep)
205 {
206 if (_xar_debug)
207 fprintf(stderr, "--> rpmxarSwapBuf(%p, %p[%u], %p, %p) %p[%u]\n", xar, b, (unsigned) bsize, obp, obsizep, xar->b, (unsigned) xar->bsize);
208 
209  if (xar) {
210  if (obsizep != NULL)
211  *obsizep = xar->bsize;
212  if (obp != NULL) {
213 /*@-onlytrans@*/
214  *obp = xar->b;
215 /*@=onlytrans@*/
216  xar->b = NULL;
217  }
218  xar->b = _free(xar->b);
219 /*@-assignexpose -temptrans @*/
220  xar->b = b;
221 /*@=assignexpose =temptrans @*/
222  xar->bsize = bsize;
223  }
224 /*@-nullstate@*/
225  return 0;
226 /*@=nullstate@*/
227 }
228 
229 ssize_t xarRead(void * cookie, /*@out@*/ char * buf, size_t count)
230 {
231  FD_t fd = (FD_t) cookie;
232  rpmxar xar = fdGetXAR(fd);
233  ssize_t rc = 0;
234 
235 assert(xar != NULL);
236 #if 0
237  if ((xx = rpmxarNext(xar)) != 0) return RPMRC_FAIL;
238  if ((xx = rpmxarPull(xar, "Signature")) != 0) return RPMRC_FAIL;
239  (void) rpmxarSwapBuf(xar, NULL, 0, &b, &nb);
240 #endif
241 
242  rc = xar->bsize - xar->bx;
243  if (rc > 0) {
244  if (count < (size_t)rc) rc = count;
245 assert(xar->b != NULL);
246  memmove(buf, &xar->b[xar->bx], rc);
247  xar->bx += rc;
248  } else
249  if (rc < 0) {
250  rc = -1;
251  } else
252  rc = 0;
253 
254 if (_xar_debug)
255 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);
256 
257  return rc;
258 }
259 
260 const char * rpmxarPath(rpmxar xar)
261 {
262  const char * path = (xar && xar->f ? xar_get_path(xar->f) : NULL);
263 if (_xar_debug)
264 fprintf(stderr, "<-- %s(%p) %s\n", __FUNCTION__, xar, path);
265  return path;
266 }
267 
268 static mode_t xarMode(rpmxar xar)
269  /*@*/
270 {
271  mode_t m = 0;
272 #ifdef WITH_XAR
273  const char * t = NULL;
274 
275  xar_prop_get(xar->f, "mode", &t);
276  m = (t ? (mode_t) strtoll(t, NULL, 8) : 0);
277 
278  xar_prop_get(xar->f, "type", &t);
279  if (!strcmp(t, "file"))
280  m |= S_IFREG;
281  else if (!strcmp(t, "hardlink"))
282  m |= S_IFREG;
283  else if (!strcmp(t, "directory"))
284  m |= S_IFDIR;
285  else if (!strcmp(t, "symlink"))
286  m |= S_IFLNK;
287  else if (!strcmp(t, "fifo"))
288  m |= S_IFIFO;
289  else if (!strcmp(t, "character special"))
290  m |= S_IFCHR;
291  else if (!strcmp(t, "block special"))
292  m |= S_IFBLK;
293  else if (!strcmp(t, "socket"))
294  m |= S_IFSOCK;
295 #ifdef S_IFWHT
296  else if (!strcmp(t, "whiteout"))
297  m |= S_IFWHT;
298 #endif
299 #endif
300 
301  return m;
302 }
303 
304 static dev_t xarDev(rpmxar xar)
305  /*@*/
306 {
307  unsigned major = 0;
308  unsigned minor = 0;
309 #ifdef WITH_XAR
310  const char *t = NULL;
311 
312  xar_prop_get(xar->f, "device/major", &t);
313  major = (t ? (unsigned) strtoll(t, NULL, 0) : 0);
314  xar_prop_get(xar->f, "device/minor", &t);
315  minor = (t ? (unsigned) strtoll(t, NULL, 0) : 0);
316 #endif
317 #ifdef makedev
318  return makedev(major, minor);
319 #else
320  return (major << 8) | minor;
321 #endif
322 }
323 
324 static long long xarSize(rpmxar xar)
325  /*@*/
326 {
327  long long ll = 0L;
328 #ifdef WITH_XAR
329  char * t = NULL;
330 #if defined(HAVE_XAR_GET_SIZE)
331  t = xar_get_size(xar->x, xar->f);
332  ll = strtoll(t, NULL, 0);
333  t = _free(t);
334 #else
335  xar_prop_get(xar->f, "data/size", &t);
336  if (t)
337  ll = strtoll(t, NULL, 0);
338 #endif
339 #endif
340  return ll;
341 }
342 
343 static uid_t xarUid(rpmxar xar)
344  /*@*/
345 {
346  uid_t u = 0;
347 #ifdef WITH_XAR
348  const char * t = NULL;
349 
350  xar_prop_get(xar->f, "user", &t);
351  if (t == NULL || unameToUid(t, &u) < 0) {
352  xar_prop_get(xar->f, "uid", &t);
353  u = (t ? (uid_t) strtoll(t, NULL, 0) : getuid());
354  }
355 #endif
356  return u;
357 }
358 
359 static gid_t xarGid(rpmxar xar)
360  /*@*/
361 {
362  gid_t g = 0;
363 #ifdef WITH_XAR
364  const char * t = NULL;
365 
366  xar_prop_get(xar->f, "group", &t);
367  if (t == NULL || gnameToGid(t, &g) < 0) {
368  xar_prop_get(xar->f, "gid", &t);
369  g = (t ? (gid_t) strtoll(t, NULL, 0) : getgid());
370  }
371 #endif
372  return g;
373 }
374 
375 static void xarTime(rpmxar xar, const char * tprop, struct timeval *tv)
376  /*@modifies *tvp */
377 {
378 #ifdef WITH_XAR
379  const char * t = NULL;
380 
381  xar_prop_get(xar->f, tprop, &t);
382  if (t) {
383  struct tm tm;
384  strptime(t, "%FT%T", &tm);
385  tv->tv_sec = timegm(&tm);
386  tv->tv_usec = 0;
387  } else
388 #endif
389  {
390  tv->tv_sec = time(NULL);
391  tv->tv_usec = 0;
392  }
393 }
394 
395 int rpmxarStat(rpmxar xar, struct stat * st)
396 {
397  int rc = -1; /* assume failure */
398 
399  if (xar && xar->f) {
400  const char * path = rpmxarPath(xar);
401  memset(st, 0, sizeof(*st));
402  st->st_dev = (dev_t)0;
403  st->st_ino = hashFunctionString(0, path, 0);;
404  path = _free(path);
405  st->st_mode = xarMode(xar);
406  st->st_nlink = (S_ISDIR(st->st_mode) ? 2 : 1); /* XXX FIXME */
407  st->st_uid = xarUid(xar);
408  st->st_gid = xarGid(xar);
409  st->st_rdev = (S_ISCHR(st->st_mode) || S_ISBLK(st->st_mode))
410  ? xarDev(xar) : (dev_t)0;
411  st->st_size = xarSize(xar);
412  st->st_blksize = (blksize_t) 0;
413  st->st_blocks = (blkcnt_t) 0;
414  xarTime(xar, "atime", (struct timeval *)&st->st_atime);
415  xarTime(xar, "ctime", (struct timeval *)&st->st_ctime);
416  xarTime(xar, "mtime", (struct timeval *)&st->st_mtime);
417  rc = 0;
418  }
419 
420 if (_xar_debug)
421 fprintf(stderr, "<-- %s(%p,%p) rc %d\n", __FUNCTION__, xar, st, rc);
422  return rc;
423 }
Structure(s)and methods for a XAR archive wrapper format.
const bson * b
Definition: bson.h:280
static gid_t xarGid(rpmxar xar)
Definition: rpmxar.c:359
struct rpmxar_s * rpmxar
Definition: rpmxar.h:14
#define WRITE
Definition: rpmxar.c:43
#define xar_file_first(_x, _i)
Definition: rpmxar.c:48
static void xarTime(rpmxar xar, const char *tprop, struct timeval *tv)
Definition: rpmxar.c:375
#define makedev(maj, min)
Definition: system.h:142
const char int time
Definition: bson.h:1005
int rpmxarNext(rpmxar xar)
Iterate a xar archive instance.
Definition: rpmxar.c:128
#define XAR_OPT_VAL_NONE
Definition: rpmxar.c:55
Hash table implemenation.
static mode_t xarMode(rpmxar xar)
Definition: rpmxar.c:268
static dev_t xarDev(rpmxar xar)
Definition: rpmxar.c:304
const char * buffer
Definition: bson.h:289
int _xar_debug
Definition: rpmxar.c:70
const char * rpmxarPath(rpmxar xar)
Return path of current archive member.
Definition: rpmxar.c:260
int rpmxarStat(rpmxar xar, struct stat *st)
Return stat(2) of current archive member.
Definition: rpmxar.c:395
int rpmxarPush(rpmxar xar, const char *fn, unsigned char *b, size_t bsize)
Definition: rpmxar.c:147
struct _FD_s * FD_t
Definition: rpmio.h:43
int rpmxarPull(rpmxar xar, const char *fn)
Definition: rpmxar.c:168
rpmioItem rpmioGetPool(rpmioPool pool, size_t size)
Get unused item from pool, or alloc a new item.
Definition: rpmmalloc.c:220
int gnameToGid(const char *thisGname, gid_t *gid)
Definition: ugid.c:71
#define XAR_OPT_VAL_GZIP
Definition: rpmxar.c:56
static uid_t xarUid(rpmxar xar)
Definition: rpmxar.c:343
#define xar_open(_fn, _f)
Definition: rpmxar.c:44
#define xar_get_path(_f)
Definition: rpmxar.c:52
static const char * file
Definition: parseFiles.c:20
static long long xarSize(rpmxar xar)
Definition: rpmxar.c:324
#define READ
Definition: rpmxar.c:42
The FD_t File Handle data structure.
#define xar_add_frombuffer(_x, _parent, _fn, _b, _bsize)
Definition: rpmxar.c:50
#define xar_file_next(_i)
Definition: rpmxar.c:49
const char const bson int mongo_write_concern int flags
Definition: mongo.h:485
#define S_IFSOCK
Definition: system.h:647
#define L(CS)
Definition: fnmatch.c:161
const char const int i
Definition: bson.h:778
#define XAR_OPT_COMPRESSION
Definition: rpmxar.c:54
rpmioPool rpmioNewPool(const char *name, size_t size, int limit, int flags, char *(*dbg)(void *item), void(*init)(void *item), void(*fini)(void *item))
Create a memory pool.
Definition: rpmmalloc.c:109
#define xar_close(_x)
Definition: rpmxar.c:45
int rpmxarSwapBuf(rpmxar xar, unsigned char *b, size_t bsize, unsigned char **obp, size_t *obsizep)
Definition: rpmxar.c:203
const char const char size_t size
Definition: bson.h:895
static rpmxar rpmxarGetPool(rpmioPool pool)
Definition: rpmxar.c:96
static void * _free(const void *p)
Wrapper to free(3), hides const compilation noise, permit NULL, return NULL.
Definition: rpmiotypes.h:756
static rpmxar fdGetXAR(FD_t fd)
#define xar_iter_new()
Definition: rpmxar.c:46
#define minor(dev)
Definition: system.h:141
rpmuint32_t hashFunctionString(rpmuint32_t h, const void *data, size_t size)
Return hash value of a string.
Definition: rpmhash.c:83
static const char * name
rpmioPool _xarPool
Definition: rpmxar.c:73
int unameToUid(const char *thisUname, uid_t *uid)
Definition: ugid.c:16
#define xar_opt_set(_a1, _a2, _a3)
Definition: rpmxar.c:53
static void rpmxarFini(void *_xar)
Definition: rpmxar.c:76
#define xar_extract_tobuffersz(_x, _f, _b, _bsize)
Definition: rpmxar.c:51
rpmxar rpmxarNew(const char *fn, const char *fmode)
Create a xar archive instance.
Definition: rpmxar.c:112
ssize_t xarRead(void *cookie, char *buf, size_t count)
Definition: rpmxar.c:229
rpmxar rpmxarLink(rpmxar xar, const char *msg)
Reference a xar archive instance.
#define major(dev)
Definition: system.h:140
#define xar_iter_free(_i)
Definition: rpmxar.c:47