Remove most usages of strncmp()
[pacman-ng.git] / lib / libalpm / handle.c
blob9bffd4fd80563ce1cbb704c6a9843595bb285599
1 /*
2 * handle.c
4 * Copyright (c) 2006-2011 Pacman Development Team <pacman-dev@archlinux.org>
5 * Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
6 * Copyright (c) 2005 by Aurelien Foret <orelien@chez.com>
7 * Copyright (c) 2005, 2006 by Miklos Vajna <vmiklos@frugalware.org>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include "config.h"
25 #include <errno.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <limits.h>
29 #include <sys/types.h>
30 #include <syslog.h>
31 #include <sys/stat.h>
32 #include <fcntl.h>
34 /* libalpm */
35 #include "handle.h"
36 #include "alpm_list.h"
37 #include "util.h"
38 #include "log.h"
39 #include "trans.h"
40 #include "alpm.h"
42 alpm_handle_t *_alpm_handle_new()
44 alpm_handle_t *handle;
46 CALLOC(handle, 1, sizeof(alpm_handle_t), return NULL);
48 handle->siglevel = ALPM_SIG_PACKAGE | ALPM_SIG_PACKAGE_OPTIONAL |
49 ALPM_SIG_DATABASE | ALPM_SIG_DATABASE_OPTIONAL;
51 return handle;
54 void _alpm_handle_free(alpm_handle_t *handle)
56 if(handle == NULL) {
57 return;
60 /* close logfile */
61 if(handle->logstream) {
62 fclose(handle->logstream);
63 handle->logstream= NULL;
65 if(handle->usesyslog) {
66 handle->usesyslog = 0;
67 closelog();
70 #ifdef HAVE_LIBCURL
71 /* release curl handle */
72 curl_easy_cleanup(handle->curl);
73 #endif
75 /* free memory */
76 _alpm_trans_free(handle->trans);
77 FREE(handle->root);
78 FREE(handle->dbpath);
79 FREELIST(handle->cachedirs);
80 FREE(handle->logfile);
81 FREE(handle->lockfile);
82 FREE(handle->arch);
83 FREE(handle->gpgdir);
84 FREELIST(handle->dbs_sync);
85 FREELIST(handle->noupgrade);
86 FREELIST(handle->noextract);
87 FREELIST(handle->ignorepkg);
88 FREELIST(handle->ignoregroup);
89 FREE(handle);
92 /** Lock the database */
93 int _alpm_handle_lock(alpm_handle_t *handle)
95 int fd;
96 char *dir, *ptr;
98 ASSERT(handle->lockfile != NULL, return -1);
99 ASSERT(handle->lckstream == NULL, return 0);
101 /* create the dir of the lockfile first */
102 dir = strdup(handle->lockfile);
103 ptr = strrchr(dir, '/');
104 if(ptr) {
105 *ptr = '\0';
107 if(_alpm_makepath(dir)) {
108 FREE(dir);
109 return -1;
111 FREE(dir);
113 do {
114 fd = open(handle->lockfile, O_WRONLY | O_CREAT | O_EXCL, 0000);
115 } while(fd == -1 && errno == EINTR);
116 if(fd > 0) {
117 FILE *f = fdopen(fd, "w");
118 fprintf(f, "%ld\n", (long)getpid());
119 fflush(f);
120 fsync(fd);
121 handle->lckstream = f;
122 return 0;
124 return -1;
127 /** Remove a lock file */
128 int _alpm_handle_unlock(alpm_handle_t *handle)
130 ASSERT(handle->lockfile != NULL, return -1);
131 ASSERT(handle->lckstream != NULL, return 0);
133 if(handle->lckstream != NULL) {
134 fclose(handle->lckstream);
135 handle->lckstream = NULL;
137 if(unlink(handle->lockfile) && errno != ENOENT) {
138 return -1;
140 return 0;
144 alpm_cb_log SYMEXPORT alpm_option_get_logcb(alpm_handle_t *handle)
146 CHECK_HANDLE(handle, return NULL);
147 return handle->logcb;
150 alpm_cb_download SYMEXPORT alpm_option_get_dlcb(alpm_handle_t *handle)
152 CHECK_HANDLE(handle, return NULL);
153 return handle->dlcb;
156 alpm_cb_fetch SYMEXPORT alpm_option_get_fetchcb(alpm_handle_t *handle)
158 CHECK_HANDLE(handle, return NULL);
159 return handle->fetchcb;
162 alpm_cb_totaldl SYMEXPORT alpm_option_get_totaldlcb(alpm_handle_t *handle)
164 CHECK_HANDLE(handle, return NULL);
165 return handle->totaldlcb;
168 const char SYMEXPORT *alpm_option_get_root(alpm_handle_t *handle)
170 CHECK_HANDLE(handle, return NULL);
171 return handle->root;
174 const char SYMEXPORT *alpm_option_get_dbpath(alpm_handle_t *handle)
176 CHECK_HANDLE(handle, return NULL);
177 return handle->dbpath;
180 alpm_list_t SYMEXPORT *alpm_option_get_cachedirs(alpm_handle_t *handle)
182 CHECK_HANDLE(handle, return NULL);
183 return handle->cachedirs;
186 const char SYMEXPORT *alpm_option_get_logfile(alpm_handle_t *handle)
188 CHECK_HANDLE(handle, return NULL);
189 return handle->logfile;
192 const char SYMEXPORT *alpm_option_get_lockfile(alpm_handle_t *handle)
194 CHECK_HANDLE(handle, return NULL);
195 return handle->lockfile;
198 const char SYMEXPORT *alpm_option_get_gpgdir(alpm_handle_t *handle)
200 CHECK_HANDLE(handle, return NULL);
201 return handle->gpgdir;
204 int SYMEXPORT alpm_option_get_usesyslog(alpm_handle_t *handle)
206 CHECK_HANDLE(handle, return -1);
207 return handle->usesyslog;
210 alpm_list_t SYMEXPORT *alpm_option_get_noupgrades(alpm_handle_t *handle)
212 CHECK_HANDLE(handle, return NULL);
213 return handle->noupgrade;
216 alpm_list_t SYMEXPORT *alpm_option_get_noextracts(alpm_handle_t *handle)
218 CHECK_HANDLE(handle, return NULL);
219 return handle->noextract;
222 alpm_list_t SYMEXPORT *alpm_option_get_ignorepkgs(alpm_handle_t *handle)
224 CHECK_HANDLE(handle, return NULL);
225 return handle->ignorepkg;
228 alpm_list_t SYMEXPORT *alpm_option_get_ignoregroups(alpm_handle_t *handle)
230 CHECK_HANDLE(handle, return NULL);
231 return handle->ignoregroup;
234 const char SYMEXPORT *alpm_option_get_arch(alpm_handle_t *handle)
236 CHECK_HANDLE(handle, return NULL);
237 return handle->arch;
240 int SYMEXPORT alpm_option_get_usedelta(alpm_handle_t *handle)
242 CHECK_HANDLE(handle, return -1);
243 return handle->usedelta;
246 int SYMEXPORT alpm_option_get_checkspace(alpm_handle_t *handle)
248 CHECK_HANDLE(handle, return -1);
249 return handle->checkspace;
252 alpm_db_t SYMEXPORT *alpm_option_get_localdb(alpm_handle_t *handle)
254 CHECK_HANDLE(handle, return NULL);
255 return handle->db_local;
258 alpm_list_t SYMEXPORT *alpm_option_get_syncdbs(alpm_handle_t *handle)
260 CHECK_HANDLE(handle, return NULL);
261 return handle->dbs_sync;
264 int SYMEXPORT alpm_option_set_logcb(alpm_handle_t *handle, alpm_cb_log cb)
266 CHECK_HANDLE(handle, return -1);
267 handle->logcb = cb;
268 return 0;
271 int SYMEXPORT alpm_option_set_dlcb(alpm_handle_t *handle, alpm_cb_download cb)
273 CHECK_HANDLE(handle, return -1);
274 handle->dlcb = cb;
275 return 0;
278 int SYMEXPORT alpm_option_set_fetchcb(alpm_handle_t *handle, alpm_cb_fetch cb)
280 CHECK_HANDLE(handle, return -1);
281 handle->fetchcb = cb;
282 return 0;
285 int SYMEXPORT alpm_option_set_totaldlcb(alpm_handle_t *handle, alpm_cb_totaldl cb)
287 CHECK_HANDLE(handle, return -1);
288 handle->totaldlcb = cb;
289 return 0;
292 static char *canonicalize_path(const char *path) {
293 char *new_path;
294 size_t len;
296 /* verify path ends in a '/' */
297 len = strlen(path);
298 if(path[len - 1] != '/') {
299 len += 1;
301 CALLOC(new_path, len + 1, sizeof(char), return NULL);
302 strcpy(new_path, path);
303 new_path[len - 1] = '/';
304 return new_path;
307 enum _alpm_errno_t _alpm_set_directory_option(const char *value,
308 char **storage, int must_exist)
310 struct stat st;
311 char *real = NULL;
312 const char *path;
314 path = value;
315 if(!path) {
316 return ALPM_ERR_WRONG_ARGS;
318 if(must_exist) {
319 if(stat(path, &st) == -1 || !S_ISDIR(st.st_mode)) {
320 return ALPM_ERR_NOT_A_DIR;
322 CALLOC(real, PATH_MAX, sizeof(char), return ALPM_ERR_MEMORY);
323 if(!realpath(path, real)) {
324 free(real);
325 return ALPM_ERR_NOT_A_DIR;
327 path = real;
330 if(*storage) {
331 FREE(*storage);
333 *storage = canonicalize_path(path);
334 if(!*storage) {
335 return ALPM_ERR_MEMORY;
337 free(real);
338 return 0;
341 int SYMEXPORT alpm_option_add_cachedir(alpm_handle_t *handle, const char *cachedir)
343 char *newcachedir;
345 CHECK_HANDLE(handle, return -1);
346 ASSERT(cachedir != NULL, RET_ERR(handle, ALPM_ERR_WRONG_ARGS, -1));
347 /* don't stat the cachedir yet, as it may not even be needed. we can
348 * fail later if it is needed and the path is invalid. */
350 newcachedir = canonicalize_path(cachedir);
351 if(!newcachedir) {
352 RET_ERR(handle, ALPM_ERR_MEMORY, -1);
354 handle->cachedirs = alpm_list_add(handle->cachedirs, newcachedir);
355 _alpm_log(handle, ALPM_LOG_DEBUG, "option 'cachedir' = %s\n", newcachedir);
356 return 0;
359 int SYMEXPORT alpm_option_set_cachedirs(alpm_handle_t *handle, alpm_list_t *cachedirs)
361 alpm_list_t *i;
362 CHECK_HANDLE(handle, return -1);
363 if(handle->cachedirs) {
364 FREELIST(handle->cachedirs);
366 for(i = cachedirs; i; i = i->next) {
367 int ret = alpm_option_add_cachedir(handle, i->data);
368 if(ret) {
369 return ret;
372 return 0;
375 int SYMEXPORT alpm_option_remove_cachedir(alpm_handle_t *handle, const char *cachedir)
377 char *vdata = NULL;
378 char *newcachedir;
379 CHECK_HANDLE(handle, return -1);
380 ASSERT(cachedir != NULL, RET_ERR(handle, ALPM_ERR_WRONG_ARGS, -1));
382 newcachedir = canonicalize_path(cachedir);
383 if(!newcachedir) {
384 RET_ERR(handle, ALPM_ERR_MEMORY, -1);
386 handle->cachedirs = alpm_list_remove_str(handle->cachedirs, newcachedir, &vdata);
387 FREE(newcachedir);
388 if(vdata != NULL) {
389 FREE(vdata);
390 return 1;
392 return 0;
395 int SYMEXPORT alpm_option_set_logfile(alpm_handle_t *handle, const char *logfile)
397 char *oldlogfile = handle->logfile;
399 CHECK_HANDLE(handle, return -1);
400 if(!logfile) {
401 handle->pm_errno = ALPM_ERR_WRONG_ARGS;
402 return -1;
405 handle->logfile = strdup(logfile);
407 /* free the old logfile path string, and close the stream so logaction
408 * will reopen a new stream on the new logfile */
409 if(oldlogfile) {
410 FREE(oldlogfile);
412 if(handle->logstream) {
413 fclose(handle->logstream);
414 handle->logstream = NULL;
416 _alpm_log(handle, ALPM_LOG_DEBUG, "option 'logfile' = %s\n", handle->logfile);
417 return 0;
420 int SYMEXPORT alpm_option_set_gpgdir(alpm_handle_t *handle, const char *gpgdir)
422 CHECK_HANDLE(handle, return -1);
423 if(!gpgdir) {
424 handle->pm_errno = ALPM_ERR_WRONG_ARGS;
425 return -1;
428 if(handle->gpgdir) {
429 FREE(handle->gpgdir);
431 handle->gpgdir = strdup(gpgdir);
433 _alpm_log(handle, ALPM_LOG_DEBUG, "option 'gpgdir' = %s\n", handle->gpgdir);
434 return 0;
437 int SYMEXPORT alpm_option_set_usesyslog(alpm_handle_t *handle, int usesyslog)
439 CHECK_HANDLE(handle, return -1);
440 handle->usesyslog = usesyslog;
441 return 0;
444 int SYMEXPORT alpm_option_add_noupgrade(alpm_handle_t *handle, const char *pkg)
446 CHECK_HANDLE(handle, return -1);
447 handle->noupgrade = alpm_list_add(handle->noupgrade, strdup(pkg));
448 return 0;
451 int SYMEXPORT alpm_option_set_noupgrades(alpm_handle_t *handle, alpm_list_t *noupgrade)
453 CHECK_HANDLE(handle, return -1);
454 if(handle->noupgrade) FREELIST(handle->noupgrade);
455 handle->noupgrade = alpm_list_strdup(noupgrade);
456 return 0;
459 int SYMEXPORT alpm_option_remove_noupgrade(alpm_handle_t *handle, const char *pkg)
461 char *vdata = NULL;
462 CHECK_HANDLE(handle, return -1);
463 handle->noupgrade = alpm_list_remove_str(handle->noupgrade, pkg, &vdata);
464 if(vdata != NULL) {
465 FREE(vdata);
466 return 1;
468 return 0;
471 int SYMEXPORT alpm_option_add_noextract(alpm_handle_t *handle, const char *pkg)
473 CHECK_HANDLE(handle, return -1);
474 handle->noextract = alpm_list_add(handle->noextract, strdup(pkg));
475 return 0;
478 int SYMEXPORT alpm_option_set_noextracts(alpm_handle_t *handle, alpm_list_t *noextract)
480 CHECK_HANDLE(handle, return -1);
481 if(handle->noextract) FREELIST(handle->noextract);
482 handle->noextract = alpm_list_strdup(noextract);
483 return 0;
486 int SYMEXPORT alpm_option_remove_noextract(alpm_handle_t *handle, const char *pkg)
488 char *vdata = NULL;
489 CHECK_HANDLE(handle, return -1);
490 handle->noextract = alpm_list_remove_str(handle->noextract, pkg, &vdata);
491 if(vdata != NULL) {
492 FREE(vdata);
493 return 1;
495 return 0;
498 int SYMEXPORT alpm_option_add_ignorepkg(alpm_handle_t *handle, const char *pkg)
500 CHECK_HANDLE(handle, return -1);
501 handle->ignorepkg = alpm_list_add(handle->ignorepkg, strdup(pkg));
502 return 0;
505 int SYMEXPORT alpm_option_set_ignorepkgs(alpm_handle_t *handle, alpm_list_t *ignorepkgs)
507 CHECK_HANDLE(handle, return -1);
508 if(handle->ignorepkg) FREELIST(handle->ignorepkg);
509 handle->ignorepkg = alpm_list_strdup(ignorepkgs);
510 return 0;
513 int SYMEXPORT alpm_option_remove_ignorepkg(alpm_handle_t *handle, const char *pkg)
515 char *vdata = NULL;
516 CHECK_HANDLE(handle, return -1);
517 handle->ignorepkg = alpm_list_remove_str(handle->ignorepkg, pkg, &vdata);
518 if(vdata != NULL) {
519 FREE(vdata);
520 return 1;
522 return 0;
525 int SYMEXPORT alpm_option_add_ignoregroup(alpm_handle_t *handle, const char *grp)
527 CHECK_HANDLE(handle, return -1);
528 handle->ignoregroup = alpm_list_add(handle->ignoregroup, strdup(grp));
529 return 0;
532 int SYMEXPORT alpm_option_set_ignoregroups(alpm_handle_t *handle, alpm_list_t *ignoregrps)
534 CHECK_HANDLE(handle, return -1);
535 if(handle->ignoregroup) FREELIST(handle->ignoregroup);
536 handle->ignoregroup = alpm_list_strdup(ignoregrps);
537 return 0;
540 int SYMEXPORT alpm_option_remove_ignoregroup(alpm_handle_t *handle, const char *grp)
542 char *vdata = NULL;
543 CHECK_HANDLE(handle, return -1);
544 handle->ignoregroup = alpm_list_remove_str(handle->ignoregroup, grp, &vdata);
545 if(vdata != NULL) {
546 FREE(vdata);
547 return 1;
549 return 0;
552 int SYMEXPORT alpm_option_set_arch(alpm_handle_t *handle, const char *arch)
554 CHECK_HANDLE(handle, return -1);
555 if(handle->arch) FREE(handle->arch);
556 if(arch) {
557 handle->arch = strdup(arch);
558 } else {
559 handle->arch = NULL;
561 return 0;
564 int SYMEXPORT alpm_option_set_usedelta(alpm_handle_t *handle, int usedelta)
566 CHECK_HANDLE(handle, return -1);
567 handle->usedelta = usedelta;
568 return 0;
571 int SYMEXPORT alpm_option_set_checkspace(alpm_handle_t *handle, int checkspace)
573 CHECK_HANDLE(handle, return -1);
574 handle->checkspace = checkspace;
575 return 0;
578 int SYMEXPORT alpm_option_set_default_siglevel(alpm_handle_t *handle,
579 alpm_siglevel_t level)
581 CHECK_HANDLE(handle, return -1);
582 handle->siglevel = level;
583 return 0;
586 alpm_siglevel_t SYMEXPORT alpm_option_get_default_siglevel(alpm_handle_t *handle)
588 CHECK_HANDLE(handle, return -1);
589 return handle->siglevel;
592 /* vim: set ts=2 sw=2 noet: */