Line data Source code
1 : //
2 : // rpm.c
3 : // deployctl
4 : //
5 : // Created by Danny Goossen on 29/5/17.
6 : // Copyright (c) 2017 Danny Goossen. All rights reserved.
7 : //
8 :
9 : #include "deployd.h"
10 :
11 : #ifdef __APPLE__
12 : #include <rpm/rpm4compat.h>
13 : #else
14 : #include <rpm/rpmlegacy.h>
15 : #include <rpm/rpmlib.h>
16 : #include <rpm/header.h>
17 : #include <rpm/rpmts.h>
18 : #include <rpm/rpmdb.h>
19 : #include <rpm/rpmio.h>
20 : #endif
21 : #include "rpm.h"
22 :
23 : // TODO, feed back info on feedback in opague
24 : // TODO Remove RPMLOG
25 : /*
26 : Returns if susccessfull:
27 : {
28 : "name": "test",
29 : "version": "0.1",
30 : "arch": "x86_64",
31 : "release": "1",
32 : "distribution": "el7",
33 : "SRPM": false,
34 : "filename": "test-0.1-1.el7.centos.x86_64.rpm",
35 : "filepath": "./test_check_rpm/projectdir/rpm/"
36 : }
37 :
38 : */
39 :
40 : #ifndef __APPLE__
41 21 : static inline int headerGetEntry(Header h, rpm_tag_t tag, rpm_tagtype_t * type, void ** p, rpm_count_t * c) {
42 : //HE_t he = (HE_t)memset(alloca(sizeof(*he)), 0, sizeof(*he));
43 : struct rpmtd_s td;
44 21 : td.tag=tag;
45 : int rc;
46 : /* Always ensure to initialize */
47 21 : *(void **)p = NULL;
48 21 : rc = headerGet(h, tag,(rpmtd)&td, 0);
49 21 : if (rc) {
50 17 : if (type) *type = td.type;
51 17 : if (p) *(void **) p = td.data;
52 17 : if (c) *c = td.count;
53 : }
54 21 : return rc;
55 : }
56 : #else
57 : #define _RPMVSF_NODIGESTS \
58 : ( RPMVSF_NOSHA1HEADER | \
59 : RPMVSF_NOMD5HEADER | \
60 : RPMVSF_NOSHA1 | \
61 : RPMVSF_NOMD5 )
62 :
63 : #define _RPMVSF_NOSIGNATURES \
64 : ( RPMVSF_NODSAHEADER | \
65 : RPMVSF_NORSAHEADER | \
66 : RPMVSF_NODSA | \
67 : RPMVSF_NORSA )
68 : #endif
69 :
70 :
71 6 : int get_rpm_fileinfo(void * opaque, const char * filepath, const char * filename,cJSON ** rpm_info)
72 : {
73 6 : if (!filepath || !filename ) return RPM_ERR_BADARG;
74 :
75 : rpmts ts;
76 : FD_t fd;
77 : rpmRC rc;
78 : Header hdr;
79 4 : rpmVSFlags vsflags = 0;
80 :
81 4 : rc = rpmReadConfigFiles(NULL, NULL);
82 4 : if (rc != RPMRC_OK) {
83 : //rpmlog(RPMLOG_NOTICE, "Unable to read RPM configuration.\n");
84 0 : * rpm_info =cJSON_CreateObject();
85 0 : cJSON_AddStringToObject(*rpm_info, "error", "system rpm config");
86 0 : cJSON_AddStringToObject(*rpm_info, "type", "rpm");
87 0 : cJSON_AddStringToObject(*rpm_info, "filename", filename);
88 0 : return(RPM_ERR_SYSTEM);
89 : }
90 4 : char * file_path=alloca(strlen(filepath) +1+strlen(filename));
91 4 : sprintf(file_path, "%s%s",filepath,filename);
92 4 : fd = Fopen(file_path, "r.ufdio");
93 4 : if ((!fd) || Ferror(fd)) {
94 : //rpmlog(RPMLOG_NOTICE, "Failed to open package file (%s)\n", Fstrerror(fd));
95 0 : if (fd) {
96 0 : Fclose(fd);
97 : }
98 0 : * rpm_info =cJSON_CreateObject();
99 0 : cJSON_AddStringToObject(*rpm_info, "error", "failed open rpm");
100 0 : cJSON_AddStringToObject(*rpm_info, "type", "rpm");
101 0 : cJSON_AddStringToObject(*rpm_info, "filename", filename);
102 0 : return(RPM_ERR_OPEN);
103 : }
104 :
105 4 : ts = rpmtsCreate();
106 :
107 4 : vsflags |= _RPMVSF_NODIGESTS;
108 4 : vsflags |= _RPMVSF_NOSIGNATURES;
109 4 : vsflags |= RPMVSF_NOHDRCHK;
110 4 : (void) rpmtsSetVSFlags(ts, vsflags);
111 :
112 4 : rc = rpmReadPackageFile(ts, fd, NULL, &hdr);
113 4 : if (rc != RPMRC_OK) {
114 : //rpmlog(RPMLOG_NOTICE, "Could not read package file %s\n",file_path);
115 1 : Fclose(fd);
116 1 : rpmtsFree(ts);
117 1 : * rpm_info =cJSON_CreateObject();
118 1 : cJSON_AddStringToObject(*rpm_info, "error", "could not read rpm");
119 1 : cJSON_AddStringToObject(*rpm_info, "type", "rpm");
120 1 : cJSON_AddStringToObject(*rpm_info, "filename", filename);
121 1 : return(RPM_ERR_READ);
122 : }
123 3 : Fclose(fd);
124 :
125 3 : Header h = headerLink( hdr );
126 3 : const char *n =NULL;
127 3 : const char *v=NULL;
128 3 : const char *r=NULL;
129 3 : const char *d=NULL;
130 3 : const char *a=NULL;
131 3 : const char *o=NULL;
132 3 : const char *s=NULL;
133 3 : headerGetEntry( h, RPMTAG_NAME, NULL, (void**)&n, NULL);
134 3 : headerGetEntry( h, RPMTAG_VERSION, NULL, (void**)&v, NULL);
135 3 : headerGetEntry( h, RPMTAG_RELEASE, NULL, (void**)&r, NULL);
136 3 : headerGetEntry( h, RPMTAG_ARCH, NULL, (void**)&a, NULL);
137 3 : headerGetEntry( h, RPMTAG_OS, NULL, (void**)&o, NULL);
138 3 : headerGetEntry( h, RPMTAG_DISTRIBUTION, NULL, (void**)&d, NULL);
139 :
140 3 : headerGetEntry( h, RPMTAG_SOURCERPM, NULL, (void**)&s, NULL);
141 :
142 3 : if (n){
143 3 : * rpm_info =cJSON_CreateObject();
144 3 : if (n) cJSON_AddStringToObject(*rpm_info, "name", n);
145 3 : if (v) cJSON_AddStringToObject(*rpm_info, "version", v);
146 3 : if (a) cJSON_AddStringToObject(*rpm_info, "arch", a);
147 3 : if (d && strstr(d,"openSUSE")) cJSON_AddStringToObject(*rpm_info, "distribution", d);
148 3 : else if (r) {
149 3 : const char *ptr = strchr(r,'.');
150 3 : if (ptr){
151 2 : const char *centos =strstr(r,".centos");
152 2 : if (centos)
153 1 : cJSON_AddStringToObject_n(*rpm_info, "distribution", ptr+1,(size_t)(centos-ptr-1));
154 : else
155 1 : cJSON_AddStringToObject(*rpm_info, "distribution", ptr+1);
156 : }
157 : }
158 3 : cJSON_AddBoolToObject(*rpm_info, "SRPM", s==NULL);
159 3 : cJSON_AddStringToObject(*rpm_info, "filename", filename);
160 3 : if (filepath)cJSON_AddStringToObject(*rpm_info, "filepath", filepath);
161 3 : cJSON_AddStringToObject(*rpm_info, "fullpath", file_path);
162 3 : cJSON_AddStringToObject(*rpm_info, "type", "rpm");
163 3 : headerFree(hdr);
164 3 : rpmtsFree(ts);
165 : //fprintf(stderr,"RPM info OK\n");
166 3 : return RPM_OK;
167 : }
168 : else
169 : {
170 0 : * rpm_info =cJSON_CreateObject();
171 0 : cJSON_AddStringToObject(*rpm_info, "error", "invalid rpm-file");
172 0 : cJSON_AddStringToObject(*rpm_info, "type", "rpm");
173 0 : cJSON_AddStringToObject(*rpm_info, "filename", filename);
174 : //fprintf(stderr,"no valid RPM\n");
175 0 : headerFree(hdr);
176 0 : rpmtsFree(ts);
177 0 : return RPM_ERR_INVALID;
178 : }
179 : return(0);
180 : }
|