ruby-rpm 1.2.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,800 @@
1
+ /* -*- mode: C; c-basic-offset: 4; tab-width: 4; -*- */
2
+ /* Ruby/RPM
3
+ *
4
+ * Copyright (C) 2002 Kenta MURATA <muraken2@nifty.com>.
5
+ */
6
+
7
+ /* $Id: package.c 45 2004-06-04 15:11:20Z kazuhiko $ */
8
+
9
+ #include "private.h"
10
+
11
+ char *stpcpy( char *dest, const char *source );
12
+
13
+ VALUE rpm_cPackage;
14
+ VALUE rpm_sChangeLog;
15
+
16
+ static ID id_signature;
17
+ struct st_table *tbl = NULL;
18
+
19
+ static VALUE
20
+ package_clear_cache(VALUE klass){
21
+ st_free_table(tbl);
22
+ tbl = NULL;
23
+ return klass;
24
+ }
25
+
26
+ static VALUE
27
+ package_use_cache(VALUE klass,VALUE b){
28
+ if((b==Qtrue)&&(tbl==NULL))
29
+ tbl = (struct st_table*)st_init_numtable();
30
+ else if (b == Qfalse)
31
+ package_clear_cache(klass);
32
+ return klass;
33
+ }
34
+
35
+ static void
36
+ package_free(Header hdr)
37
+ {
38
+ if(tbl){
39
+ char *sigmd5;
40
+ VALUE signature;
41
+ VALUE p;
42
+ sigmd5 = headerSprintf(hdr,"%{sigmd5}",
43
+ rpmTagTable, rpmHeaderFormats, NULL);
44
+ if(strcmp(sigmd5,"(none)")!=0){
45
+ signature = INT2NUM(rb_intern(sigmd5));
46
+ st_delete(tbl,&signature,&p);
47
+ }
48
+ free(sigmd5);
49
+ }
50
+ headerFree(hdr);
51
+ }
52
+
53
+ static VALUE inline
54
+ package_new_from_header(VALUE klass, Header hdr)
55
+ {
56
+ VALUE p;
57
+ VALUE signature;
58
+
59
+ p = Qnil;
60
+ signature = Qnil;
61
+
62
+ if (hdr == NULL) {
63
+ return Qnil;
64
+ }
65
+
66
+ if(tbl){
67
+ char *sigmd5;
68
+ sigmd5 = headerSprintf(hdr,"%{sigmd5}",
69
+ rpmTagTable, rpmHeaderFormats, NULL);
70
+ if(strcmp(sigmd5,"(none)")!=0){
71
+ signature = INT2NUM(rb_intern(sigmd5));
72
+ st_lookup(tbl,signature,&p);
73
+ }
74
+ free(sigmd5);
75
+ }
76
+ if (NIL_P(p)){
77
+ p = Data_Wrap_Struct(klass, NULL, package_free, headerLink(hdr));
78
+ if(tbl)
79
+ st_insert(tbl,signature,p);
80
+ }
81
+ return p;
82
+ }
83
+
84
+ static VALUE
85
+ package_s_create(VALUE klass, VALUE name, VALUE version)
86
+ {
87
+ Header hdr;
88
+ VALUE pkg;
89
+
90
+ if ((TYPE(name) != T_STRING) || (
91
+ rb_obj_is_kind_of(version, rpm_cVersion) == Qfalse)) {
92
+ rb_raise(rb_eTypeError, "illegal argument type");
93
+ }
94
+
95
+ hdr = headerNew();
96
+ headerAddEntry(hdr,RPMTAG_NAME,RPM_STRING_TYPE,RSTRING(name)->ptr,1);
97
+ headerAddEntry(hdr,RPMTAG_VERSION,RPM_STRING_TYPE,RSTRING(rpm_version_get_v(version))->ptr,1);
98
+ headerAddEntry(hdr,RPMTAG_RELEASE,RPM_STRING_TYPE,RSTRING(rpm_version_get_r(version))->ptr,1);
99
+ if(!NIL_P(rpm_version_get_e(version))){
100
+ int e = NUM2INT(rpm_version_get_e(version));
101
+ headerAddEntry(hdr,RPMTAG_EPOCH,RPM_INT32_TYPE,&e,1);
102
+ }
103
+ pkg = package_new_from_header(klass, hdr);
104
+ return pkg;
105
+ }
106
+
107
+ static VALUE
108
+ package_s_open(VALUE klass, VALUE filename)
109
+ {
110
+ VALUE pkg = Qnil;
111
+ FD_t fd;
112
+ Header hdr, sigs;
113
+ rpmRC rc;
114
+
115
+ if (TYPE(filename) != T_STRING) {
116
+ rb_raise(rb_eTypeError, "illegal argument type");
117
+ }
118
+
119
+ fd = Fopen(RSTRING(filename)->ptr, "r");
120
+ if (!fd) {
121
+ rb_raise(rb_eRuntimeError, "can not open file %s",
122
+ RSTRING(filename)->ptr);
123
+ }
124
+ rc = rpmReadPackageInfo(fd, &sigs, &hdr);
125
+ Fclose(fd);
126
+
127
+ switch (rc) {
128
+ #if RPM_VERSION_CODE < RPM_VERSION(4,1,0)
129
+ case RPMRC_BADSIZE:
130
+ #else
131
+ case RPMRC_NOTTRUSTED:
132
+ case RPMRC_NOKEY:
133
+ /* MO_TODO: zaki: should I warn these two status to users? */
134
+ #endif
135
+ case RPMRC_OK:
136
+ headerFree(sigs);
137
+ pkg = package_new_from_header(klass, hdr);
138
+ headerFree(hdr);
139
+ break;
140
+
141
+ #if RPM_VERSION_CODE < RPM_VERSION(4,1,0)
142
+ case RPMRC_BADMAGIC:
143
+ rb_raise(rb_eRuntimeError, "bad magic");
144
+ break;
145
+
146
+ #else
147
+ case RPMRC_NOTFOUND:
148
+ rb_raise(rb_eRuntimeError, "bad magic");
149
+ break;
150
+
151
+ #endif
152
+ case RPMRC_FAIL:
153
+ #if RPM_VERSION_CODE < RPM_VERSION(4,1,0)
154
+ case RPMRC_SHORTREAD:
155
+ #endif
156
+ rb_raise(rb_eRuntimeError, "error reading pakcage");
157
+ break;
158
+ }
159
+
160
+ return pkg;
161
+ }
162
+
163
+ static VALUE
164
+ package_s_load(VALUE klass, VALUE str)
165
+ {
166
+ VALUE pkg, temp;
167
+ Header hdr;
168
+ FD_t fd;
169
+
170
+ Check_Type(str, T_STRING);
171
+
172
+ temp = ruby_rpm_make_temp_name();
173
+ fd = Fopen(RSTRING(temp)->ptr, "wb+");
174
+ Fwrite(RSTRING(str)->ptr, RSTRING(str)->len, 1, fd);
175
+ Fseek(fd, 0, SEEK_SET);
176
+ hdr = headerRead(fd, HEADER_MAGIC_YES);
177
+ Fclose(fd);
178
+ Unlink(RSTRING(temp)->ptr);
179
+
180
+ if (!hdr) {
181
+ rb_raise(rb_eArgError, "unable load RPM::Package");
182
+ }
183
+
184
+ pkg = package_new_from_header(klass, hdr);
185
+ headerFree(hdr);
186
+
187
+ return pkg;
188
+ }
189
+
190
+ VALUE
191
+ rpm_package_copy_tags(VALUE from,VALUE to,VALUE tags)
192
+ {
193
+ int_32 *copy_tags;
194
+ int length = NUM2INT(rb_funcall(tags,rb_intern("length"),0));
195
+ int i;
196
+
197
+ copy_tags = ALLOCA_N(int_32,length);
198
+ for (i=0;i<length;i++)
199
+ copy_tags[i] = NUM2INT(rb_ary_entry(tags, i));
200
+ headerCopyTags(RPM_HEADER(from),RPM_HEADER(to),copy_tags);
201
+ return Qnil;
202
+ }
203
+
204
+ VALUE
205
+ rpm_package_new_from_header(Header hdr)
206
+ {
207
+ return package_new_from_header(rpm_cPackage, hdr);
208
+ }
209
+
210
+ #if RPM_VERSION(4,1,0) <= RPM_VERSION_CODE
211
+ VALUE
212
+ rpm_package_new_from_N_EVR(VALUE name, VALUE version)
213
+ {
214
+ return package_s_create(rpm_cPackage, name, version);
215
+ }
216
+ #endif
217
+
218
+ VALUE
219
+ rpm_package_add_dependency(VALUE pkg,VALUE dep)
220
+ {
221
+ int nametag;
222
+ int versiontag;
223
+ int flagstag;
224
+ char* name;
225
+ char* evr;
226
+ int flag;
227
+
228
+ if ( rb_obj_is_kind_of(dep, rpm_cDependency) == Qfalse ) {
229
+ rb_raise(rb_eTypeError, "illegal argument type");
230
+ }
231
+
232
+ nametag = NUM2INT(rpm_dependency_get_nametag(dep));
233
+ versiontag = NUM2INT(rpm_dependency_get_versiontag(dep));
234
+ flagstag = NUM2INT(rpm_dependency_get_flagstag(dep));
235
+
236
+ name = RSTRING(rpm_dependency_get_name(dep))->ptr;
237
+ evr = RSTRING(rpm_version_to_vre(rpm_dependency_get_version(dep)))->ptr;
238
+ flag = NUM2INT(rpm_dependency_get_flags(dep));
239
+
240
+ headerAddOrAppendEntry(RPM_HEADER(pkg),nametag,RPM_STRING_ARRAY_TYPE,&name,1);
241
+ headerAddOrAppendEntry(RPM_HEADER(pkg),versiontag,RPM_STRING_ARRAY_TYPE,&evr,1);
242
+ headerAddOrAppendEntry(RPM_HEADER(pkg),flagstag,RPM_INT32_TYPE,&flag,1);
243
+ return Qnil;
244
+ }
245
+
246
+ VALUE
247
+ rpm_package_add_int32(VALUE pkg,VALUE tag,VALUE val)
248
+ {
249
+ int_32 v;
250
+ if (TYPE(val) == T_FIXNUM) {
251
+ v = (int_32) FIX2LONG(val);
252
+ }
253
+ else if (TYPE(val) == T_BIGNUM) {
254
+ v = (int_32) NUM2LONG(val);
255
+ }
256
+ else {
257
+ rb_raise(rb_eTypeError, "illegal argument type");
258
+ }
259
+
260
+ headerAddOrAppendEntry(RPM_HEADER(pkg),NUM2INT(tag),RPM_INT32_TYPE,&v,1);
261
+ return Qnil;
262
+ }
263
+
264
+ VALUE
265
+ rpm_package_add_string_array(VALUE pkg,VALUE tag,VALUE val)
266
+ {
267
+ if ((TYPE(val) != T_STRING)) {
268
+ rb_raise(rb_eTypeError, "illegal argument type");
269
+ }
270
+ headerAddOrAppendEntry(RPM_HEADER(pkg),NUM2INT(tag),RPM_STRING_ARRAY_TYPE,&RSTRING(val)->ptr,1);
271
+ return Qnil;
272
+ }
273
+
274
+ VALUE
275
+ rpm_package_add_string(VALUE pkg,VALUE tag,VALUE val)
276
+ {
277
+ if ((TYPE(val) != T_STRING)) {
278
+ rb_raise(rb_eTypeError, "illegal argument type");
279
+ }
280
+ headerAddEntry(RPM_HEADER(pkg),NUM2INT(tag),RPM_STRING_TYPE,RSTRING(val)->ptr,1);
281
+ return Qnil;
282
+ }
283
+
284
+ VALUE
285
+ rpm_package_add_binary(VALUE pkg,VALUE tag,VALUE val)
286
+ {
287
+ if ((TYPE(val) != T_STRING)) {
288
+ rb_raise(rb_eTypeError, "illegal argument type");
289
+ }
290
+ headerAddEntry(RPM_HEADER(pkg),NUM2INT(tag),RPM_BIN_TYPE,RSTRING(val)->ptr,RSTRING(val)->len);
291
+ return Qnil;
292
+ }
293
+
294
+ VALUE
295
+ rpm_package_delete_tag(VALUE pkg, VALUE tag)
296
+ {
297
+ rpmTag tagval = NUM2INT(tag);
298
+ VALUE val;
299
+
300
+ val = rpm_package_aref(pkg, tag);
301
+ headerRemoveEntry(RPM_HEADER(pkg), tagval);
302
+ return val;
303
+ }
304
+
305
+ VALUE
306
+ rpm_package_aref(VALUE pkg, VALUE tag)
307
+ {
308
+ rpmTag tagval = NUM2INT(tag);
309
+ VALUE val = Qnil;
310
+ void* data;
311
+ rpmTagType type;
312
+ int_32 count;
313
+ register int i;
314
+ register const char* p;
315
+ int ary_p = 0;
316
+ int i18n_p = 0;
317
+
318
+ if (!headerGetEntryMinMemory(RPM_HEADER(pkg), tagval, (hTYP_t)&type,
319
+ (hPTR_t*)&data, (hCNT_t)&count)) {
320
+ goto leave;
321
+ }
322
+ switch (tagval) {
323
+ case RPMTAG_DIRINDEXES:
324
+ case RPMTAG_FILESIZES:
325
+ case RPMTAG_FILESTATES:
326
+ case RPMTAG_FILEMODES:
327
+ case RPMTAG_FILERDEVS:
328
+ case RPMTAG_FILEMTIMES:
329
+ case RPMTAG_FILEMD5S:
330
+ case RPMTAG_FILEFLAGS:
331
+ case RPMTAG_FILEUSERNAME:
332
+ case RPMTAG_FILEGROUPNAME:
333
+ case RPMTAG_PROVIDEFLAGS:
334
+ case RPMTAG_REQUIREFLAGS:
335
+ case RPMTAG_CONFLICTFLAGS:
336
+ case RPMTAG_OBSOLETEFLAGS:
337
+ ary_p = 1;
338
+ break;
339
+
340
+ case RPMTAG_GROUP:
341
+ case RPMTAG_SUMMARY:
342
+ case RPMTAG_DISTRIBUTION:
343
+ case RPMTAG_VENDOR:
344
+ case RPMTAG_LICENSE:
345
+ case RPMTAG_PACKAGER:
346
+ case RPMTAG_DESCRIPTION:
347
+ i18n_p = 1;
348
+ break;
349
+ default:
350
+ break;
351
+ }
352
+
353
+ switch (type) {
354
+ case RPM_BIN_TYPE:
355
+ val = rb_str_new(data, count);
356
+ break;
357
+
358
+ case RPM_CHAR_TYPE:
359
+ case RPM_INT8_TYPE:
360
+ if (count == 1 && !ary_p) {
361
+ val = INT2NUM(*(int_8*)data);
362
+ } else {
363
+ val = rb_ary_new();
364
+ for (i = 0; i < count; i++) {
365
+ rb_ary_push(val, INT2NUM(((int_8*)data)[i]));
366
+ }
367
+ }
368
+ break;
369
+
370
+ case RPM_INT16_TYPE:
371
+ if (count == 1 && !ary_p) {
372
+ val = INT2NUM(*(int_16*)data);
373
+ } else {
374
+ val = rb_ary_new();
375
+ for (i = 0; i < count; i++) {
376
+ rb_ary_push(val, INT2NUM(((int_16*)data)[i]));
377
+ }
378
+ }
379
+ break;
380
+
381
+ case RPM_INT32_TYPE:
382
+ if (count == 1 && !ary_p) {
383
+ val = INT2NUM(*(int_32*)data);
384
+ } else {
385
+ val = rb_ary_new();
386
+ for (i = 0; i < count; i++) {
387
+ rb_ary_push(val, INT2NUM(((int_32*)data)[i]));
388
+ }
389
+ }
390
+ break;
391
+
392
+ case RPM_STRING_TYPE:
393
+ if (count == 1 && !ary_p) {
394
+ val = rb_str_new2((char*)data);
395
+ } else {
396
+ char** p = (char**)data;
397
+ val = rb_ary_new();
398
+ for (i = 0; i < count; i++) {
399
+ rb_ary_push(val, rb_str_new2(p[i]));
400
+ }
401
+ }
402
+ release_entry(type, data);
403
+ break;
404
+
405
+ case RPM_STRING_ARRAY_TYPE:
406
+ {
407
+ char** p = (char**)data;
408
+ if (i18n_p) {
409
+ char** i18ntab;
410
+ rpmTagType i18nt;
411
+ int_32 i18nc;
412
+
413
+ if (!headerGetEntryMinMemory(
414
+ RPM_HEADER(pkg), HEADER_I18NTABLE, (hTYP_t)&i18nt,
415
+ (hPTR_t*)&i18ntab, (hCNT_t)&i18nc)) {
416
+ goto strary;
417
+ }
418
+
419
+ val = rb_hash_new();
420
+ for (i = 0; i < count; i++) {
421
+ VALUE lang = rb_str_new2(i18ntab[i]);
422
+ VALUE str = rb_str_new2(p[i]);
423
+ rb_hash_aset(val, lang, str);
424
+ }
425
+ release_entry(i18nt, (void*)i18ntab);
426
+ } else {
427
+ strary:
428
+ val = rb_ary_new();
429
+ for (i = 0; i < count; i++) {
430
+ rb_ary_push(val, rb_str_new2(p[i]));
431
+ }
432
+ }
433
+ release_entry(type, data);
434
+ }
435
+ break;
436
+
437
+ default:
438
+ goto leave;
439
+ }
440
+ leave:
441
+ return val;
442
+ }
443
+
444
+ VALUE
445
+ rpm_package_sprintf(VALUE pkg, VALUE fmt)
446
+ {
447
+ const char *errstr = "(unknown error)";
448
+ const char *str;
449
+
450
+ str = headerSprintf(RPM_HEADER(pkg), StringValueCStr(fmt),
451
+ rpmTagTable, rpmHeaderFormats, &errstr);
452
+ if (str == NULL) {
453
+ rb_raise(rb_eRuntimeError, "incorrect format: %s",
454
+ errstr);
455
+ }
456
+ return rb_str_new2(str);
457
+ }
458
+
459
+ VALUE
460
+ rpm_package_get_name(VALUE pkg)
461
+ {
462
+ VALUE name;
463
+ const char* n;
464
+ headerNVR(RPM_HEADER(pkg), &n, NULL, NULL);
465
+ name = n ? rb_str_new2(n) : Qnil;
466
+
467
+ return name;
468
+ }
469
+
470
+ VALUE
471
+ rpm_package_get_arch(VALUE pkg)
472
+ {
473
+ VALUE arch;
474
+ const char* a;
475
+ headerNEVRA(RPM_HEADER(pkg), NULL, NULL, NULL, NULL, &a);
476
+ arch = a ? rb_str_new2(a) : Qnil;
477
+
478
+ return arch;
479
+ }
480
+
481
+ VALUE
482
+ rpm_package_get_signature(VALUE pkg)
483
+ {
484
+ VALUE signature = rb_ivar_get(pkg, id_signature);
485
+
486
+ if (NIL_P(signature)) {
487
+ char *sigmd5;
488
+ sigmd5 = headerSprintf(RPM_HEADER(pkg),"%{sigmd5}",
489
+ rpmTagTable, rpmHeaderFormats, NULL);
490
+ if(sigmd5[0]){
491
+ signature = INT2NUM(rb_intern(sigmd5));
492
+ rb_ivar_set(pkg, id_signature, signature);
493
+ }
494
+ free(sigmd5);
495
+ }
496
+ return signature;
497
+ }
498
+
499
+ VALUE
500
+ rpm_package_get_version(VALUE pkg)
501
+ {
502
+ VALUE ver;
503
+ const char* v;
504
+ const char* r;
505
+ VALUE e;
506
+
507
+ headerNVR(RPM_HEADER(pkg), NULL, &v, &r);
508
+ if (!v) {
509
+ ver = Qnil;
510
+ } else if (!r) {
511
+ ver = rpm_version_new(v);
512
+ } else {
513
+ e = rpm_package_aref(pkg, INT2NUM(RPMTAG_EPOCH));
514
+ if (NIL_P(e)) {
515
+ char* buf = ALLOCA_N(char, strlen(v) + strlen(r) + 2);
516
+ sprintf(buf, "%s-%s", v, r);
517
+ ver = rpm_version_new(buf);
518
+ } else {
519
+ ver = rpm_version_new3(v, r, NUM2INT(e));
520
+ }
521
+ }
522
+
523
+ return ver;
524
+ }
525
+
526
+ VALUE
527
+ rpm_package_get_files(VALUE pkg)
528
+ {
529
+ VALUE files;
530
+ VALUE basenames = rpm_package_aref(pkg, INT2NUM(RPMTAG_BASENAMES));
531
+ VALUE dirnames = rpm_package_aref(pkg, INT2NUM(RPMTAG_DIRNAMES));
532
+ VALUE diridxs = rpm_package_aref(pkg, INT2NUM(RPMTAG_DIRINDEXES));
533
+ VALUE statelist = rpm_package_aref(pkg, INT2NUM(RPMTAG_FILESTATES));
534
+ VALUE flaglist = rpm_package_aref(pkg, INT2NUM(RPMTAG_FILEFLAGS));
535
+ VALUE sizelist = rpm_package_aref(pkg, INT2NUM(RPMTAG_FILESIZES));
536
+ VALUE modelist = rpm_package_aref(pkg, INT2NUM(RPMTAG_FILEMODES));
537
+ VALUE mtimelist = rpm_package_aref(pkg, INT2NUM(RPMTAG_FILEMTIMES));
538
+ VALUE rdevlist = rpm_package_aref(pkg, INT2NUM(RPMTAG_FILERDEVS));
539
+ VALUE linklist = rpm_package_aref(pkg, INT2NUM(RPMTAG_FILELINKTOS));
540
+ VALUE md5list = rpm_package_aref(pkg, INT2NUM(RPMTAG_FILEMD5S));
541
+ VALUE ownerlist = rpm_package_aref(pkg, INT2NUM(RPMTAG_FILEUSERNAME));
542
+ VALUE grouplist = rpm_package_aref(pkg, INT2NUM(RPMTAG_FILEGROUPNAME));
543
+ register int i;
544
+
545
+ files = rb_ary_new();
546
+ if (!NIL_P(basenames)) {
547
+ for (i = 0; i < RARRAY(basenames)->len; i++) {
548
+ static char buf[BUFSIZ];
549
+ VALUE file;
550
+ buf[0] = '\0';
551
+ stpcpy(stpcpy(buf, RSTRING(RARRAY(dirnames)->ptr[
552
+ NUM2INT(RARRAY(diridxs)->ptr[i])])->ptr),
553
+ RSTRING(RARRAY(basenames)->ptr[i])->ptr);
554
+ file = rpm_file_new(
555
+ buf,
556
+ RSTRING(RARRAY(md5list)->ptr[i])->ptr,
557
+ (NIL_P(linklist)
558
+ ? NULL
559
+ : RSTRING(RARRAY(linklist)->ptr[i])->ptr),
560
+ NUM2UINT(RARRAY(sizelist)->ptr[i]),
561
+ NUM2INT(RARRAY(mtimelist)->ptr[i]),
562
+ (NIL_P(ownerlist)
563
+ ? NULL
564
+ : RSTRING(RARRAY(ownerlist)->ptr[i])->ptr),
565
+ (NIL_P(grouplist)
566
+ ? NULL
567
+ : RSTRING(RARRAY(grouplist)->ptr[i])->ptr),
568
+ NUM2UINT(RARRAY(rdevlist)->ptr[i]),
569
+ NUM2UINT(RARRAY(modelist)->ptr[i]),
570
+ (NIL_P(flaglist)
571
+ ? RPMFILE_NONE
572
+ : NUM2INT(RARRAY(flaglist)->ptr[i])),
573
+ (NIL_P(statelist)
574
+ ? RPMFILE_STATE_NORMAL
575
+ : NUM2INT(RARRAY(statelist)->ptr[i])));
576
+ rb_ary_push(files, file);
577
+ }
578
+ }
579
+ return files;
580
+ }
581
+
582
+ VALUE
583
+ rpm_package_get_dependency(VALUE pkg,int nametag,int versiontag,int flagtag,VALUE (*dependency_new)(const char*,VALUE,int,VALUE))
584
+ {
585
+ VALUE deps;
586
+ register int i;
587
+
588
+ char **names,**versions;
589
+ int_32 *flags;
590
+ rpmTagType nametype,versiontype,flagtype;
591
+ int_32 count;
592
+
593
+ deps = rb_ary_new();
594
+
595
+ if (!headerGetEntryMinMemory(RPM_HEADER(pkg), nametag, (hTYP_t)&nametype,
596
+ (hPTR_t*)&names, (hCNT_t)&count)) {
597
+ return deps;
598
+ }
599
+ if (!headerGetEntryMinMemory(RPM_HEADER(pkg), versiontag, (hTYP_t)&versiontype,
600
+ (hPTR_t*)&versions, (hCNT_t)&count)) {
601
+ release_entry(nametype, (void*)names);
602
+ return deps;
603
+ }
604
+ if (!headerGetEntryMinMemory(RPM_HEADER(pkg), flagtag, (hTYP_t)&flagtype,
605
+ (hPTR_t*)&flags, (hCNT_t)&count)) {
606
+ release_entry(nametype, (void*)names);
607
+ release_entry(versiontype, (void*)versions);
608
+ return deps;
609
+ }
610
+
611
+ for (i = 0; i < count; i++) {
612
+ rb_ary_push(deps,dependency_new(names[i],rpm_version_new(versions[i]),flags[i],pkg));
613
+ }
614
+
615
+ release_entry(nametype, (void*)names);
616
+ release_entry(versiontype, (void*)versions);
617
+ release_entry(flagtype, (void*)flags);
618
+ return deps;
619
+ }
620
+
621
+ VALUE
622
+ rpm_package_get_provides(VALUE pkg)
623
+ {
624
+ return rpm_package_get_dependency(pkg,RPMTAG_PROVIDENAME,RPMTAG_PROVIDEVERSION,RPMTAG_PROVIDEFLAGS,rpm_provide_new);
625
+ }
626
+
627
+ VALUE
628
+ rpm_package_get_requires(VALUE pkg)
629
+ {
630
+ return rpm_package_get_dependency(pkg,RPMTAG_REQUIRENAME,RPMTAG_REQUIREVERSION,RPMTAG_REQUIREFLAGS,rpm_require_new);
631
+ }
632
+
633
+ VALUE
634
+ rpm_package_get_conflicts(VALUE pkg)
635
+ {
636
+ return rpm_package_get_dependency(pkg,RPMTAG_CONFLICTNAME,RPMTAG_CONFLICTVERSION,RPMTAG_CONFLICTFLAGS,rpm_conflict_new);
637
+ }
638
+
639
+ VALUE
640
+ rpm_package_get_obsoletes(VALUE pkg)
641
+ {
642
+ return rpm_package_get_dependency(pkg,RPMTAG_OBSOLETENAME,RPMTAG_OBSOLETEVERSION,RPMTAG_OBSOLETEFLAGS,rpm_obsolete_new);
643
+ }
644
+
645
+ VALUE
646
+ rpm_package_get_changelog(VALUE pkg)
647
+ {
648
+ VALUE cl;
649
+ register int i;
650
+
651
+ char **times,**names,**texts;
652
+ rpmTagType timetype,nametype,texttype;
653
+ int_32 count;
654
+
655
+ cl = rb_ary_new();
656
+
657
+ if (!headerGetEntryMinMemory(RPM_HEADER(pkg), RPMTAG_CHANGELOGTIME, (hTYP_t)&timetype,
658
+ (hPTR_t*)&times, (hCNT_t)&count)) {
659
+ return cl;
660
+ }
661
+ if (!headerGetEntryMinMemory(RPM_HEADER(pkg), RPMTAG_CHANGELOGNAME, (hTYP_t)&nametype,
662
+ (hPTR_t*)&names, (hCNT_t)&count)) {
663
+ release_entry(timetype, (void*)times);
664
+ return cl;
665
+ }
666
+ if (!headerGetEntryMinMemory(RPM_HEADER(pkg), RPMTAG_CHANGELOGTEXT, (hTYP_t)&texttype,
667
+ (hPTR_t*)&texts, (hCNT_t)&count)) {
668
+ release_entry(timetype, (void*)times);
669
+ release_entry(nametype, (void*)names);
670
+ return cl;
671
+ }
672
+
673
+ for (i = 0; i < count; i++) {
674
+ VALUE chglog = rb_struct_new(
675
+ rpm_sChangeLog,
676
+ rb_time_new((time_t)times[i], (time_t)0),
677
+ rb_str_new2(names[i]),
678
+ rb_str_new2(texts[i]));
679
+ rb_ary_push(cl, chglog);
680
+ }
681
+ return cl;
682
+ }
683
+
684
+ VALUE
685
+ rpm_package_dump(VALUE pkg)
686
+ {
687
+ VALUE dump, temp;
688
+ FD_t fd;
689
+ off_t size;
690
+ char* buf;
691
+
692
+ temp = ruby_rpm_make_temp_name();
693
+ fd = Fopen(RSTRING(temp)->ptr, "wb+");
694
+ headerWrite(fd, RPM_HEADER(pkg), HEADER_MAGIC_YES);
695
+ size = fdSize(fd);
696
+
697
+ buf = mmap(NULL, size, PROT_READ, MAP_PRIVATE, Fileno(fd), 0);
698
+ dump = rb_str_new(buf, size);
699
+ munmap(buf, size);
700
+
701
+ Fclose(fd);
702
+ Unlink(RSTRING(temp)->ptr);
703
+
704
+ return dump;
705
+ }
706
+
707
+ VALUE
708
+ rpm_package__dump(VALUE pkg, VALUE limit)
709
+ {
710
+ return rpm_package_dump(pkg);
711
+ }
712
+
713
+ VALUE
714
+ rpm_package_to_s(VALUE pkg)
715
+ {
716
+ char buf[BUFSIZ];
717
+ VALUE name = rpm_package_get_name(pkg);
718
+ VALUE ver = rpm_package_get_version(pkg);
719
+ VALUE arch = rpm_package_get_arch(pkg);
720
+
721
+ if (NIL_P(name)) {
722
+ buf[0] = '\0';
723
+ } else if (NIL_P(ver)) {
724
+ snprintf(buf, BUFSIZ, "%s", RSTRING(name)->ptr);
725
+ } else if (NIL_P(arch)) {
726
+ snprintf(buf, BUFSIZ, "%s-%s",
727
+ RSTRING(name)->ptr,
728
+ RSTRING(rpm_version_to_s(ver))->ptr);
729
+ } else {
730
+ snprintf(buf, BUFSIZ, "%s-%s-%s",
731
+ RSTRING(name)->ptr,
732
+ RSTRING(rpm_version_to_s(ver))->ptr,
733
+ RSTRING(arch)->ptr);
734
+ }
735
+
736
+ return rb_str_new2(buf);
737
+ }
738
+
739
+ VALUE
740
+ rpm_package_inspect(VALUE pkg)
741
+ {
742
+ char buf[BUFSIZ];
743
+ VALUE name = rpm_package_get_name(pkg);
744
+ VALUE ver = rpm_package_get_version(pkg);
745
+
746
+ if (NIL_P(name)) {
747
+ buf[0] = '\0';
748
+ } else if (NIL_P(ver)) {
749
+ snprintf(buf, BUFSIZ, "#<RPM::Package name=%s>",
750
+ RSTRING(rb_inspect(name))->ptr);
751
+ } else {
752
+ snprintf(buf, BUFSIZ, "#<RPM::Package name=%s, version=%s>",
753
+ RSTRING(rb_inspect(name))->ptr,
754
+ RSTRING(rb_inspect(ver))->ptr);
755
+ }
756
+
757
+ return rb_str_new2(buf);
758
+ }
759
+
760
+ void
761
+ Init_rpm_package(void)
762
+ {
763
+ rpm_cPackage = rb_define_class_under(rpm_mRPM, "Package", rb_cObject);
764
+ rb_define_singleton_method(rpm_cPackage, "open", package_s_open, 1);
765
+ rb_define_singleton_method(rpm_cPackage, "new", package_s_open, 1);
766
+ rb_define_singleton_method(rpm_cPackage, "create", package_s_create, 2);
767
+ rb_define_singleton_method(rpm_cPackage, "load", package_s_load, 1);
768
+ rb_define_alias(rb_singleton_class(rpm_cPackage), "_load", "load");
769
+ rb_define_singleton_method(rpm_cPackage, "clear_cache", package_clear_cache, 0);
770
+ rb_define_singleton_method(rpm_cPackage, "use_cache=", package_use_cache, 1);
771
+ rb_define_method(rpm_cPackage, "[]", rpm_package_aref, 1);
772
+ rb_define_method(rpm_cPackage, "delete_tag", rpm_package_delete_tag, 1);
773
+ rb_define_method(rpm_cPackage, "sprintf", rpm_package_sprintf, 1);
774
+ rb_define_method(rpm_cPackage, "signature", rpm_package_get_signature, 0);
775
+ rb_define_method(rpm_cPackage, "arch", rpm_package_get_arch, 0);
776
+ rb_define_method(rpm_cPackage, "name", rpm_package_get_name, 0);
777
+ rb_define_method(rpm_cPackage, "version", rpm_package_get_version, 0);
778
+ rb_define_method(rpm_cPackage, "files", rpm_package_get_files, 0);
779
+ rb_define_method(rpm_cPackage, "provides", rpm_package_get_provides, 0);
780
+ rb_define_method(rpm_cPackage, "requires", rpm_package_get_requires, 0);
781
+ rb_define_method(rpm_cPackage, "conflicts", rpm_package_get_conflicts, 0);
782
+ rb_define_method(rpm_cPackage, "obsoletes", rpm_package_get_obsoletes, 0);
783
+ rb_define_method(rpm_cPackage, "changelog", rpm_package_get_changelog, 0);
784
+ rb_define_method(rpm_cPackage, "add_dependency", rpm_package_add_dependency, 1);
785
+ rb_define_method(rpm_cPackage, "add_string", rpm_package_add_string, 2);
786
+ rb_define_method(rpm_cPackage, "add_string_array", rpm_package_add_string_array, 2);
787
+ rb_define_method(rpm_cPackage, "add_int32", rpm_package_add_int32, 2);
788
+ rb_define_method(rpm_cPackage, "add_binary", rpm_package_add_binary, 2);
789
+ rb_define_method(rpm_cPackage, "dump", rpm_package_dump, 0);
790
+ rb_define_method(rpm_cPackage, "_dump", rpm_package__dump, 1);
791
+ rb_define_method(rpm_cPackage, "to_s", rpm_package_to_s, 0);
792
+ rb_define_method(rpm_cPackage, "inspect", rpm_package_inspect, 0);
793
+ rb_define_method(rpm_cPackage, "copy_to", rpm_package_copy_tags, 2);
794
+
795
+ rpm_sChangeLog = rb_struct_define(NULL, "time", "name", "text", NULL);
796
+ rb_define_const(rpm_mRPM, "ChangeLog", rpm_sChangeLog);
797
+
798
+ id_signature = rb_intern("signature");
799
+ package_use_cache(rpm_cPackage,Qtrue);
800
+ }