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,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
+ }