Bail early if we don't have a valid lockfile path
[pacman-ng.git] / lib / libalpm / handle.c
blob586aad1e86e823897d21a086d238ff7a5fc2b9ee
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 <stdlib.h>
26 #include <string.h>
27 #include <limits.h>
28 #include <sys/types.h>
29 #include <syslog.h>
30 #include <time.h>
31 #include <sys/stat.h>
32 #include <errno.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 /* global var for handle (private to libalpm) */
43 pmhandle_t *handle = NULL;
45 pmhandle_t *_alpm_handle_new()
47 pmhandle_t *handle;
49 CALLOC(handle, 1, sizeof(pmhandle_t), RET_ERR(PM_ERR_MEMORY, NULL));
51 return(handle);
54 void _alpm_handle_free(pmhandle_t *handle)
56 ALPM_LOG_FUNC;
58 if(handle == NULL) {
59 return;
62 /* close logfile */
63 if(handle->logstream) {
64 fclose(handle->logstream);
65 handle->logstream= NULL;
67 if(handle->usesyslog) {
68 handle->usesyslog = 0;
69 closelog();
72 /* free memory */
73 _alpm_trans_free(handle->trans);
74 FREE(handle->root);
75 FREE(handle->dbpath);
76 FREELIST(handle->cachedirs);
77 FREE(handle->logfile);
78 FREE(handle->lockfile);
79 FREE(handle->arch);
80 FREELIST(handle->dbs_sync);
81 FREELIST(handle->noupgrade);
82 FREELIST(handle->noextract);
83 FREELIST(handle->ignorepkg);
84 FREELIST(handle->ignoregrp);
85 FREE(handle);
88 alpm_cb_log SYMEXPORT alpm_option_get_logcb()
90 if (handle == NULL) {
91 pm_errno = PM_ERR_HANDLE_NULL;
92 return NULL;
94 return handle->logcb;
97 alpm_cb_download SYMEXPORT alpm_option_get_dlcb()
99 if (handle == NULL) {
100 pm_errno = PM_ERR_HANDLE_NULL;
101 return NULL;
103 return handle->dlcb;
106 alpm_cb_fetch SYMEXPORT alpm_option_get_fetchcb()
108 if (handle == NULL) {
109 pm_errno = PM_ERR_HANDLE_NULL;
110 return NULL;
112 return handle->fetchcb;
115 alpm_cb_totaldl SYMEXPORT alpm_option_get_totaldlcb()
117 if (handle == NULL) {
118 pm_errno = PM_ERR_HANDLE_NULL;
119 return NULL;
121 return handle->totaldlcb;
124 const char SYMEXPORT *alpm_option_get_root()
126 if (handle == NULL) {
127 pm_errno = PM_ERR_HANDLE_NULL;
128 return NULL;
130 return handle->root;
133 const char SYMEXPORT *alpm_option_get_dbpath()
135 if (handle == NULL) {
136 pm_errno = PM_ERR_HANDLE_NULL;
137 return NULL;
139 return handle->dbpath;
142 alpm_list_t SYMEXPORT *alpm_option_get_cachedirs()
144 if (handle == NULL) {
145 pm_errno = PM_ERR_HANDLE_NULL;
146 return NULL;
148 return handle->cachedirs;
151 const char SYMEXPORT *alpm_option_get_logfile()
153 if (handle == NULL) {
154 pm_errno = PM_ERR_HANDLE_NULL;
155 return NULL;
157 return handle->logfile;
160 const char SYMEXPORT *alpm_option_get_lockfile()
162 if (handle == NULL) {
163 pm_errno = PM_ERR_HANDLE_NULL;
164 return NULL;
166 return handle->lockfile;
169 int SYMEXPORT alpm_option_get_usesyslog()
171 if (handle == NULL) {
172 pm_errno = PM_ERR_HANDLE_NULL;
173 return -1;
175 return handle->usesyslog;
178 alpm_list_t SYMEXPORT *alpm_option_get_noupgrades()
180 if (handle == NULL) {
181 pm_errno = PM_ERR_HANDLE_NULL;
182 return NULL;
184 return handle->noupgrade;
187 alpm_list_t SYMEXPORT *alpm_option_get_noextracts()
189 if (handle == NULL) {
190 pm_errno = PM_ERR_HANDLE_NULL;
191 return NULL;
193 return handle->noextract;
196 alpm_list_t SYMEXPORT *alpm_option_get_ignorepkgs()
198 if (handle == NULL) {
199 pm_errno = PM_ERR_HANDLE_NULL;
200 return NULL;
202 return handle->ignorepkg;
205 alpm_list_t SYMEXPORT *alpm_option_get_ignoregrps()
207 if (handle == NULL) {
208 pm_errno = PM_ERR_HANDLE_NULL;
209 return NULL;
211 return handle->ignoregrp;
214 const char SYMEXPORT *alpm_option_get_arch()
216 if (handle == NULL) {
217 pm_errno = PM_ERR_HANDLE_NULL;
218 return NULL;
220 return handle->arch;
223 int SYMEXPORT alpm_option_get_usedelta()
225 if (handle == NULL) {
226 pm_errno = PM_ERR_HANDLE_NULL;
227 return -1;
229 return handle->usedelta;
232 int SYMEXPORT alpm_option_get_checkspace()
234 if (handle == NULL) {
235 pm_errno = PM_ERR_HANDLE_NULL;
236 return -1;
238 return handle->checkspace;
241 pmdb_t SYMEXPORT *alpm_option_get_localdb()
243 if (handle == NULL) {
244 pm_errno = PM_ERR_HANDLE_NULL;
245 return NULL;
247 return handle->db_local;
250 alpm_list_t SYMEXPORT *alpm_option_get_syncdbs()
252 if (handle == NULL) {
253 pm_errno = PM_ERR_HANDLE_NULL;
254 return NULL;
256 return handle->dbs_sync;
259 void SYMEXPORT alpm_option_set_logcb(alpm_cb_log cb)
261 if (handle == NULL) {
262 pm_errno = PM_ERR_HANDLE_NULL;
263 return;
265 handle->logcb = cb;
268 void SYMEXPORT alpm_option_set_dlcb(alpm_cb_download cb)
270 if (handle == NULL) {
271 pm_errno = PM_ERR_HANDLE_NULL;
272 return;
274 handle->dlcb = cb;
277 void SYMEXPORT alpm_option_set_fetchcb(alpm_cb_fetch cb)
279 if (handle == NULL) {
280 pm_errno = PM_ERR_HANDLE_NULL;
281 return;
283 handle->fetchcb = cb;
286 void SYMEXPORT alpm_option_set_totaldlcb(alpm_cb_totaldl cb)
288 if (handle == NULL) {
289 pm_errno = PM_ERR_HANDLE_NULL;
290 return;
292 handle->totaldlcb = cb;
295 int SYMEXPORT alpm_option_set_root(const char *root)
297 struct stat st;
298 char *realroot;
299 size_t rootlen;
301 ALPM_LOG_FUNC;
303 ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
305 if(!root) {
306 pm_errno = PM_ERR_WRONG_ARGS;
307 return(-1);
309 if(stat(root, &st) == -1 || !S_ISDIR(st.st_mode)) {
310 pm_errno = PM_ERR_NOT_A_DIR;
311 return(-1);
314 realroot = calloc(PATH_MAX+1, sizeof(char));
315 if(!realpath(root, realroot)) {
316 FREE(realroot);
317 pm_errno = PM_ERR_NOT_A_DIR;
318 return(-1);
321 /* verify root ends in a '/' */
322 rootlen = strlen(realroot);
323 if(realroot[rootlen-1] != '/') {
324 rootlen += 1;
326 if(handle->root) {
327 FREE(handle->root);
329 handle->root = calloc(rootlen + 1, sizeof(char));
330 strncpy(handle->root, realroot, rootlen);
331 handle->root[rootlen-1] = '/';
332 FREE(realroot);
333 _alpm_log(PM_LOG_DEBUG, "option 'root' = %s\n", handle->root);
334 return(0);
337 int SYMEXPORT alpm_option_set_dbpath(const char *dbpath)
339 struct stat st;
340 size_t dbpathlen, lockfilelen;
341 const char *lf = "db.lck";
343 ALPM_LOG_FUNC;
345 ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
346 if(!dbpath) {
347 pm_errno = PM_ERR_WRONG_ARGS;
348 return(-1);
350 if(stat(dbpath, &st) == -1 || !S_ISDIR(st.st_mode)) {
351 pm_errno = PM_ERR_NOT_A_DIR;
352 return(-1);
354 /* verify dbpath ends in a '/' */
355 dbpathlen = strlen(dbpath);
356 if(dbpath[dbpathlen-1] != '/') {
357 dbpathlen += 1;
359 if(handle->dbpath) {
360 FREE(handle->dbpath);
362 handle->dbpath = calloc(dbpathlen+1, sizeof(char));
363 strncpy(handle->dbpath, dbpath, dbpathlen);
364 handle->dbpath[dbpathlen-1] = '/';
365 _alpm_log(PM_LOG_DEBUG, "option 'dbpath' = %s\n", handle->dbpath);
367 if(handle->lockfile) {
368 FREE(handle->lockfile);
370 lockfilelen = strlen(handle->dbpath) + strlen(lf) + 1;
371 handle->lockfile = calloc(lockfilelen, sizeof(char));
372 snprintf(handle->lockfile, lockfilelen, "%s%s", handle->dbpath, lf);
373 _alpm_log(PM_LOG_DEBUG, "option 'lockfile' = %s\n", handle->lockfile);
374 return(0);
377 int SYMEXPORT alpm_option_add_cachedir(const char *cachedir)
379 char *newcachedir;
380 size_t cachedirlen;
382 ALPM_LOG_FUNC;
384 ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
385 if(!cachedir) {
386 pm_errno = PM_ERR_WRONG_ARGS;
387 return(-1);
389 /* don't stat the cachedir yet, as it may not even be needed. we can
390 * fail later if it is needed and the path is invalid. */
392 /* verify cachedir ends in a '/' */
393 cachedirlen = strlen(cachedir);
394 if(cachedir[cachedirlen-1] != '/') {
395 cachedirlen += 1;
397 newcachedir = calloc(cachedirlen + 1, sizeof(char));
398 strncpy(newcachedir, cachedir, cachedirlen);
399 newcachedir[cachedirlen-1] = '/';
400 handle->cachedirs = alpm_list_add(handle->cachedirs, newcachedir);
401 _alpm_log(PM_LOG_DEBUG, "option 'cachedir' = %s\n", newcachedir);
402 return(0);
405 void SYMEXPORT alpm_option_set_cachedirs(alpm_list_t *cachedirs)
407 ASSERT(handle != NULL, RET_ERR_VOID(PM_ERR_HANDLE_NULL));
408 if(handle->cachedirs) FREELIST(handle->cachedirs);
409 if(cachedirs) handle->cachedirs = cachedirs;
412 int SYMEXPORT alpm_option_remove_cachedir(const char *cachedir)
414 char *vdata = NULL;
415 char *newcachedir;
416 size_t cachedirlen;
417 ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
418 /* verify cachedir ends in a '/' */
419 cachedirlen = strlen(cachedir);
420 if(cachedir[cachedirlen-1] != '/') {
421 cachedirlen += 1;
423 newcachedir = calloc(cachedirlen + 1, sizeof(char));
424 strncpy(newcachedir, cachedir, cachedirlen);
425 newcachedir[cachedirlen-1] = '/';
426 handle->cachedirs = alpm_list_remove_str(handle->cachedirs, newcachedir, &vdata);
427 FREE(newcachedir);
428 if(vdata != NULL) {
429 FREE(vdata);
430 return(1);
432 return(0);
435 int SYMEXPORT alpm_option_set_logfile(const char *logfile)
437 char *oldlogfile = handle->logfile;
439 ALPM_LOG_FUNC;
441 ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
442 if(!logfile) {
443 pm_errno = PM_ERR_WRONG_ARGS;
444 return(-1);
447 handle->logfile = strdup(logfile);
449 /* free the old logfile path string, and close the stream so logaction
450 * will reopen a new stream on the new logfile */
451 if(oldlogfile) {
452 FREE(oldlogfile);
454 if(handle->logstream) {
455 fclose(handle->logstream);
456 handle->logstream = NULL;
458 _alpm_log(PM_LOG_DEBUG, "option 'logfile' = %s\n", handle->logfile);
459 return(0);
462 void SYMEXPORT alpm_option_set_usesyslog(int usesyslog)
464 ASSERT(handle != NULL, RET_ERR_VOID(PM_ERR_HANDLE_NULL));
465 handle->usesyslog = usesyslog;
468 void SYMEXPORT alpm_option_add_noupgrade(const char *pkg)
470 ASSERT(handle != NULL, RET_ERR_VOID(PM_ERR_HANDLE_NULL));
471 handle->noupgrade = alpm_list_add(handle->noupgrade, strdup(pkg));
474 void SYMEXPORT alpm_option_set_noupgrades(alpm_list_t *noupgrade)
476 ASSERT(handle != NULL, RET_ERR_VOID(PM_ERR_HANDLE_NULL));
477 if(handle->noupgrade) FREELIST(handle->noupgrade);
478 if(noupgrade) handle->noupgrade = noupgrade;
481 int SYMEXPORT alpm_option_remove_noupgrade(const char *pkg)
483 char *vdata = NULL;
484 ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
485 handle->noupgrade = alpm_list_remove_str(handle->noupgrade, pkg, &vdata);
486 if(vdata != NULL) {
487 FREE(vdata);
488 return(1);
490 return(0);
493 void SYMEXPORT alpm_option_add_noextract(const char *pkg)
495 ASSERT(handle != NULL, RET_ERR_VOID(PM_ERR_HANDLE_NULL));
496 handle->noextract = alpm_list_add(handle->noextract, strdup(pkg));
499 void SYMEXPORT alpm_option_set_noextracts(alpm_list_t *noextract)
501 ASSERT(handle != NULL, RET_ERR_VOID(PM_ERR_HANDLE_NULL));
502 if(handle->noextract) FREELIST(handle->noextract);
503 if(noextract) handle->noextract = noextract;
506 int SYMEXPORT alpm_option_remove_noextract(const char *pkg)
508 char *vdata = NULL;
509 ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
510 handle->noextract = alpm_list_remove_str(handle->noextract, pkg, &vdata);
511 if(vdata != NULL) {
512 FREE(vdata);
513 return(1);
515 return(0);
518 void SYMEXPORT alpm_option_add_ignorepkg(const char *pkg)
520 ASSERT(handle != NULL, RET_ERR_VOID(PM_ERR_HANDLE_NULL));
521 handle->ignorepkg = alpm_list_add(handle->ignorepkg, strdup(pkg));
524 void SYMEXPORT alpm_option_set_ignorepkgs(alpm_list_t *ignorepkgs)
526 ASSERT(handle != NULL, RET_ERR_VOID(PM_ERR_HANDLE_NULL));
527 if(handle->ignorepkg) FREELIST(handle->ignorepkg);
528 if(ignorepkgs) handle->ignorepkg = ignorepkgs;
531 int SYMEXPORT alpm_option_remove_ignorepkg(const char *pkg)
533 char *vdata = NULL;
534 ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
535 handle->ignorepkg = alpm_list_remove_str(handle->ignorepkg, pkg, &vdata);
536 if(vdata != NULL) {
537 FREE(vdata);
538 return(1);
540 return(0);
543 void SYMEXPORT alpm_option_add_ignoregrp(const char *grp)
545 ASSERT(handle != NULL, RET_ERR_VOID(PM_ERR_HANDLE_NULL));
546 handle->ignoregrp = alpm_list_add(handle->ignoregrp, strdup(grp));
549 void SYMEXPORT alpm_option_set_ignoregrps(alpm_list_t *ignoregrps)
551 ASSERT(handle != NULL, RET_ERR_VOID(PM_ERR_HANDLE_NULL));
552 if(handle->ignoregrp) FREELIST(handle->ignoregrp);
553 if(ignoregrps) handle->ignoregrp = ignoregrps;
556 int SYMEXPORT alpm_option_remove_ignoregrp(const char *grp)
558 char *vdata = NULL;
559 ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
560 handle->ignoregrp = alpm_list_remove_str(handle->ignoregrp, grp, &vdata);
561 if(vdata != NULL) {
562 FREE(vdata);
563 return(1);
565 return(0);
568 void SYMEXPORT alpm_option_set_arch(const char *arch)
570 ASSERT(handle != NULL, RET_ERR_VOID(PM_ERR_HANDLE_NULL));
571 if(handle->arch) FREE(handle->arch);
572 if(arch) handle->arch = strdup(arch);
575 void SYMEXPORT alpm_option_set_usedelta(int usedelta)
577 ASSERT(handle != NULL, RET_ERR_VOID(PM_ERR_HANDLE_NULL));
578 handle->usedelta = usedelta;
581 void SYMEXPORT alpm_option_set_checkspace(int checkspace)
583 ASSERT(handle != NULL, RET_ERR_VOID(PM_ERR_HANDLE_NULL));
584 handle->checkspace = checkspace;
587 /* vim: set ts=2 sw=2 noet: */