]>
Commit | Line | Data |
---|---|---|
e2faeb46 AF |
1 | /* |
2 | * be_files.c | |
3 | * | |
d37ad048 AG |
4 | * Copyright (c) 2006 by Christian Hamar <krics@linuxforum.hu> |
5 | * Copyright (c) 2006 by Miklos Vajna <vmiklos@frugalware.org> | |
e2faeb46 AF |
6 | * |
7 | * This program is free software; you can redistribute it and/or modify | |
8 | * it under the terms of the GNU General Public License as published by | |
9 | * the Free Software Foundation; either version 2 of the License, or | |
10 | * (at your option) any later version. | |
11 | * | |
12 | * This program is distributed in the hope that it will be useful, | |
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | * GNU General Public License for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU General Public License | |
18 | * along with this program; if not, write to the Free Software | |
19 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, | |
20 | * USA. | |
21 | */ | |
22 | ||
23 | #include "config.h" | |
24 | #include <unistd.h> | |
25 | #include <stdio.h> | |
26 | #include <stdlib.h> | |
27 | #include <errno.h> | |
28 | #include <string.h> | |
d37ad048 AG |
29 | #ifdef __sun__ |
30 | #include <strings.h> | |
31 | #endif | |
e2faeb46 AF |
32 | #include <sys/stat.h> |
33 | #include <dirent.h> | |
bb787e26 | 34 | #include <libintl.h> |
d37ad048 | 35 | #include <locale.h> |
e2faeb46 AF |
36 | #ifdef CYGWIN |
37 | #include <limits.h> /* PATH_MAX */ | |
38 | #endif | |
39 | /* pacman */ | |
40 | #include "log.h" | |
41 | #include "util.h" | |
42 | #include "db.h" | |
43 | #include "alpm.h" | |
d37ad048 AG |
44 | #include "error.h" |
45 | #include "handle.h" | |
46 | ||
e8275fa9 AG |
47 | |
48 | /* This function is used to convert the downloaded db file to the proper backend | |
49 | * format | |
50 | */ | |
51 | int _alpm_db_install(pmdb_t *db, const char *dbfile) | |
52 | { | |
53 | /* ORE | |
54 | we should not simply unpack the archive, but better parse it and | |
55 | db_write each entry (see sync_load_dbarchive to get archive content) */ | |
56 | _alpm_log(PM_LOG_FLOW2, _("unpacking database '%s'"), dbfile); | |
57 | ||
58 | if(_alpm_unpack(dbfile, db->path, NULL)) { | |
59 | RET_ERR(PM_ERR_SYSTEM, -1); | |
60 | } | |
61 | ||
62 | return unlink(dbfile); | |
63 | } | |
64 | ||
d37ad048 | 65 | int _alpm_db_open(pmdb_t *db) |
e2faeb46 | 66 | { |
e2faeb46 | 67 | if(db == NULL) { |
e8275fa9 | 68 | RET_ERR(PM_ERR_DB_NULL, -1); |
e2faeb46 AF |
69 | } |
70 | ||
ad2c7463 | 71 | db->handle = opendir(db->path); |
e2faeb46 | 72 | if(db->handle == NULL) { |
e8275fa9 | 73 | RET_ERR(PM_ERR_DB_OPEN, -1); |
e2faeb46 AF |
74 | } |
75 | ||
76 | return(0); | |
77 | } | |
78 | ||
79 | void _alpm_db_close(pmdb_t *db) | |
80 | { | |
81 | if(db == NULL) { | |
82 | return; | |
83 | } | |
84 | ||
85 | if(db->handle) { | |
86 | closedir(db->handle); | |
87 | db->handle = NULL; | |
88 | } | |
89 | } | |
90 | ||
91 | void _alpm_db_rewind(pmdb_t *db) | |
92 | { | |
93 | if(db == NULL || db->handle == NULL) { | |
94 | return; | |
95 | } | |
96 | ||
97 | rewinddir(db->handle); | |
98 | } | |
99 | ||
100 | pmpkg_t *_alpm_db_scan(pmdb_t *db, char *target, unsigned int inforeq) | |
101 | { | |
102 | struct dirent *ent = NULL; | |
103 | struct stat sbuf; | |
104 | char path[PATH_MAX]; | |
105 | char name[PKG_FULLNAME_LEN]; | |
106 | char *ptr = NULL; | |
107 | int found = 0; | |
108 | pmpkg_t *pkg; | |
109 | ||
110 | if(db == NULL) { | |
e8275fa9 | 111 | RET_ERR(PM_ERR_DB_NULL, NULL); |
e2faeb46 AF |
112 | } |
113 | ||
114 | if(target != NULL) { | |
115 | /* search for a specific package (by name only) */ | |
116 | rewinddir(db->handle); | |
117 | while(!found && (ent = readdir(db->handle)) != NULL) { | |
118 | if(!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, "..")) { | |
119 | continue; | |
120 | } | |
121 | /* stat the entry, make sure it's a directory */ | |
ad2c7463 | 122 | snprintf(path, PATH_MAX, "%s/%s", db->path, ent->d_name); |
e2faeb46 AF |
123 | if(stat(path, &sbuf) || !S_ISDIR(sbuf.st_mode)) { |
124 | continue; | |
125 | } | |
126 | STRNCPY(name, ent->d_name, PKG_FULLNAME_LEN); | |
127 | /* truncate the string at the second-to-last hyphen, */ | |
128 | /* which will give us the package name */ | |
129 | if((ptr = rindex(name, '-'))) { | |
130 | *ptr = '\0'; | |
131 | } | |
132 | if((ptr = rindex(name, '-'))) { | |
133 | *ptr = '\0'; | |
134 | } | |
135 | if(!strcmp(name, target)) { | |
136 | found = 1; | |
137 | } | |
138 | } | |
139 | if(!found) { | |
140 | return(NULL); | |
141 | } | |
142 | } else { | |
143 | /* normal iteration */ | |
144 | int isdir = 0; | |
145 | while(!isdir) { | |
146 | ent = readdir(db->handle); | |
147 | if(ent == NULL) { | |
148 | return(NULL); | |
149 | } | |
150 | if(!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, "..")) { | |
151 | isdir = 0; | |
152 | continue; | |
153 | } | |
154 | /* stat the entry, make sure it's a directory */ | |
ad2c7463 | 155 | snprintf(path, PATH_MAX, "%s/%s", db->path, ent->d_name); |
e2faeb46 AF |
156 | if(!stat(path, &sbuf) && S_ISDIR(sbuf.st_mode)) { |
157 | isdir = 1; | |
158 | } | |
159 | } | |
160 | } | |
161 | ||
162 | pkg = _alpm_pkg_new(NULL, NULL); | |
163 | if(pkg == NULL) { | |
164 | return(NULL); | |
165 | } | |
166 | if(_alpm_pkg_splitname(ent->d_name, pkg->name, pkg->version) == -1) { | |
bb787e26 | 167 | _alpm_log(PM_LOG_ERROR, _("invalid name for dabatase entry '%s'"), ent->d_name); |
e2faeb46 AF |
168 | return(NULL); |
169 | } | |
170 | if(_alpm_db_read(db, inforeq, pkg) == -1) { | |
171 | FREEPKG(pkg); | |
172 | } | |
173 | ||
174 | return(pkg); | |
175 | } | |
176 | ||
177 | int _alpm_db_read(pmdb_t *db, unsigned int inforeq, pmpkg_t *info) | |
178 | { | |
179 | FILE *fp = NULL; | |
180 | struct stat buf; | |
181 | char path[PATH_MAX]; | |
182 | char line[512]; | |
d37ad048 | 183 | char *lang_tmp; |
7131b7ac | 184 | pmlist_t *tmplist; |
d37ad048 | 185 | char *foo; |
e2faeb46 | 186 | |
e8275fa9 AG |
187 | if(db == NULL) { |
188 | RET_ERR(PM_ERR_DB_NULL, -1); | |
189 | } | |
190 | ||
191 | if(info == NULL || info->name[0] == 0 || info->version[0] == 0) { | |
192 | _alpm_log(PM_LOG_ERROR, _("invalid package entry provided to _alpm_db_read")); | |
e2faeb46 AF |
193 | return(-1); |
194 | } | |
195 | ||
ad2c7463 | 196 | snprintf(path, PATH_MAX, "%s/%s-%s", db->path, info->name, info->version); |
e2faeb46 AF |
197 | if(stat(path, &buf)) { |
198 | /* directory doesn't exist or can't be opened */ | |
af2fb332 | 199 | _alpm_log(PM_LOG_ERROR, _("cannot find '%s-%s' in db '%s'"), info->name, info->version, db->treename); |
e2faeb46 AF |
200 | return(-1); |
201 | } | |
202 | ||
203 | /* DESC */ | |
204 | if(inforeq & INFRQ_DESC) { | |
ad2c7463 | 205 | snprintf(path, PATH_MAX, "%s/%s-%s/desc", db->path, info->name, info->version); |
e2faeb46 AF |
206 | fp = fopen(path, "r"); |
207 | if(fp == NULL) { | |
d37ad048 | 208 | _alpm_log(PM_LOG_DEBUG, "%s (%s)", path, strerror(errno)); |
e2faeb46 AF |
209 | goto error; |
210 | } | |
211 | while(!feof(fp)) { | |
212 | if(fgets(line, 256, fp) == NULL) { | |
213 | break; | |
214 | } | |
215 | _alpm_strtrim(line); | |
216 | if(!strcmp(line, "%DESC%")) { | |
d37ad048 AG |
217 | while(fgets(line, 512, fp) && strlen(_alpm_strtrim(line))) { |
218 | info->desc_localized = _alpm_list_add(info->desc_localized, strdup(line)); | |
219 | } | |
220 | ||
221 | if (setlocale(LC_ALL, "") == NULL) { /* To fix segfault when locale invalid */ | |
222 | setenv("LC_ALL", "C", 1); | |
223 | } | |
224 | if((lang_tmp = (char *)malloc(strlen(setlocale(LC_ALL, "")))) == NULL) { | |
225 | RET_ERR(PM_ERR_MEMORY, -1); | |
226 | } | |
227 | snprintf(lang_tmp, strlen(setlocale(LC_ALL, "")), "%s", setlocale(LC_ALL, "")); | |
228 | ||
229 | if(info->desc_localized && !info->desc_localized->next) { | |
230 | snprintf(info->desc, 512, "%s", (char*)info->desc_localized->data); | |
231 | } else { | |
232 | for (tmplist = info->desc_localized; tmplist; tmplist = tmplist->next) { | |
233 | if (tmplist->data && strncmp(tmplist->data, lang_tmp, strlen(lang_tmp))) { | |
234 | snprintf(info->desc, 512, "%s", (char*)info->desc_localized->data); | |
235 | } else { | |
236 | foo = strdup(tmplist->data); | |
237 | snprintf(info->desc, 512, "%s", foo+strlen(lang_tmp)+1); | |
238 | FREE(foo); | |
239 | break; | |
240 | } | |
241 | } | |
e2faeb46 AF |
242 | } |
243 | _alpm_strtrim(info->desc); | |
d37ad048 | 244 | FREE(lang_tmp); |
e2faeb46 AF |
245 | } else if(!strcmp(line, "%GROUPS%")) { |
246 | while(fgets(line, 512, fp) && strlen(_alpm_strtrim(line))) { | |
247 | info->groups = _alpm_list_add(info->groups, strdup(line)); | |
248 | } | |
249 | } else if(!strcmp(line, "%URL%")) { | |
250 | if(fgets(info->url, sizeof(info->url), fp) == NULL) { | |
251 | goto error; | |
252 | } | |
253 | _alpm_strtrim(info->url); | |
254 | } else if(!strcmp(line, "%LICENSE%")) { | |
255 | while(fgets(line, 512, fp) && strlen(_alpm_strtrim(line))) { | |
256 | info->license = _alpm_list_add(info->license, strdup(line)); | |
257 | } | |
258 | } else if(!strcmp(line, "%ARCH%")) { | |
259 | if(fgets(info->arch, sizeof(info->arch), fp) == NULL) { | |
260 | goto error; | |
261 | } | |
262 | _alpm_strtrim(info->arch); | |
263 | } else if(!strcmp(line, "%BUILDDATE%")) { | |
264 | if(fgets(info->builddate, sizeof(info->builddate), fp) == NULL) { | |
265 | goto error; | |
266 | } | |
267 | _alpm_strtrim(info->builddate); | |
d37ad048 AG |
268 | } else if(!strcmp(line, "%BUILDTYPE%")) { |
269 | if(fgets(info->buildtype, sizeof(info->buildtype), fp) == NULL) { | |
270 | goto error; | |
271 | } | |
272 | _alpm_strtrim(info->buildtype); | |
e2faeb46 AF |
273 | } else if(!strcmp(line, "%INSTALLDATE%")) { |
274 | if(fgets(info->installdate, sizeof(info->installdate), fp) == NULL) { | |
275 | goto error; | |
276 | } | |
277 | _alpm_strtrim(info->installdate); | |
278 | } else if(!strcmp(line, "%PACKAGER%")) { | |
279 | if(fgets(info->packager, sizeof(info->packager), fp) == NULL) { | |
280 | goto error; | |
281 | } | |
282 | _alpm_strtrim(info->packager); | |
283 | } else if(!strcmp(line, "%REASON%")) { | |
284 | char tmp[32]; | |
285 | if(fgets(tmp, sizeof(tmp), fp) == NULL) { | |
286 | goto error; | |
287 | } | |
288 | _alpm_strtrim(tmp); | |
289 | info->reason = atol(tmp); | |
290 | } else if(!strcmp(line, "%SIZE%") || !strcmp(line, "%CSIZE%")) { | |
291 | /* NOTE: the CSIZE and SIZE fields both share the "size" field | |
292 | * in the pkginfo_t struct. This can be done b/c CSIZE | |
293 | * is currently only used in sync databases, and SIZE is | |
294 | * only used in local databases. | |
295 | */ | |
296 | char tmp[32]; | |
297 | if(fgets(tmp, sizeof(tmp), fp) == NULL) { | |
298 | goto error; | |
299 | } | |
300 | _alpm_strtrim(tmp); | |
301 | info->size = atol(tmp); | |
d37ad048 AG |
302 | } else if(!strcmp(line, "%USIZE%")) { |
303 | /* USIZE (uncompressed size) tag only appears in sync repositories, | |
304 | * not the local one. */ | |
305 | char tmp[32]; | |
306 | if(fgets(tmp, sizeof(tmp), fp) == NULL) { | |
307 | goto error; | |
308 | } | |
309 | _alpm_strtrim(tmp); | |
310 | info->usize = atol(tmp); | |
311 | } else if(!strcmp(line, "%SHA1SUM%")) { | |
312 | /* SHA1SUM tag only appears in sync repositories, | |
313 | * not the local one. */ | |
314 | if(fgets(info->sha1sum, sizeof(info->sha1sum), fp) == NULL) { | |
315 | goto error; | |
316 | } | |
e2faeb46 AF |
317 | } else if(!strcmp(line, "%MD5SUM%")) { |
318 | /* MD5SUM tag only appears in sync repositories, | |
319 | * not the local one. */ | |
320 | if(fgets(info->md5sum, sizeof(info->md5sum), fp) == NULL) { | |
321 | goto error; | |
322 | } | |
323 | /* XXX: these are only here as backwards-compatibility for pacman 2.x | |
324 | * sync repos.... in pacman3, they have been moved to DEPENDS. | |
325 | * Remove this when we move to pacman3 repos. | |
326 | */ | |
327 | } else if(!strcmp(line, "%REPLACES%")) { | |
328 | /* the REPLACES tag is special -- it only appears in sync repositories, | |
329 | * not the local one. */ | |
330 | while(fgets(line, 512, fp) && strlen(_alpm_strtrim(line))) { | |
331 | info->replaces = _alpm_list_add(info->replaces, strdup(line)); | |
332 | } | |
333 | } else if(!strcmp(line, "%FORCE%")) { | |
334 | /* FORCE tag only appears in sync repositories, | |
335 | * not the local one. */ | |
336 | info->force = 1; | |
337 | } | |
338 | } | |
339 | fclose(fp); | |
340 | fp = NULL; | |
341 | } | |
342 | ||
343 | /* FILES */ | |
344 | if(inforeq & INFRQ_FILES) { | |
ad2c7463 | 345 | snprintf(path, PATH_MAX, "%s/%s-%s/files", db->path, info->name, info->version); |
e2faeb46 AF |
346 | fp = fopen(path, "r"); |
347 | if(fp == NULL) { | |
d37ad048 | 348 | _alpm_log(PM_LOG_WARNING, "%s (%s)", path, strerror(errno)); |
e2faeb46 AF |
349 | goto error; |
350 | } | |
351 | while(fgets(line, 256, fp)) { | |
352 | _alpm_strtrim(line); | |
353 | if(!strcmp(line, "%FILES%")) { | |
354 | while(fgets(line, 512, fp) && strlen(_alpm_strtrim(line))) { | |
355 | info->files = _alpm_list_add(info->files, strdup(line)); | |
356 | } | |
357 | } else if(!strcmp(line, "%BACKUP%")) { | |
358 | while(fgets(line, 512, fp) && strlen(_alpm_strtrim(line))) { | |
359 | info->backup = _alpm_list_add(info->backup, strdup(line)); | |
360 | } | |
361 | } | |
362 | } | |
363 | fclose(fp); | |
364 | fp = NULL; | |
365 | } | |
366 | ||
367 | /* DEPENDS */ | |
368 | if(inforeq & INFRQ_DEPENDS) { | |
ad2c7463 | 369 | snprintf(path, PATH_MAX, "%s/%s-%s/depends", db->path, info->name, info->version); |
e2faeb46 AF |
370 | fp = fopen(path, "r"); |
371 | if(fp == NULL) { | |
d37ad048 | 372 | _alpm_log(PM_LOG_WARNING, "%s (%s)", path, strerror(errno)); |
e2faeb46 AF |
373 | goto error; |
374 | } | |
375 | while(!feof(fp)) { | |
376 | fgets(line, 255, fp); | |
377 | _alpm_strtrim(line); | |
378 | if(!strcmp(line, "%DEPENDS%")) { | |
379 | while(fgets(line, 512, fp) && strlen(_alpm_strtrim(line))) { | |
380 | info->depends = _alpm_list_add(info->depends, strdup(line)); | |
381 | } | |
382 | } else if(!strcmp(line, "%REQUIREDBY%")) { | |
383 | while(fgets(line, 512, fp) && strlen(_alpm_strtrim(line))) { | |
384 | info->requiredby = _alpm_list_add(info->requiredby, strdup(line)); | |
385 | } | |
386 | } else if(!strcmp(line, "%CONFLICTS%")) { | |
387 | while(fgets(line, 512, fp) && strlen(_alpm_strtrim(line))) { | |
388 | info->conflicts = _alpm_list_add(info->conflicts, strdup(line)); | |
389 | } | |
390 | } else if(!strcmp(line, "%PROVIDES%")) { | |
391 | while(fgets(line, 512, fp) && strlen(_alpm_strtrim(line))) { | |
392 | info->provides = _alpm_list_add(info->provides, strdup(line)); | |
393 | } | |
394 | } else if(!strcmp(line, "%REPLACES%")) { | |
395 | /* the REPLACES tag is special -- it only appears in sync repositories, | |
396 | * not the local one. */ | |
397 | while(fgets(line, 512, fp) && strlen(_alpm_strtrim(line))) { | |
398 | info->replaces = _alpm_list_add(info->replaces, strdup(line)); | |
399 | } | |
400 | } else if(!strcmp(line, "%FORCE%")) { | |
401 | /* FORCE tag only appears in sync repositories, | |
402 | * not the local one. */ | |
403 | info->force = 1; | |
404 | } | |
405 | } | |
406 | fclose(fp); | |
407 | fp = NULL; | |
408 | } | |
409 | ||
410 | /* INSTALL */ | |
411 | if(inforeq & INFRQ_SCRIPLET) { | |
839a64df | 412 | snprintf(path, PATH_MAX, "%s/%s-%s/install", db->path, info->name, info->version); |
e2faeb46 AF |
413 | if(!stat(path, &buf)) { |
414 | info->scriptlet = 1; | |
415 | } | |
416 | } | |
417 | ||
418 | /* internal */ | |
419 | info->infolevel |= inforeq; | |
420 | ||
421 | return(0); | |
422 | ||
423 | error: | |
424 | if(fp) { | |
425 | fclose(fp); | |
426 | } | |
427 | return(-1); | |
428 | } | |
429 | ||
430 | int _alpm_db_write(pmdb_t *db, pmpkg_t *info, unsigned int inforeq) | |
431 | { | |
432 | FILE *fp = NULL; | |
433 | char path[PATH_MAX]; | |
434 | mode_t oldmask; | |
7131b7ac | 435 | pmlist_t *lp = NULL; |
e2faeb46 AF |
436 | int retval = 0; |
437 | int local = 0; | |
438 | ||
439 | if(db == NULL || info == NULL) { | |
440 | return(-1); | |
441 | } | |
442 | ||
ad2c7463 | 443 | snprintf(path, PATH_MAX, "%s/%s-%s", db->path, info->name, info->version); |
e2faeb46 AF |
444 | oldmask = umask(0000); |
445 | mkdir(path, 0755); | |
446 | /* make sure we have a sane umask */ | |
447 | umask(0022); | |
448 | ||
449 | if(strcmp(db->treename, "local") == 0) { | |
450 | local = 1; | |
451 | } | |
452 | ||
453 | /* DESC */ | |
454 | if(inforeq & INFRQ_DESC) { | |
ad2c7463 | 455 | snprintf(path, PATH_MAX, "%s/%s-%s/desc", db->path, info->name, info->version); |
e2faeb46 | 456 | if((fp = fopen(path, "w")) == NULL) { |
bb787e26 | 457 | _alpm_log(PM_LOG_ERROR, _("db_write: could not open file %s/desc"), db->treename); |
e2faeb46 AF |
458 | retval = 1; |
459 | goto cleanup; | |
460 | } | |
461 | fprintf(fp, "%%NAME%%\n%s\n\n" | |
462 | "%%VERSION%%\n%s\n\n", info->name, info->version); | |
463 | if(info->desc[0]) { | |
d37ad048 AG |
464 | fputs("%DESC%\n", fp); |
465 | for(lp = info->desc_localized; lp; lp = lp->next) { | |
466 | fprintf(fp, "%s\n", (char *)lp->data); | |
467 | } | |
468 | fprintf(fp, "\n"); | |
e2faeb46 AF |
469 | } |
470 | if(info->groups) { | |
471 | fputs("%GROUPS%\n", fp); | |
472 | for(lp = info->groups; lp; lp = lp->next) { | |
473 | fprintf(fp, "%s\n", (char *)lp->data); | |
474 | } | |
475 | fprintf(fp, "\n"); | |
476 | } | |
477 | if(local) { | |
478 | if(info->url[0]) { | |
479 | fprintf(fp, "%%URL%%\n" | |
480 | "%s\n\n", info->url); | |
481 | } | |
482 | if(info->license) { | |
483 | fputs("%LICENSE%\n", fp); | |
484 | for(lp = info->license; lp; lp = lp->next) { | |
485 | fprintf(fp, "%s\n", (char *)lp->data); | |
486 | } | |
487 | fprintf(fp, "\n"); | |
488 | } | |
489 | if(info->arch[0]) { | |
490 | fprintf(fp, "%%ARCH%%\n" | |
491 | "%s\n\n", info->arch); | |
492 | } | |
493 | if(info->builddate[0]) { | |
494 | fprintf(fp, "%%BUILDDATE%%\n" | |
495 | "%s\n\n", info->builddate); | |
496 | } | |
d37ad048 AG |
497 | if(info->buildtype[0]) { |
498 | fprintf(fp, "%%BUILDTYPE%%\n" | |
499 | "%s\n\n", info->buildtype); | |
500 | } | |
e2faeb46 AF |
501 | if(info->installdate[0]) { |
502 | fprintf(fp, "%%INSTALLDATE%%\n" | |
503 | "%s\n\n", info->installdate); | |
504 | } | |
505 | if(info->packager[0]) { | |
506 | fprintf(fp, "%%PACKAGER%%\n" | |
507 | "%s\n\n", info->packager); | |
508 | } | |
509 | if(info->size) { | |
510 | fprintf(fp, "%%SIZE%%\n" | |
511 | "%ld\n\n", info->size); | |
512 | } | |
513 | if(info->reason) { | |
514 | fprintf(fp, "%%REASON%%\n" | |
515 | "%d\n\n", info->reason); | |
516 | } | |
517 | } else { | |
518 | if(info->size) { | |
519 | fprintf(fp, "%%CSIZE%%\n" | |
520 | "%ld\n\n", info->size); | |
521 | } | |
d37ad048 AG |
522 | if(info->usize) { |
523 | fprintf(fp, "%%USIZE%%\n" | |
524 | "%ld\n\n", info->usize); | |
525 | } | |
526 | if(info->sha1sum) { | |
527 | fprintf(fp, "%%SHA1SUM%%\n" | |
528 | "%s\n\n", info->sha1sum); | |
529 | } else if(info->md5sum) { | |
e2faeb46 AF |
530 | fprintf(fp, "%%MD5SUM%%\n" |
531 | "%s\n\n", info->md5sum); | |
532 | } | |
533 | } | |
534 | fclose(fp); | |
535 | fp = NULL; | |
536 | } | |
537 | ||
538 | /* FILES */ | |
539 | if(local && (inforeq & INFRQ_FILES)) { | |
ad2c7463 | 540 | snprintf(path, PATH_MAX, "%s/%s-%s/files", db->path, info->name, info->version); |
e2faeb46 | 541 | if((fp = fopen(path, "w")) == NULL) { |
bb787e26 | 542 | _alpm_log(PM_LOG_ERROR, _("db_write: could not open file %s/files"), db->treename); |
e2faeb46 AF |
543 | retval = -1; |
544 | goto cleanup; | |
545 | } | |
546 | if(info->files) { | |
547 | fprintf(fp, "%%FILES%%\n"); | |
548 | for(lp = info->files; lp; lp = lp->next) { | |
549 | fprintf(fp, "%s\n", (char *)lp->data); | |
550 | } | |
551 | fprintf(fp, "\n"); | |
552 | } | |
553 | if(info->backup) { | |
554 | fprintf(fp, "%%BACKUP%%\n"); | |
555 | for(lp = info->backup; lp; lp = lp->next) { | |
556 | fprintf(fp, "%s\n", (char *)lp->data); | |
557 | } | |
558 | fprintf(fp, "\n"); | |
559 | } | |
560 | fclose(fp); | |
561 | fp = NULL; | |
562 | } | |
563 | ||
564 | /* DEPENDS */ | |
565 | if(inforeq & INFRQ_DEPENDS) { | |
ad2c7463 | 566 | snprintf(path, PATH_MAX, "%s/%s-%s/depends", db->path, info->name, info->version); |
e2faeb46 | 567 | if((fp = fopen(path, "w")) == NULL) { |
bb787e26 | 568 | _alpm_log(PM_LOG_ERROR, _("db_write: could not open file %s/depends"), db->treename); |
e2faeb46 AF |
569 | retval = -1; |
570 | goto cleanup; | |
571 | } | |
572 | if(info->depends) { | |
573 | fputs("%DEPENDS%\n", fp); | |
574 | for(lp = info->depends; lp; lp = lp->next) { | |
575 | fprintf(fp, "%s\n", (char *)lp->data); | |
576 | } | |
577 | fprintf(fp, "\n"); | |
578 | } | |
579 | if(local && info->requiredby) { | |
580 | fputs("%REQUIREDBY%\n", fp); | |
581 | for(lp = info->requiredby; lp; lp = lp->next) { | |
582 | fprintf(fp, "%s\n", (char *)lp->data); | |
583 | } | |
584 | fprintf(fp, "\n"); | |
585 | } | |
586 | if(info->conflicts) { | |
587 | fputs("%CONFLICTS%\n", fp); | |
588 | for(lp = info->conflicts; lp; lp = lp->next) { | |
589 | fprintf(fp, "%s\n", (char *)lp->data); | |
590 | } | |
591 | fprintf(fp, "\n"); | |
592 | } | |
593 | if(info->provides) { | |
594 | fputs("%PROVIDES%\n", fp); | |
595 | for(lp = info->provides; lp; lp = lp->next) { | |
596 | fprintf(fp, "%s\n", (char *)lp->data); | |
597 | } | |
598 | fprintf(fp, "\n"); | |
599 | } | |
600 | if(!local) { | |
601 | if(info->replaces) { | |
602 | fputs("%REPLACES%\n", fp); | |
603 | for(lp = info->replaces; lp; lp = lp->next) { | |
604 | fprintf(fp, "%s\n", (char *)lp->data); | |
605 | } | |
606 | fprintf(fp, "\n"); | |
607 | } | |
608 | if(info->force) { | |
609 | fprintf(fp, "%%FORCE%%\n" | |
610 | "\n"); | |
611 | } | |
612 | } | |
613 | fclose(fp); | |
614 | fp = NULL; | |
615 | } | |
616 | ||
617 | /* INSTALL */ | |
d37ad048 | 618 | /* nothing needed here (script is automatically extracted) */ |
e2faeb46 AF |
619 | |
620 | cleanup: | |
621 | umask(oldmask); | |
622 | ||
623 | if(fp) { | |
624 | fclose(fp); | |
625 | } | |
626 | ||
627 | return(retval); | |
628 | } | |
629 | ||
630 | int _alpm_db_remove(pmdb_t *db, pmpkg_t *info) | |
631 | { | |
632 | char path[PATH_MAX]; | |
633 | ||
634 | if(db == NULL || info == NULL) { | |
e8275fa9 | 635 | RET_ERR(PM_ERR_DB_NULL, -1); |
e2faeb46 AF |
636 | } |
637 | ||
e8275fa9 AG |
638 | snprintf(path, PATH_MAX, "%s/%s-%s", db->path, info->name, info->version); |
639 | if(_alpm_rmrf(path) == -1) { | |
e2faeb46 AF |
640 | return(-1); |
641 | } | |
642 | ||
643 | return(0); | |
644 | } | |
645 | ||
d37ad048 AG |
646 | /* reads dbpath/.lastupdate and populates *ts with the contents. |
647 | * *ts should be malloc'ed and should be at least 15 bytes. | |
648 | * | |
649 | * Returns 0 on success, 1 on error | |
650 | * | |
651 | */ | |
652 | int _alpm_db_getlastupdate(pmdb_t *db, char *ts) | |
653 | { | |
654 | FILE *fp; | |
655 | char file[PATH_MAX]; | |
656 | ||
657 | if(db == NULL || ts == NULL) { | |
658 | return(-1); | |
659 | } | |
660 | ||
661 | snprintf(file, PATH_MAX, "%s%s/%s/.lastupdate", handle->root, handle->dbpath, db->treename); | |
662 | ||
663 | /* get the last update time, if it's there */ | |
664 | if((fp = fopen(file, "r")) == NULL) { | |
665 | return(-1); | |
666 | } else { | |
667 | char line[256]; | |
668 | if(fgets(line, sizeof(line), fp)) { | |
669 | STRNCPY(ts, line, 15); /* YYYYMMDDHHMMSS */ | |
670 | ts[14] = '\0'; | |
671 | } else { | |
672 | fclose(fp); | |
673 | return(-1); | |
674 | } | |
675 | } | |
676 | fclose(fp); | |
677 | return(0); | |
678 | } | |
679 | ||
680 | /* writes the dbpath/.lastupdate with the contents of *ts | |
681 | */ | |
682 | int _alpm_db_setlastupdate(pmdb_t *db, char *ts) | |
683 | { | |
684 | FILE *fp; | |
685 | char file[PATH_MAX]; | |
686 | ||
687 | if(db == NULL || ts == NULL || strlen(ts) == 0) { | |
688 | return(-1); | |
689 | } | |
690 | ||
691 | snprintf(file, PATH_MAX, "%s%s/%s/.lastupdate", handle->root, handle->dbpath, db->treename); | |
692 | ||
693 | if((fp = fopen(file, "w")) == NULL) { | |
694 | return(-1); | |
695 | } | |
696 | if(fputs(ts, fp) <= 0) { | |
697 | fclose(fp); | |
698 | return(-1); | |
699 | } | |
700 | fclose(fp); | |
701 | ||
702 | return(0); | |
703 | } | |
704 | ||
e2faeb46 | 705 | /* vim: set ts=2 sw=2 noet: */ |