ruby-rpm 1.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,13 @@
1
+ MANIFEST
2
+ db.c
3
+ dependency.c
4
+ extconf.rb
5
+ file.c
6
+ package.c
7
+ private.h
8
+ rpm.c
9
+ ruby-rpm.h
10
+ source.c
11
+ spec.c
12
+ version.c
13
+ rpm40_compat.c
@@ -0,0 +1,1128 @@
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: db.c 45 2004-06-04 15:11:20Z kazuhiko $ */
8
+
9
+ #include "private.h"
10
+
11
+ VALUE rpm_cDB;
12
+ VALUE rpm_cTransaction;
13
+ VALUE rpm_cMatchIterator;
14
+ VALUE rpm_sCallbackData;
15
+ VALUE rpm_sProblem;
16
+
17
+ static ID id_db;
18
+ static ID id_sf;
19
+ static ID id_keys;
20
+ static ID id_commited;
21
+ static ID id_aborted;
22
+ static ID id_pl;
23
+ static ID id_type;
24
+ static ID id_key;
25
+ static ID id_pkg;
26
+ static ID id_mes;
27
+ static ID id_amount;
28
+ static ID id_total;
29
+ static ID id_file;
30
+ static ID id_fdt;
31
+
32
+ static void
33
+ db_ref(rpm_db_t* db){
34
+ db->ref_count++;
35
+ }
36
+
37
+ static void
38
+ db_unref(rpm_db_t* db){
39
+ db->ref_count--;
40
+ if (!db->ref_count){
41
+ rpmdbClose(db->db);
42
+ free(db);
43
+ }
44
+ }
45
+
46
+ static void
47
+ db_free(rpm_db_t* db)
48
+ {
49
+ if (db)
50
+ db_unref(db);
51
+ }
52
+
53
+ static VALUE
54
+ db_s_open(int argc, VALUE* argv, VALUE obj)
55
+ {
56
+ VALUE db;
57
+ rpm_db_t* rdb;
58
+ int writable = 0;
59
+ const char* root = "";
60
+
61
+ switch (argc) {
62
+ case 0:
63
+ break;
64
+
65
+ case 1:
66
+ writable = RTEST(argv[0]);
67
+ break;
68
+
69
+ case 2:
70
+ if (!NIL_P(argv[1])) {
71
+ if (TYPE(argv[1]) != T_STRING) {
72
+ rb_raise(rb_eTypeError, "illegal argument type");
73
+ }
74
+ root = RSTRING(argv[1])->ptr;
75
+ }
76
+ writable = RTEST(argv[0]);
77
+ break;
78
+
79
+ default:
80
+ rb_raise(rb_eArgError, "too many argument(0..2)");
81
+ }
82
+
83
+
84
+ rdb = ALLOC_N(rpm_db_t,1);
85
+ if (rpmdbOpen(root, &(rdb->db), writable ? O_RDWR | O_CREAT : O_RDONLY, 0644)) {
86
+ free(rdb);
87
+ rb_raise(rb_eRuntimeError, "can not open database in %s",
88
+ RSTRING(rb_str_concat(rb_str_new2(root),
89
+ rb_str_new2("/var/lib/rpm")))->ptr);
90
+ }
91
+
92
+ rdb->ref_count = 0;
93
+ db_ref(rdb);
94
+ db = Data_Wrap_Struct(rpm_cDB, NULL, db_free, rdb);
95
+ if (!writable) {
96
+ rb_obj_freeze(db);
97
+ }
98
+ return db;
99
+ }
100
+
101
+ VALUE
102
+ rpm_db_open(int writable, const char* root)
103
+ {
104
+ VALUE argv[2];
105
+ argv[0] = writable ? Qtrue : Qfalse;
106
+ argv[1] = root ? rb_str_new2(root) : Qnil;
107
+ return db_s_open(2, argv, rpm_cDB);
108
+ }
109
+
110
+ static VALUE
111
+ db_s_init(int argc, VALUE* argv, VALUE obj)
112
+ {
113
+ int writable = 0;
114
+ const char* root;
115
+
116
+ switch (argc) {
117
+ case 0:
118
+ rb_raise(rb_eArgError, "too few argument(1..2)");
119
+
120
+ case 1: case 2:
121
+ if (TYPE(argv[0]) != T_STRING) {
122
+ rb_raise(rb_eTypeError, "illegal argument type");
123
+ }
124
+ root = RSTRING(argv[0])->ptr;
125
+ if (argc == 2) {
126
+ writable = RTEST(argv[1]);
127
+ }
128
+ break;
129
+
130
+ default:
131
+ rb_raise(rb_eArgError, "too many argument(1..2)");
132
+ }
133
+
134
+ if (rpmdbInit(root, writable ? O_RDWR | O_CREAT : O_RDONLY)) {
135
+ rb_raise(rb_eRuntimeError, "can not initialize database in %s",
136
+ RSTRING(rb_str_concat(rb_str_new2(root),
137
+ rb_str_new2("/var/lib/rpm")))->ptr);
138
+ }
139
+
140
+ return Qnil;
141
+ }
142
+
143
+ void
144
+ rpm_db_init(const char* root, int writable)
145
+ {
146
+ VALUE argv[2];
147
+ argv[0] = rb_str_new2(root);
148
+ argv[1] = writable ? Qtrue : Qfalse;
149
+ db_s_init(2, argv, rpm_cDB);
150
+ }
151
+
152
+ static VALUE
153
+ db_s_rebuild(int argc, VALUE* argv, VALUE obj)
154
+ {
155
+ const char* root = "";
156
+ int ret;
157
+
158
+ switch (argc) {
159
+ case 0:
160
+ break;
161
+
162
+ case 1:
163
+ if (!NIL_P(argv[0])) {
164
+ if (TYPE(argv[0]) != T_STRING) {
165
+ rb_raise(rb_eTypeError, "illegal argument type");
166
+ }
167
+ root = RSTRING(argv[0])->ptr;
168
+ }
169
+ break;
170
+
171
+ default:
172
+ rb_raise(rb_eArgError, "too many arguments(0..1)");
173
+ break;
174
+ }
175
+
176
+ #if RPM_VERSION_CODE < RPM_VERSION(4,1,0)
177
+ ret = rpmdbRebuild(root);
178
+ #else
179
+ ret = rpmdbRebuild(root, NULL, NULL);
180
+ #endif
181
+ if (ret) {
182
+ rb_raise(rb_eRuntimeError, "can not rebuild database in %s",
183
+ RSTRING(rb_str_concat(rb_str_new2(root),
184
+ rb_str_new2("/var/lib/rpm")))->ptr);
185
+ }
186
+
187
+ return Qnil;
188
+ }
189
+
190
+ void
191
+ rpm_db_rebuild(const char* root)
192
+ {
193
+ VALUE argv[1];
194
+ argv[0] = root ? rb_str_new2(root) : Qnil;
195
+ db_s_rebuild(1, argv, rpm_cDB);
196
+ }
197
+
198
+ VALUE
199
+ rpm_db_close(VALUE db)
200
+ {
201
+ db_unref((rpm_db_t*)DATA_PTR(db));
202
+ DATA_PTR(db) = NULL;
203
+ return Qnil;
204
+ }
205
+
206
+ VALUE
207
+ rpm_db_is_closed(VALUE vdb)
208
+ {
209
+ return DATA_PTR(vdb) ? Qfalse : Qtrue;
210
+ }
211
+
212
+ static void
213
+ check_closed(VALUE db)
214
+ {
215
+ if (!DATA_PTR(db)) {
216
+ rb_raise(rb_eRuntimeError, "RPM::DB closed");
217
+ }
218
+ }
219
+
220
+ VALUE
221
+ rpm_db_get_root(VALUE db)
222
+ {
223
+ check_closed(db);
224
+ return rb_str_new2(RPM_DB(db)->db_root);
225
+ }
226
+
227
+ VALUE
228
+ rpm_db_get_home(VALUE db)
229
+ {
230
+ check_closed(db);
231
+ return rb_str_new2(RPM_DB(db)->db_home);
232
+ }
233
+
234
+ VALUE
235
+ rpm_db_is_writable(VALUE db)
236
+ {
237
+ check_closed(db);
238
+ return OBJ_FROZEN(db) ? Qfalse : Qtrue;
239
+ }
240
+
241
+ VALUE
242
+ rpm_db_each_match(VALUE db, VALUE key, VALUE val)
243
+ {
244
+ VALUE mi;
245
+
246
+ check_closed(db);
247
+
248
+ mi = rpm_db_init_iterator (db, key, val);
249
+
250
+ if (!NIL_P(mi))
251
+ return rpm_mi_each (mi);
252
+ return Qnil;
253
+ }
254
+
255
+ VALUE
256
+ rpm_db_each(VALUE db)
257
+ {
258
+ check_closed(db);
259
+ return rpm_db_each_match(db,INT2NUM(RPMDBI_PACKAGES),Qnil);
260
+ }
261
+
262
+ static void
263
+ transaction_free(rpm_trans_t* trans)
264
+ {
265
+ if (trans->script_fd)
266
+ Fclose(trans->script_fd);
267
+ #if RPM_VERSION_CODE < RPM_VERSION(4,1,0)
268
+ rpmtransFree(trans->ts);
269
+ #else
270
+ rpmtsFree(trans->ts);
271
+ #endif
272
+ db_unref(trans->db);
273
+ free(trans);
274
+ }
275
+
276
+ static VALUE
277
+ transaction_yield(VALUE tag, VALUE ts)
278
+ {
279
+ return rb_yield(ts);
280
+ }
281
+
282
+ static VALUE
283
+ transaction_commit(VALUE tag, VALUE ts)
284
+ {
285
+ rpm_transaction_commit(0, NULL, ts);
286
+
287
+ /* not reached because rpm_transaction_commit() always call rb_throw() */
288
+ return Qnil;
289
+ }
290
+
291
+ VALUE
292
+ rpm_db_transaction(int argc, VALUE* argv, VALUE db)
293
+ {
294
+ VALUE trans;
295
+ rpm_trans_t* ts;
296
+ const char* root = "/";
297
+
298
+ #if 0
299
+ if (OBJ_FROZEN(db)) {
300
+ rb_error_frozen("RPM::DB");
301
+ }
302
+ #endif
303
+ switch (argc) {
304
+ case 0:
305
+ break;
306
+
307
+ case 1:
308
+ if (TYPE(argv[0]) != T_STRING) {
309
+ rb_raise(rb_eTypeError, "illegal argument type");
310
+ }
311
+ root = RSTRING(argv[0])->ptr;
312
+ break;
313
+
314
+ default:
315
+ rb_raise(rb_eArgError, "argument too many(0..1)");
316
+ }
317
+
318
+ ts = ALLOC(rpm_trans_t);
319
+ #if RPM_VERSION_CODE < RPM_VERSION(4,1,0)
320
+ ts->ts = rpmtransCreateSet(RPM_DB(db), root);
321
+ #else
322
+ ts->ts = rpmtsCreate();
323
+ rpmtsSetRootDir(ts->ts, root);
324
+ #endif
325
+ ts->script_fd = 0;
326
+ ts->db = DATA_PTR(db);
327
+ trans = Data_Wrap_Struct(rpm_cTransaction, NULL, transaction_free, ts);
328
+ db_ref(ts->db);
329
+ rb_ivar_set(trans, id_db, db);
330
+
331
+ rb_catch("abort", transaction_yield, trans);
332
+
333
+ if (rb_ivar_get(trans, id_aborted) == Qtrue) {
334
+ return Qfalse;
335
+ } else if (rb_ivar_get(trans, id_commited) != Qtrue && !OBJ_FROZEN(db)) {
336
+ rb_catch("abort", transaction_commit, trans);
337
+ }
338
+
339
+ return rb_ivar_get(trans, id_pl);
340
+ }
341
+
342
+ VALUE
343
+ rpm_transaction_get_db(VALUE trans)
344
+ {
345
+ return rb_ivar_get(trans, id_db);
346
+ }
347
+
348
+ VALUE
349
+ rpm_transaction_get_script_file(VALUE trans)
350
+ {
351
+ return rb_ivar_get(trans, id_sf);
352
+ }
353
+
354
+ VALUE
355
+ rpm_transaction_set_script_file(VALUE trans, VALUE file)
356
+ {
357
+ if (TYPE(file) != T_FILE) {
358
+ rb_raise(rb_eTypeError, "illegal argument type");
359
+ }
360
+ rb_ivar_set(trans, id_sf, file);
361
+ RPM_SCRIPT_FD(trans) = fdDup(NUM2INT(rb_Integer(file)));
362
+ #if RPM_VERSION_CODE < RPM_VERSION(4,1,0)
363
+ rpmtransSetScriptFd(RPM_TRANSACTION(trans), RPM_SCRIPT_FD(trans));
364
+ #else
365
+ rpmtsSetScriptFd(RPM_TRANSACTION(trans), RPM_SCRIPT_FD(trans));
366
+ #endif
367
+ return Qnil;
368
+ }
369
+
370
+ VALUE
371
+ rpm_transaction_install(VALUE trans, VALUE pkg, VALUE key)
372
+ {
373
+ VALUE keys;
374
+
375
+ if (rb_obj_is_kind_of(pkg, rpm_cPackage) == Qfalse ||
376
+ TYPE(key) != T_STRING) {
377
+ rb_raise(rb_eTypeError, "illegal argument type");
378
+ }
379
+
380
+ keys = rb_ivar_get(trans, id_keys);
381
+
382
+ if (NIL_P(keys)) {
383
+ keys = rb_ary_new();
384
+ rb_ivar_set(trans, id_keys, keys);
385
+ }
386
+ if (rb_ary_includes(keys, key) == Qtrue) {
387
+ rb_raise(rb_eArgError, "key must be unique");
388
+ }
389
+ rb_ary_push(keys, key);
390
+
391
+ #if RPM_VERSION_CODE < RPM_VERSION(4,1,0)
392
+ rpmtransAddPackage(RPM_TRANSACTION(trans), RPM_HEADER(pkg), NULL,
393
+ RSTRING(key)->ptr, 0, NULL);
394
+ #else
395
+ rpmtsAddInstallElement(RPM_TRANSACTION(trans), RPM_HEADER(pkg),
396
+ RSTRING(key)->ptr, 0, NULL);
397
+ #endif
398
+
399
+ return Qnil;
400
+ }
401
+
402
+ VALUE
403
+ rpm_transaction_upgrade(VALUE trans, VALUE pkg, VALUE key)
404
+ {
405
+ VALUE keys;
406
+ if (rb_obj_is_kind_of(pkg, rpm_cPackage) == Qfalse ||
407
+ TYPE(key) != T_STRING) {
408
+ rb_raise(rb_eTypeError, "illegal argument type");
409
+ }
410
+
411
+ keys = rb_ivar_get(trans, id_keys);
412
+
413
+ if (NIL_P(keys)) {
414
+ keys = rb_ary_new();
415
+ rb_ivar_set(trans, id_keys, keys);
416
+ }
417
+ if (rb_ary_includes(keys, key) == Qtrue) {
418
+ rb_raise(rb_eArgError, "key must be unique");
419
+ }
420
+ rb_ary_push(keys, key);
421
+ #if RPM_VERSION_CODE < RPM_VERSION(4,1,0)
422
+ rpmtransAddPackage(RPM_TRANSACTION(trans), RPM_HEADER(pkg), NULL,
423
+ RSTRING(key)->ptr, 1, NULL);
424
+ #else
425
+ rpmtsAddInstallElement(RPM_TRANSACTION(trans), RPM_HEADER(pkg),
426
+ RSTRING(key)->ptr, 1, NULL);
427
+ #endif
428
+
429
+ return Qnil;
430
+ }
431
+
432
+ VALUE
433
+ rpm_transaction_available(VALUE trans, VALUE pkg, VALUE key)
434
+ {
435
+ VALUE keys;
436
+
437
+ if (rb_obj_is_kind_of(pkg, rpm_cPackage) == Qfalse ||
438
+ TYPE(key) != T_STRING) {
439
+ rb_raise(rb_eTypeError, "illegal argument type");
440
+ }
441
+
442
+ keys = rb_ivar_get(trans, id_keys);
443
+ if (NIL_P(keys)) {
444
+ keys = rb_ary_new();
445
+ rb_ivar_set(trans, id_keys, keys);
446
+ }
447
+ if (rb_ary_includes(keys, key) == Qtrue) {
448
+ rb_raise(rb_eArgError, "key must be unique");
449
+ }
450
+ rb_ary_push(keys, key);
451
+
452
+ #if RPM_VERSION_CODE < RPM_VERSION(4,1,0)
453
+ rpmtransAvailablePackage(RPM_TRANSACTION(trans), RPM_HEADER(pkg),
454
+ RSTRING(key)->ptr);
455
+ #else
456
+ rpmtsAvailablePackage(RPM_TRANSACTION(trans), RPM_HEADER(pkg),
457
+ RSTRING(key)->ptr);
458
+ #endif
459
+
460
+ return Qnil;
461
+ }
462
+
463
+ VALUE
464
+ rpm_transaction_delete(VALUE trans, VALUE pkg)
465
+ {
466
+ VALUE db;
467
+ VALUE mi;
468
+
469
+ db = rb_ivar_get(trans, id_db);
470
+
471
+ if (TYPE(pkg) == T_STRING)
472
+ mi = rpm_db_init_iterator(db, INT2NUM(RPMDBI_LABEL), pkg);
473
+ else if (rb_obj_is_kind_of(pkg, rpm_cPackage) != Qfalse) {
474
+ VALUE sigmd5 = rpm_package_aref(pkg,INT2NUM(RPMTAG_SIGMD5));
475
+ if (sigmd5 != Qnil){
476
+ mi = rpm_db_init_iterator(db, INT2NUM(RPMTAG_SIGMD5), sigmd5);
477
+ }else{
478
+ VALUE name = rpm_package_aref(pkg,INT2NUM(RPMDBI_LABEL));
479
+ mi = rpm_db_init_iterator(db, INT2NUM(RPMDBI_LABEL), name);
480
+ }
481
+ } else if ( rb_obj_is_kind_of(pkg, rpm_cDependency) ==Qfalse &&
482
+ rb_respond_to(pkg,rb_intern("name")) && rb_respond_to(pkg,rb_intern("version"))){
483
+ VALUE name = rb_funcall(pkg,rb_intern("name"),0);
484
+ mi = rpm_db_init_iterator(db, INT2NUM(RPMDBI_LABEL),rb_funcall(pkg,rb_intern("name"),0));
485
+ rpm_mi_set_iterator_version(mi,rb_funcall(pkg,rb_intern("version"),0));
486
+ } else
487
+ rb_raise(rb_eTypeError, "illegal argument type");
488
+
489
+ VALUE p;
490
+ while (!NIL_P(p = rpm_mi_next_iterator(mi))) {
491
+ VALUE off = rpm_mi_get_iterator_offset(mi);
492
+ if (!NIL_P(off)){
493
+ #if RPM_VERSION_CODE < RPM_VERSION(4,1,0)
494
+ rpmtransRemovePackage(RPM_TRANSACTION(trans), NUM2INT(off));
495
+ #else
496
+ rpmtsAddEraseElement(RPM_TRANSACTION(trans), RPM_HEADER(p), NUM2INT(off));
497
+ #endif
498
+ }
499
+ }
500
+
501
+ return Qnil;
502
+ }
503
+
504
+ #if RPM_VERSION(4,1,0) <= RPM_VERSION_CODE
505
+
506
+ /* from rpm-4.2.1/lib/rpmps.c */
507
+ static int
508
+ sameProblem(const rpmProblem p1, const rpmProblem p2)
509
+ {
510
+ if (p1->type != p2->type)
511
+ return 1;
512
+ if (p1->pkgNEVR)
513
+ if (p2->pkgNEVR && strcmp(p1->pkgNEVR, p2->pkgNEVR))
514
+ return 1;
515
+ if (p1->altNEVR)
516
+ if (p2->altNEVR && strcmp(p1->altNEVR, p2->altNEVR))
517
+ return 1;
518
+ if (p1->str1)
519
+ if (p2->str1 && strcmp(p1->str1, p2->str1))
520
+ return 1;
521
+ if (p1->ulong1 != p2->ulong1)
522
+ return 1;
523
+
524
+ return 0;
525
+ }
526
+
527
+ static VALUE
528
+ version_new_from_EVR(const char* evr)
529
+ {
530
+ char *e = NULL;
531
+ char *vr = NULL;
532
+ char *end = NULL;
533
+ char *tmp_evr = NULL;
534
+ VALUE version = Qnil;
535
+
536
+ tmp_evr = strdup(evr);
537
+ if (tmp_evr==NULL) { return Qnil; }
538
+
539
+ e = tmp_evr;
540
+ if ( end=strchr(e, ':') ) {
541
+ /* epoch is found */
542
+ *end = '\0';
543
+ vr = end+1;
544
+ } else {
545
+ /* no epoch */
546
+ vr = e;
547
+ e = NULL;
548
+ }
549
+
550
+ if ( e ) {
551
+ version = rpm_version_new2(vr, atoi(e));
552
+ } else {
553
+ version = rpm_version_new(vr);
554
+ }
555
+
556
+ free(tmp_evr);
557
+ return version;
558
+ }
559
+
560
+ static VALUE
561
+ package_new_from_NEVR(const char* nevr)
562
+ {
563
+ char *name = NULL;
564
+ char *evr = NULL;
565
+ char *end = NULL;
566
+ char *tmp_nevr = NULL;
567
+ VALUE package = Qnil;
568
+ int i=0;
569
+
570
+ tmp_nevr = strdup(nevr);
571
+ if (tmp_nevr==NULL) { return Qnil; }
572
+
573
+ name = tmp_nevr;
574
+ for ( end=name; *end != '\0'; end++ ) {
575
+ }
576
+ i=0;
577
+ while ( i<2 ) {
578
+ if ( end <= name ) { break; }
579
+ end--;
580
+ if ( *end == '-' ) { i++; }
581
+ }
582
+ if ( i==2 ) {
583
+ *end = '\0'; evr = end + 1;
584
+ } else {
585
+ evr = "";
586
+ }
587
+
588
+ package = rpm_package_new_from_N_EVR(rb_str_new2(name),
589
+ version_new_from_EVR(evr));
590
+ free(tmp_nevr);
591
+ return package;
592
+ }
593
+ #endif
594
+
595
+
596
+ VALUE
597
+ rpm_transaction_check(VALUE trans)
598
+ {
599
+ #if RPM_VERSION_CODE < RPM_VERSION(4,1,0)
600
+ rpmDependencyConflict conflicts;
601
+ int num;
602
+
603
+ rpmdepCheck(RPM_TRANSACTION(trans), &conflicts, &num);
604
+ if (num) {
605
+ VALUE list = rb_ary_new();
606
+ register int i;
607
+
608
+ for (i = 0; i < num; i++) {
609
+ VALUE dep;
610
+ switch (conflicts[i].sense) {
611
+ case RPMDEP_SENSE_REQUIRES:
612
+ dep = rpm_require_new(conflicts[i].needsName,
613
+ rpm_version_new(conflicts[i].needsVersion),
614
+ conflicts[i].needsFlags,
615
+ rpm_package_new_from_header(conflicts[i].byHeader));
616
+ break;
617
+
618
+ case RPMDEP_SENSE_CONFLICTS:
619
+ dep = rpm_conflict_new(conflicts[i].needsName,
620
+ rpm_version_new(conflicts[i].needsVersion),
621
+ conflicts[i].needsFlags,
622
+ rpm_package_new_from_header(conflicts[i].byHeader));
623
+ break;
624
+ }
625
+ rb_ary_push(list, dep);
626
+ }
627
+
628
+ rpmdepFreeConflicts(conflicts, num);
629
+ return list;
630
+ }
631
+
632
+ return Qnil;
633
+ #else
634
+ int rc;
635
+ rpmps ps;
636
+ int num;
637
+ VALUE list = Qnil;
638
+
639
+ rc = rpmtsCheck(RPM_TRANSACTION(trans));
640
+ ps = rpmtsProblems(RPM_TRANSACTION(trans));
641
+ num = rpmpsNumProblems(ps);
642
+
643
+ if (ps != NULL && 0 < num) {
644
+ rpmProblem p;
645
+ int i;
646
+ list = rb_ary_new();
647
+
648
+ for (i = 0; i < num; i++) {
649
+ const char *altNEVR;
650
+ int j;
651
+ VALUE dep;
652
+
653
+ p = ps->probs + i;
654
+ altNEVR = (p->altNEVR ? p->altNEVR : "? ?altNEVR?");
655
+
656
+ if (p->ignoreProblem)
657
+ continue;
658
+
659
+ /* Filter already appended problems. */
660
+ for (j = 0; j < i; j++) {
661
+ if (!sameProblem(p, ps->probs + j))
662
+ break;
663
+ }
664
+ if (j < i)
665
+ continue;
666
+
667
+ if ( p->type == RPMPROB_REQUIRES ) {
668
+ char *buf = strdup ( altNEVR );
669
+ /* TODO: zaki: NULL check*/
670
+ char *end;
671
+
672
+ char *name = buf+2;
673
+ char *relation = NULL;
674
+ char *evr = "";
675
+ rpmsenseFlags sense_flags = 0;
676
+
677
+ end = strchr ( name, ' ');
678
+ if ( end ) {
679
+ *end = '\0';
680
+ relation = end + 1;
681
+ end = strchr ( relation, ' ');
682
+ if ( end ) {
683
+ *end = '\0';
684
+ evr = end + 1;
685
+ }
686
+ for ( ; (*relation) != '\0'; relation++ ) {
687
+ if ( (*relation) == '=' ) {
688
+ sense_flags |= RPMSENSE_EQUAL;
689
+ } else if ( (*relation) == '>' ) {
690
+ sense_flags |= RPMSENSE_GREATER;
691
+ } else if ( (*relation), '<' ) {
692
+ sense_flags |= RPMSENSE_LESS;
693
+ }
694
+ }
695
+ }
696
+
697
+ dep = rpm_require_new(name,
698
+ rpm_version_new(evr),
699
+ sense_flags,
700
+ package_new_from_NEVR(p->pkgNEVR)
701
+ );
702
+ free ( buf );
703
+ rb_ary_push(list, dep);
704
+ } else {
705
+ #if 0
706
+ RPMPROB_CONFLICT:
707
+ RPMPROB_BADARCH:
708
+ RPMPROB_BADOS:
709
+ RPMPROB_PKG_INSTALLED:
710
+ RPMPROB_BADRELOCATE:
711
+ RPMPROB_NEW_FILE_CONFLICT:
712
+ RPMPROB_FILE_CONFLICT:
713
+ RPMPROB_OLDPACKAGE:
714
+ RPMPROB_DISKSPACE:
715
+ RPMPROB_DISKNODES:
716
+ RPMPROB_BADPRETRANS:
717
+ #endif
718
+ break;
719
+ }
720
+
721
+ #if 0
722
+ printf ("%d, type=%d, ignoreProblem=%d, str1=%s pkgNEVR=%s, %s\n",
723
+ i, p->type, p->ignoreProblem, p->str1, p->pkgNEVR, altNEVR);
724
+ #endif
725
+ }
726
+ }
727
+ ps = rpmpsFree(ps);
728
+
729
+ return list;
730
+ #endif
731
+ }
732
+
733
+ VALUE
734
+ rpm_transaction_order(VALUE trans)
735
+ {
736
+ #if RPM_VERSION_CODE < RPM_VERSION(4,1,0)
737
+ rpmdepOrder(RPM_TRANSACTION(trans));
738
+ #else
739
+ rpmtsOrder(RPM_TRANSACTION(trans));
740
+ #endif
741
+ return Qnil;
742
+ }
743
+
744
+ VALUE
745
+ rpm_transaction_keys(VALUE trans)
746
+ {
747
+ return rb_ivar_get(trans, id_keys);
748
+ }
749
+
750
+ #if RPM_VERSION_CODE < RPM_VERSION(4,4,5)
751
+ static void*
752
+ transaction_callback(const void* hd, const rpmCallbackType type,
753
+ const unsigned long amount, const unsigned long total,
754
+ fnpyKey key, rpmCallbackData data)
755
+ #else
756
+ static void*
757
+ transaction_callback(const void* hd, const rpmCallbackType type,
758
+ const unsigned long long amount, const unsigned long long total,
759
+ fnpyKey key, rpmCallbackData data)
760
+ #endif
761
+ {
762
+ VALUE trans = (VALUE)data;
763
+ FD_t fdt;
764
+ const Header hdr = (Header)hd;
765
+ VALUE sig;
766
+ VALUE rv;
767
+
768
+ sig = rb_struct_new(rpm_sCallbackData, INT2NUM(type), key ? (VALUE)key:Qnil,
769
+ rpm_package_new_from_header(hdr),
770
+ UINT2NUM(amount), UINT2NUM(total));
771
+
772
+ rv = rb_yield(sig);
773
+
774
+ switch (type) {
775
+ case RPMCALLBACK_INST_OPEN_FILE:
776
+ if (TYPE(rv) != T_FILE) {
777
+ rb_raise(rb_eTypeError, "illegal return value type");
778
+ }
779
+ rb_ivar_set(trans, id_file, rv);
780
+ fdt = fdDup(NUM2INT(rb_Integer(rv)));
781
+ rb_ivar_set(trans, id_fdt, INT2NUM((long)fdt));
782
+ return fdt;
783
+
784
+ case RPMCALLBACK_INST_CLOSE_FILE:
785
+ Fclose((FD_t)NUM2LONG(rb_ivar_get(trans, id_fdt)));
786
+ rb_ivar_set(trans, id_file, Qnil);
787
+ rb_ivar_set(trans, id_fdt, Qnil);
788
+ default:
789
+ break;
790
+ }
791
+
792
+ return NULL;
793
+ }
794
+
795
+ VALUE
796
+ rpm_transaction_commit(int argc, VALUE* argv, VALUE trans)
797
+ {
798
+ #if RPM_VERSION_CODE < RPM_VERSION(4,1,0)
799
+ rpmProblemSet probset;
800
+ int flags = RPMTRANS_FLAG_NONE;
801
+ int ignores = RPMPROB_FILTER_NONE;
802
+ int rc;
803
+ VALUE db;
804
+
805
+ db = rb_ivar_get(trans, id_db);
806
+
807
+ if (OBJ_FROZEN(db)) {
808
+ rb_error_frozen("RPM::DB");
809
+ }
810
+
811
+ switch (argc) {
812
+ case 0:
813
+ break;
814
+
815
+ case 1: case 2:
816
+ flags = NUM2INT(rb_Integer(argv[0]));
817
+ if (argc == 2) {
818
+ ignores = NUM2INT(rb_Integer(argv[1]));
819
+ }
820
+ break;
821
+
822
+ default:
823
+ rb_raise(rb_eArgError, "too many arguments(0..2)");
824
+ }
825
+ if (rb_block_given_p() == Qtrue)
826
+ rc = rpmRunTransactions(RPM_TRANSACTION(trans), transaction_callback,
827
+ (void*)trans, NULL, &probset, flags, ignores);
828
+ else{
829
+ VALUE keys;
830
+
831
+ /* rpmcli.h:extern int packagesTotal; */
832
+ packagesTotal = 0;
833
+
834
+ keys = rpm_transaction_keys(trans);
835
+
836
+ if (!NIL_P(keys))
837
+ packagesTotal = NUM2INT(rb_funcall(keys,rb_intern("length"),0));
838
+ rc = rpmRunTransactions(RPM_TRANSACTION(trans), rpmShowProgress,
839
+ (void*)((long)(INSTALL_HASH|INSTALL_LABEL)),
840
+ NULL, &probset, flags, ignores);
841
+ }
842
+
843
+ if (probset != NULL) {
844
+ VALUE list = rb_ary_new();
845
+ register int i;
846
+
847
+ for (i = 0; i < probset->numProblems; i++) {
848
+ rpmProblem prob = probset->probs + i;
849
+ VALUE prb = rb_struct_new(rpm_sProblem,
850
+ INT2NUM(prob->type),
851
+ (VALUE)prob->key,
852
+ rpm_package_new_from_header(prob->h),
853
+ rb_str_new2(rpmProblemString(prob)));
854
+ rb_ary_push(list, prb);
855
+ }
856
+
857
+ rb_ivar_set(trans, id_pl, list);
858
+ }
859
+
860
+ #else
861
+ rpmps ps;
862
+ int flags = RPMTRANS_FLAG_NONE;
863
+ int ignores = RPMPROB_FILTER_NONE;
864
+ int rc;
865
+ VALUE db;
866
+
867
+ db = rb_ivar_get(trans, id_db);
868
+
869
+ if (OBJ_FROZEN(db)) {
870
+ rb_error_frozen("RPM::DB");
871
+ }
872
+
873
+ switch (argc) {
874
+ case 0:
875
+ break;
876
+
877
+ case 1: case 2:
878
+ flags = NUM2INT(rb_Integer(argv[0]));
879
+ if (argc == 2) {
880
+ ignores = NUM2INT(rb_Integer(argv[1]));
881
+ }
882
+ break;
883
+
884
+ default:
885
+ rb_raise(rb_eArgError, "too many arguments(0..2)");
886
+ }
887
+
888
+
889
+ /* Drop added/available package indices and dependency sets. */
890
+ //rpmtsClean(RPM_TRANSACTION(trans)); // zaki: required?
891
+
892
+ if (rb_block_given_p() == Qtrue) {
893
+ rpmtsSetNotifyCallback(RPM_TRANSACTION(trans),
894
+ transaction_callback,(void *)trans);
895
+ }else{
896
+ VALUE keys;
897
+
898
+ /* rpmcli.h:extern int rpmcliPackagesTotal; */
899
+ rpmcliPackagesTotal = 0;
900
+
901
+ keys = rpm_transaction_keys(trans);
902
+
903
+ if (!NIL_P(keys))
904
+ rpmcliPackagesTotal = NUM2INT(rb_funcall(keys,rb_intern("length"),0));
905
+
906
+ rpmtsSetNotifyCallback(RPM_TRANSACTION(trans), rpmShowProgress,
907
+ (void*)((long)(INSTALL_HASH|INSTALL_LABEL)));
908
+ }
909
+ rc = rpmtsRun(RPM_TRANSACTION(trans), NULL, ignores);
910
+ ps = rpmtsProblems(RPM_TRANSACTION(trans));
911
+
912
+ {
913
+ VALUE list = rb_ary_new();
914
+ if (ps != NULL && rpmpsNumProblems(ps) > 0) {
915
+ register int i;
916
+
917
+ for (i = 0; i < rpmpsNumProblems(ps); i++) {
918
+ rpmProblem p = ps->probs + i;
919
+ const char *altNEVR = (p->altNEVR ? p->altNEVR : "? ?altNEVR?");
920
+
921
+ VALUE prb = rb_struct_new(rpm_sProblem,
922
+ INT2NUM(p->type),
923
+ (VALUE)p->key,
924
+ package_new_from_NEVR(altNEVR+2),
925
+ rb_str_new2(rpmProblemString(p)));
926
+ rb_ary_push(list, prb);
927
+ }
928
+ }
929
+ rb_ivar_set(trans, id_pl, list);
930
+ }
931
+ if (ps) ps = rpmpsFree(ps);
932
+
933
+ #endif
934
+
935
+ rb_ivar_set(trans, id_commited, Qtrue);
936
+ rb_throw("abort", Qnil);
937
+
938
+ return Qnil; /* NOT REACHED */
939
+ }
940
+
941
+ VALUE
942
+ rpm_transaction_abort(VALUE trans)
943
+ {
944
+ rb_ivar_set(trans, id_aborted, Qtrue);
945
+ rb_throw("abort", Qnil);
946
+ return Qnil; /* NOT REACHED */
947
+ }
948
+
949
+ static void
950
+ mi_free(rpm_mi_t* mi)
951
+ {
952
+ rpmdbFreeIterator(mi->mi);
953
+ db_unref(mi->db);
954
+ free(mi);
955
+ }
956
+
957
+ VALUE
958
+ rpm_db_init_iterator(VALUE db, VALUE key, VALUE val)
959
+ {
960
+ rpm_mi_t* mi;
961
+
962
+ check_closed(db);
963
+
964
+ if (!NIL_P(val) && TYPE(val) != T_STRING) {
965
+ rb_raise(rb_eTypeError, "illegal argument type");
966
+ }
967
+
968
+ mi = ALLOC_N(rpm_mi_t,1);
969
+ if (mi->mi = rpmdbInitIterator(RPM_DB(db), NUM2INT(rb_Integer(key)),
970
+ NIL_P(val) ? NULL : RSTRING(val)->ptr,
971
+ NIL_P(val) ? 0 : RSTRING(val)->len)){
972
+ mi->db = (rpm_db_t*)DATA_PTR(db);
973
+ db_ref(mi->db);
974
+ return Data_Wrap_Struct(rpm_cMatchIterator, NULL, mi_free, mi);
975
+ }
976
+ free(mi);
977
+ return Qnil;
978
+ }
979
+
980
+ VALUE
981
+ rpm_mi_next_iterator(VALUE mi)
982
+ {
983
+ Header hdr;
984
+ hdr = rpmdbNextIterator(RPM_MI(mi));
985
+ if (hdr)
986
+ return rpm_package_new_from_header(hdr);
987
+ return Qnil;
988
+ }
989
+
990
+ VALUE
991
+ rpm_mi_get_iterator_count(VALUE mi)
992
+ {
993
+ return INT2NUM(rpmdbGetIteratorCount(RPM_MI(mi)));
994
+ }
995
+
996
+ VALUE
997
+ rpm_mi_get_iterator_offset(VALUE mi)
998
+ {
999
+ int off = rpmdbGetIteratorOffset(RPM_MI(mi));
1000
+ if (off)
1001
+ return INT2NUM(off);
1002
+ return Qnil;
1003
+ }
1004
+
1005
+ VALUE
1006
+ rpm_mi_set_iterator_re(VALUE mi,VALUE tag, VALUE mode, VALUE re)
1007
+ {
1008
+ if (TYPE(re) != T_STRING)
1009
+ rb_raise(rb_eTypeError, "illegal argument type");
1010
+
1011
+ rpmdbSetIteratorRE(RPM_MI(mi),NUM2INT(tag),NUM2INT(mode),RSTRING(re)->ptr);
1012
+ return mi;
1013
+ }
1014
+
1015
+ VALUE
1016
+ rpm_mi_set_iterator_version(VALUE mi, VALUE version)
1017
+ {
1018
+ /* Epoch!! */
1019
+ VALUE r;
1020
+ if (rb_obj_is_kind_of(version, rpm_cVersion) == Qfalse)
1021
+ rb_raise(rb_eTypeError, "illegal argument type");
1022
+ #if RPM_VERSION_CODE < RPM_VERSION(4,1,0)
1023
+ rpmdbSetIteratorVersion(RPM_MI(mi),RSTRING(rpm_version_get_v(version))->ptr);
1024
+ #else
1025
+ rpmdbSetIteratorRE(RPM_MI(mi),RPMTAG_VERSION,RPMMIRE_DEFAULT,RSTRING(rpm_version_get_v(version))->ptr);
1026
+ #endif
1027
+ r = rpm_version_get_r(version);
1028
+ if(!NIL_P(r)){
1029
+ #if RPM_VERSION_CODE < RPM_VERSION(4,1,0)
1030
+ rpmdbSetIteratorRelease(RPM_MI(mi),RSTRING(r)->ptr);
1031
+ #else
1032
+ rpmdbSetIteratorRE(RPM_MI(mi),RPMTAG_RELEASE,RPMMIRE_DEFAULT,RSTRING(r)->ptr);
1033
+ #endif
1034
+ }
1035
+ return mi;
1036
+ }
1037
+
1038
+ VALUE
1039
+ rpm_mi_each(VALUE mi)
1040
+ {
1041
+ VALUE p;
1042
+ while(!NIL_P( p = rpm_mi_next_iterator(mi)))
1043
+ rb_yield (p);
1044
+ return Qnil;
1045
+ }
1046
+
1047
+ void
1048
+ Init_rpm_DB(void)
1049
+ {
1050
+ rpm_cDB = rb_define_class_under(rpm_mRPM, "DB", rb_cData);
1051
+ rb_include_module(rpm_cDB, rb_mEnumerable);
1052
+ rb_define_singleton_method(rpm_cDB, "new", db_s_open, -1);
1053
+ rb_define_singleton_method(rpm_cDB, "open", db_s_open, -1);
1054
+ rb_define_singleton_method(rpm_cDB, "init", db_s_init, -1);
1055
+ rb_define_singleton_method(rpm_cDB, "rebuild", db_s_rebuild, -1);
1056
+ rb_define_method(rpm_cDB, "close", rpm_db_close, 0);
1057
+ rb_define_method(rpm_cDB, "closed?", rpm_db_is_closed, 0);
1058
+ rb_define_method(rpm_cDB, "root", rpm_db_get_root, 0);
1059
+ rb_define_method(rpm_cDB, "home", rpm_db_get_home, 0);
1060
+ rb_define_method(rpm_cDB, "writable?", rpm_db_is_writable, 0);
1061
+ rb_define_method(rpm_cDB, "each_match", rpm_db_each_match, 2);
1062
+ rb_define_method(rpm_cDB, "each", rpm_db_each, 0);
1063
+ rb_define_method(rpm_cDB, "transaction", rpm_db_transaction, -1);
1064
+ rb_define_method(rpm_cDB, "init_iterator", rpm_db_init_iterator, 2);
1065
+ rb_undef_method(rpm_cDB, "dup");
1066
+ rb_undef_method(rpm_cDB, "clone");
1067
+ }
1068
+
1069
+ void
1070
+ Init_rpm_MatchIterator(void)
1071
+ {
1072
+ rpm_cMatchIterator = rb_define_class_under(rpm_mRPM, "MatchIterator", rb_cData);
1073
+ rb_include_module(rpm_cMatchIterator, rb_mEnumerable);
1074
+ rb_define_method(rpm_cMatchIterator, "each", rpm_mi_each, 0);
1075
+ rb_define_method(rpm_cMatchIterator, "next_iterator", rpm_mi_next_iterator, 0);
1076
+ rb_define_method(rpm_cMatchIterator, "offset", rpm_mi_get_iterator_offset, 0);
1077
+ rb_define_method(rpm_cMatchIterator, "set_iterator_re", rpm_mi_set_iterator_re, 3);
1078
+ rb_define_method(rpm_cMatchIterator, "regexp", rpm_mi_set_iterator_re, 3);
1079
+ rb_define_method(rpm_cMatchIterator, "set_iterator_version", rpm_mi_set_iterator_version, 1);
1080
+ rb_define_method(rpm_cMatchIterator, "version", rpm_mi_set_iterator_version, 1);
1081
+ rb_define_method(rpm_cMatchIterator, "get_iterator_count",rpm_mi_get_iterator_count, 0);
1082
+ rb_define_method(rpm_cMatchIterator, "count",rpm_mi_get_iterator_count, 0);
1083
+ rb_define_method(rpm_cMatchIterator, "length",rpm_mi_get_iterator_count, 0);
1084
+ }
1085
+
1086
+ void
1087
+ Init_rpm_transaction(void)
1088
+ {
1089
+ rpm_cTransaction = rb_define_class_under(rpm_mRPM, "Transaction", rb_cData);
1090
+ rb_define_method(rpm_cTransaction, "db", rpm_transaction_get_db, 0);
1091
+ rb_define_method(rpm_cTransaction, "script_file", rpm_transaction_get_script_file, 0);
1092
+ rb_define_method(rpm_cTransaction, "script_file=", rpm_transaction_set_script_file, 1);
1093
+ rb_define_method(rpm_cTransaction, "install", rpm_transaction_install, 2);
1094
+ rb_define_method(rpm_cTransaction, "upgrade", rpm_transaction_upgrade, 2);
1095
+ rb_define_method(rpm_cTransaction, "available", rpm_transaction_available, 2);
1096
+ rb_define_method(rpm_cTransaction, "delete", rpm_transaction_delete, 1);
1097
+ rb_define_method(rpm_cTransaction, "check", rpm_transaction_check, 0);
1098
+ rb_define_method(rpm_cTransaction, "order", rpm_transaction_order, 0);
1099
+ rb_define_method(rpm_cTransaction, "keys", rpm_transaction_keys, 0);
1100
+ rb_define_method(rpm_cTransaction, "commit", rpm_transaction_commit, -1);
1101
+ rb_define_method(rpm_cTransaction, "abort", rpm_transaction_abort, 0);
1102
+ rb_undef_method(rpm_cTransaction, "dup");
1103
+ rb_undef_method(rpm_cTransaction, "clone");
1104
+
1105
+ rpm_sCallbackData = rb_struct_define(NULL, "type", "key", "package",
1106
+ "amount", "total", NULL);
1107
+ rb_define_const(rpm_mRPM, "CallbackData", rpm_sCallbackData);
1108
+
1109
+ rpm_sProblem = rb_struct_define(NULL, "type", "key", "package",
1110
+ "description", NULL);
1111
+ rb_define_const(rpm_mRPM, "Problem", rpm_sProblem);
1112
+
1113
+ id_db = rb_intern("db");
1114
+ id_sf = rb_intern("script_file");
1115
+ id_keys = rb_intern("keys");
1116
+ id_commited = rb_intern("commited");
1117
+ id_aborted = rb_intern("aborted");
1118
+ id_pl = rb_intern("problist");
1119
+ id_type = rb_intern("type");
1120
+ id_key = rb_intern("key");
1121
+ id_pkg = rb_intern("package");
1122
+ id_mes = rb_intern("message");
1123
+ id_amount = rb_intern("amount");
1124
+ id_total = rb_intern("total");
1125
+ //id_pkg_cache = rb_intern("package_cache");
1126
+ id_file = rb_intern("file");
1127
+ id_fdt = rb_intern("fdt");
1128
+ }