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/>.
29 #include <sys/types.h>
36 #include "alpm_list.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
->sigverify
= PM_PGP_VERIFY_OPTIONAL
;
53 void _alpm_handle_free(alpm_handle_t
*handle
)
60 if(handle
->logstream
) {
61 fclose(handle
->logstream
);
62 handle
->logstream
= NULL
;
64 if(handle
->usesyslog
) {
65 handle
->usesyslog
= 0;
70 /* release curl handle */
71 curl_easy_cleanup(handle
->curl
);
75 _alpm_trans_free(handle
->trans
);
78 FREELIST(handle
->cachedirs
);
79 FREE(handle
->logfile
);
80 FREE(handle
->lockfile
);
83 FREELIST(handle
->dbs_sync
);
84 FREELIST(handle
->noupgrade
);
85 FREELIST(handle
->noextract
);
86 FREELIST(handle
->ignorepkg
);
87 FREELIST(handle
->ignoregrp
);
91 /** Lock the database */
92 int _alpm_handle_lock(alpm_handle_t
*handle
)
97 ASSERT(handle
->lockfile
!= NULL
, return -1);
98 ASSERT(handle
->lckstream
== NULL
, return 0);
100 /* create the dir of the lockfile first */
101 dir
= strdup(handle
->lockfile
);
102 ptr
= strrchr(dir
, '/');
106 if(_alpm_makepath(dir
)) {
113 fd
= open(handle
->lockfile
, O_WRONLY
| O_CREAT
| O_EXCL
, 0000);
114 } while(fd
== -1 && errno
== EINTR
);
116 FILE *f
= fdopen(fd
, "w");
117 fprintf(f
, "%ld\n", (long)getpid());
120 handle
->lckstream
= f
;
126 /** Remove a lock file */
127 int _alpm_handle_unlock(alpm_handle_t
*handle
)
129 ASSERT(handle
->lockfile
!= NULL
, return -1);
130 ASSERT(handle
->lckstream
!= NULL
, return 0);
132 if(handle
->lckstream
!= NULL
) {
133 fclose(handle
->lckstream
);
134 handle
->lckstream
= NULL
;
136 if(unlink(handle
->lockfile
) && errno
!= ENOENT
) {
143 alpm_cb_log SYMEXPORT
alpm_option_get_logcb(alpm_handle_t
*handle
)
145 CHECK_HANDLE(handle
, return NULL
);
146 return handle
->logcb
;
149 alpm_cb_download SYMEXPORT
alpm_option_get_dlcb(alpm_handle_t
*handle
)
151 CHECK_HANDLE(handle
, return NULL
);
155 alpm_cb_fetch SYMEXPORT
alpm_option_get_fetchcb(alpm_handle_t
*handle
)
157 CHECK_HANDLE(handle
, return NULL
);
158 return handle
->fetchcb
;
161 alpm_cb_totaldl SYMEXPORT
alpm_option_get_totaldlcb(alpm_handle_t
*handle
)
163 CHECK_HANDLE(handle
, return NULL
);
164 return handle
->totaldlcb
;
167 const char SYMEXPORT
*alpm_option_get_root(alpm_handle_t
*handle
)
169 CHECK_HANDLE(handle
, return NULL
);
173 const char SYMEXPORT
*alpm_option_get_dbpath(alpm_handle_t
*handle
)
175 CHECK_HANDLE(handle
, return NULL
);
176 return handle
->dbpath
;
179 alpm_list_t SYMEXPORT
*alpm_option_get_cachedirs(alpm_handle_t
*handle
)
181 CHECK_HANDLE(handle
, return NULL
);
182 return handle
->cachedirs
;
185 const char SYMEXPORT
*alpm_option_get_logfile(alpm_handle_t
*handle
)
187 CHECK_HANDLE(handle
, return NULL
);
188 return handle
->logfile
;
191 const char SYMEXPORT
*alpm_option_get_lockfile(alpm_handle_t
*handle
)
193 CHECK_HANDLE(handle
, return NULL
);
194 return handle
->lockfile
;
197 const char SYMEXPORT
*alpm_option_get_gpgdir(alpm_handle_t
*handle
)
199 CHECK_HANDLE(handle
, return NULL
);
200 return handle
->gpgdir
;
203 int SYMEXPORT
alpm_option_get_usesyslog(alpm_handle_t
*handle
)
205 CHECK_HANDLE(handle
, return -1);
206 return handle
->usesyslog
;
209 alpm_list_t SYMEXPORT
*alpm_option_get_noupgrades(alpm_handle_t
*handle
)
211 CHECK_HANDLE(handle
, return NULL
);
212 return handle
->noupgrade
;
215 alpm_list_t SYMEXPORT
*alpm_option_get_noextracts(alpm_handle_t
*handle
)
217 CHECK_HANDLE(handle
, return NULL
);
218 return handle
->noextract
;
221 alpm_list_t SYMEXPORT
*alpm_option_get_ignorepkgs(alpm_handle_t
*handle
)
223 CHECK_HANDLE(handle
, return NULL
);
224 return handle
->ignorepkg
;
227 alpm_list_t SYMEXPORT
*alpm_option_get_ignoregroups(alpm_handle_t
*handle
)
229 CHECK_HANDLE(handle
, return NULL
);
230 return handle
->ignoregrp
;
233 const char SYMEXPORT
*alpm_option_get_arch(alpm_handle_t
*handle
)
235 CHECK_HANDLE(handle
, return NULL
);
239 int SYMEXPORT
alpm_option_get_usedelta(alpm_handle_t
*handle
)
241 CHECK_HANDLE(handle
, return -1);
242 return handle
->usedelta
;
245 int SYMEXPORT
alpm_option_get_checkspace(alpm_handle_t
*handle
)
247 CHECK_HANDLE(handle
, return -1);
248 return handle
->checkspace
;
251 alpm_db_t SYMEXPORT
*alpm_option_get_localdb(alpm_handle_t
*handle
)
253 CHECK_HANDLE(handle
, return NULL
);
254 return handle
->db_local
;
257 alpm_list_t SYMEXPORT
*alpm_option_get_syncdbs(alpm_handle_t
*handle
)
259 CHECK_HANDLE(handle
, return NULL
);
260 return handle
->dbs_sync
;
263 int SYMEXPORT
alpm_option_set_logcb(alpm_handle_t
*handle
, alpm_cb_log cb
)
265 CHECK_HANDLE(handle
, return -1);
270 int SYMEXPORT
alpm_option_set_dlcb(alpm_handle_t
*handle
, alpm_cb_download cb
)
272 CHECK_HANDLE(handle
, return -1);
277 int SYMEXPORT
alpm_option_set_fetchcb(alpm_handle_t
*handle
, alpm_cb_fetch cb
)
279 CHECK_HANDLE(handle
, return -1);
280 handle
->fetchcb
= cb
;
284 int SYMEXPORT
alpm_option_set_totaldlcb(alpm_handle_t
*handle
, alpm_cb_totaldl cb
)
286 CHECK_HANDLE(handle
, return -1);
287 handle
->totaldlcb
= cb
;
291 static char *canonicalize_path(const char *path
) {
295 /* verify path ends in a '/' */
297 if(path
[len
- 1] != '/') {
300 CALLOC(new_path
, len
+ 1, sizeof(char), return NULL
);
301 strncpy(new_path
, path
, len
);
302 new_path
[len
- 1] = '/';
306 enum _alpm_errno_t
_alpm_set_directory_option(const char *value
,
307 char **storage
, int must_exist
)
315 return PM_ERR_WRONG_ARGS
;
318 if(stat(path
, &st
) == -1 || !S_ISDIR(st
.st_mode
)) {
319 return PM_ERR_NOT_A_DIR
;
321 CALLOC(real
, PATH_MAX
, sizeof(char), return PM_ERR_MEMORY
);
322 if(!realpath(path
, real
)) {
324 return PM_ERR_NOT_A_DIR
;
332 *storage
= canonicalize_path(path
);
334 return PM_ERR_MEMORY
;
340 int SYMEXPORT
alpm_option_add_cachedir(alpm_handle_t
*handle
, const char *cachedir
)
344 CHECK_HANDLE(handle
, return -1);
345 ASSERT(cachedir
!= NULL
, RET_ERR(handle
, PM_ERR_WRONG_ARGS
, -1));
346 /* don't stat the cachedir yet, as it may not even be needed. we can
347 * fail later if it is needed and the path is invalid. */
349 newcachedir
= canonicalize_path(cachedir
);
351 RET_ERR(handle
, PM_ERR_MEMORY
, -1);
353 handle
->cachedirs
= alpm_list_add(handle
->cachedirs
, newcachedir
);
354 _alpm_log(handle
, PM_LOG_DEBUG
, "option 'cachedir' = %s\n", newcachedir
);
358 int SYMEXPORT
alpm_option_set_cachedirs(alpm_handle_t
*handle
, alpm_list_t
*cachedirs
)
361 CHECK_HANDLE(handle
, return -1);
362 if(handle
->cachedirs
) {
363 FREELIST(handle
->cachedirs
);
365 for(i
= cachedirs
; i
; i
= i
->next
) {
366 int ret
= alpm_option_add_cachedir(handle
, i
->data
);
374 int SYMEXPORT
alpm_option_remove_cachedir(alpm_handle_t
*handle
, const char *cachedir
)
378 CHECK_HANDLE(handle
, return -1);
379 ASSERT(cachedir
!= NULL
, RET_ERR(handle
, PM_ERR_WRONG_ARGS
, -1));
381 newcachedir
= canonicalize_path(cachedir
);
383 RET_ERR(handle
, PM_ERR_MEMORY
, -1);
385 handle
->cachedirs
= alpm_list_remove_str(handle
->cachedirs
, newcachedir
, &vdata
);
394 int SYMEXPORT
alpm_option_set_logfile(alpm_handle_t
*handle
, const char *logfile
)
396 char *oldlogfile
= handle
->logfile
;
398 CHECK_HANDLE(handle
, return -1);
400 handle
->pm_errno
= PM_ERR_WRONG_ARGS
;
404 handle
->logfile
= strdup(logfile
);
406 /* free the old logfile path string, and close the stream so logaction
407 * will reopen a new stream on the new logfile */
411 if(handle
->logstream
) {
412 fclose(handle
->logstream
);
413 handle
->logstream
= NULL
;
415 _alpm_log(handle
, PM_LOG_DEBUG
, "option 'logfile' = %s\n", handle
->logfile
);
419 int SYMEXPORT
alpm_option_set_gpgdir(alpm_handle_t
*handle
, const char *gpgdir
)
421 CHECK_HANDLE(handle
, return -1);
423 handle
->pm_errno
= PM_ERR_WRONG_ARGS
;
428 FREE(handle
->gpgdir
);
430 handle
->gpgdir
= strdup(gpgdir
);
432 _alpm_log(handle
, PM_LOG_DEBUG
, "option 'gpgdir' = %s\n", handle
->gpgdir
);
436 int SYMEXPORT
alpm_option_set_usesyslog(alpm_handle_t
*handle
, int usesyslog
)
438 CHECK_HANDLE(handle
, return -1);
439 handle
->usesyslog
= usesyslog
;
443 int SYMEXPORT
alpm_option_add_noupgrade(alpm_handle_t
*handle
, const char *pkg
)
445 CHECK_HANDLE(handle
, return -1);
446 handle
->noupgrade
= alpm_list_add(handle
->noupgrade
, strdup(pkg
));
450 int SYMEXPORT
alpm_option_set_noupgrades(alpm_handle_t
*handle
, alpm_list_t
*noupgrade
)
452 CHECK_HANDLE(handle
, return -1);
453 if(handle
->noupgrade
) FREELIST(handle
->noupgrade
);
454 handle
->noupgrade
= alpm_list_strdup(noupgrade
);
458 int SYMEXPORT
alpm_option_remove_noupgrade(alpm_handle_t
*handle
, const char *pkg
)
461 CHECK_HANDLE(handle
, return -1);
462 handle
->noupgrade
= alpm_list_remove_str(handle
->noupgrade
, pkg
, &vdata
);
470 int SYMEXPORT
alpm_option_add_noextract(alpm_handle_t
*handle
, const char *pkg
)
472 CHECK_HANDLE(handle
, return -1);
473 handle
->noextract
= alpm_list_add(handle
->noextract
, strdup(pkg
));
477 int SYMEXPORT
alpm_option_set_noextracts(alpm_handle_t
*handle
, alpm_list_t
*noextract
)
479 CHECK_HANDLE(handle
, return -1);
480 if(handle
->noextract
) FREELIST(handle
->noextract
);
481 handle
->noextract
= alpm_list_strdup(noextract
);
485 int SYMEXPORT
alpm_option_remove_noextract(alpm_handle_t
*handle
, const char *pkg
)
488 CHECK_HANDLE(handle
, return -1);
489 handle
->noextract
= alpm_list_remove_str(handle
->noextract
, pkg
, &vdata
);
497 int SYMEXPORT
alpm_option_add_ignorepkg(alpm_handle_t
*handle
, const char *pkg
)
499 CHECK_HANDLE(handle
, return -1);
500 handle
->ignorepkg
= alpm_list_add(handle
->ignorepkg
, strdup(pkg
));
504 int SYMEXPORT
alpm_option_set_ignorepkgs(alpm_handle_t
*handle
, alpm_list_t
*ignorepkgs
)
506 CHECK_HANDLE(handle
, return -1);
507 if(handle
->ignorepkg
) FREELIST(handle
->ignorepkg
);
508 handle
->ignorepkg
= alpm_list_strdup(ignorepkgs
);
512 int SYMEXPORT
alpm_option_remove_ignorepkg(alpm_handle_t
*handle
, const char *pkg
)
515 CHECK_HANDLE(handle
, return -1);
516 handle
->ignorepkg
= alpm_list_remove_str(handle
->ignorepkg
, pkg
, &vdata
);
524 int SYMEXPORT
alpm_option_add_ignoregroup(alpm_handle_t
*handle
, const char *grp
)
526 CHECK_HANDLE(handle
, return -1);
527 handle
->ignoregrp
= alpm_list_add(handle
->ignoregrp
, strdup(grp
));
531 int SYMEXPORT
alpm_option_set_ignoregroups(alpm_handle_t
*handle
, alpm_list_t
*ignoregrps
)
533 CHECK_HANDLE(handle
, return -1);
534 if(handle
->ignoregrp
) FREELIST(handle
->ignoregrp
);
535 handle
->ignoregrp
= alpm_list_strdup(ignoregrps
);
539 int SYMEXPORT
alpm_option_remove_ignoregroup(alpm_handle_t
*handle
, const char *grp
)
542 CHECK_HANDLE(handle
, return -1);
543 handle
->ignoregrp
= alpm_list_remove_str(handle
->ignoregrp
, grp
, &vdata
);
551 int SYMEXPORT
alpm_option_set_arch(alpm_handle_t
*handle
, const char *arch
)
553 CHECK_HANDLE(handle
, return -1);
554 if(handle
->arch
) FREE(handle
->arch
);
556 handle
->arch
= strdup(arch
);
563 int SYMEXPORT
alpm_option_set_usedelta(alpm_handle_t
*handle
, int usedelta
)
565 CHECK_HANDLE(handle
, return -1);
566 handle
->usedelta
= usedelta
;
570 int SYMEXPORT
alpm_option_set_checkspace(alpm_handle_t
*handle
, int checkspace
)
572 CHECK_HANDLE(handle
, return -1);
573 handle
->checkspace
= checkspace
;
577 int SYMEXPORT
alpm_option_set_default_sigverify(alpm_handle_t
*handle
, pgp_verify_t level
)
579 CHECK_HANDLE(handle
, return -1);
580 ASSERT(level
!= PM_PGP_VERIFY_UNKNOWN
, RET_ERR(handle
, PM_ERR_WRONG_ARGS
, -1));
581 handle
->sigverify
= level
;
585 pgp_verify_t SYMEXPORT
alpm_option_get_default_sigverify(alpm_handle_t
*handle
)
587 CHECK_HANDLE(handle
, return PM_PGP_VERIFY_UNKNOWN
);
588 return handle
->sigverify
;
591 /* vim: set ts=2 sw=2 noet: */