4 * Copyright (c) 2006-2012 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/>.
27 #include <sys/types.h>
34 #include "alpm_list.h"
41 alpm_handle_t
*_alpm_handle_new(void)
43 alpm_handle_t
*handle
;
45 CALLOC(handle
, 1, sizeof(alpm_handle_t
), return NULL
);
46 handle
->deltaratio
= 0.0;
51 void _alpm_handle_free(alpm_handle_t
*handle
)
58 if(handle
->logstream
) {
59 fclose(handle
->logstream
);
60 handle
->logstream
= NULL
;
62 if(handle
->usesyslog
) {
63 handle
->usesyslog
= 0;
68 /* release curl handle */
69 curl_easy_cleanup(handle
->curl
);
72 regfree(&handle
->delta_regex
);
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
->ignoregroup
);
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 fclose(handle
->lckstream
);
133 handle
->lckstream
= NULL
;
135 if(unlink(handle
->lockfile
) && errno
!= ENOENT
) {
142 alpm_cb_log SYMEXPORT
alpm_option_get_logcb(alpm_handle_t
*handle
)
144 CHECK_HANDLE(handle
, return NULL
);
145 return handle
->logcb
;
148 alpm_cb_download SYMEXPORT
alpm_option_get_dlcb(alpm_handle_t
*handle
)
150 CHECK_HANDLE(handle
, return NULL
);
154 alpm_cb_fetch SYMEXPORT
alpm_option_get_fetchcb(alpm_handle_t
*handle
)
156 CHECK_HANDLE(handle
, return NULL
);
157 return handle
->fetchcb
;
160 alpm_cb_totaldl SYMEXPORT
alpm_option_get_totaldlcb(alpm_handle_t
*handle
)
162 CHECK_HANDLE(handle
, return NULL
);
163 return handle
->totaldlcb
;
166 alpm_cb_event SYMEXPORT
alpm_option_get_eventcb(alpm_handle_t
*handle
)
168 CHECK_HANDLE(handle
, return NULL
);
169 return handle
->eventcb
;
172 alpm_cb_question SYMEXPORT
alpm_option_get_questioncb(alpm_handle_t
*handle
)
174 CHECK_HANDLE(handle
, return NULL
);
175 return handle
->questioncb
;
178 alpm_cb_progress SYMEXPORT
alpm_option_get_progresscb(alpm_handle_t
*handle
)
180 CHECK_HANDLE(handle
, return NULL
);
181 return handle
->progresscb
;
184 const char SYMEXPORT
*alpm_option_get_root(alpm_handle_t
*handle
)
186 CHECK_HANDLE(handle
, return NULL
);
190 const char SYMEXPORT
*alpm_option_get_dbpath(alpm_handle_t
*handle
)
192 CHECK_HANDLE(handle
, return NULL
);
193 return handle
->dbpath
;
196 alpm_list_t SYMEXPORT
*alpm_option_get_cachedirs(alpm_handle_t
*handle
)
198 CHECK_HANDLE(handle
, return NULL
);
199 return handle
->cachedirs
;
202 const char SYMEXPORT
*alpm_option_get_logfile(alpm_handle_t
*handle
)
204 CHECK_HANDLE(handle
, return NULL
);
205 return handle
->logfile
;
208 const char SYMEXPORT
*alpm_option_get_lockfile(alpm_handle_t
*handle
)
210 CHECK_HANDLE(handle
, return NULL
);
211 return handle
->lockfile
;
214 const char SYMEXPORT
*alpm_option_get_gpgdir(alpm_handle_t
*handle
)
216 CHECK_HANDLE(handle
, return NULL
);
217 return handle
->gpgdir
;
220 int SYMEXPORT
alpm_option_get_usesyslog(alpm_handle_t
*handle
)
222 CHECK_HANDLE(handle
, return -1);
223 return handle
->usesyslog
;
226 alpm_list_t SYMEXPORT
*alpm_option_get_noupgrades(alpm_handle_t
*handle
)
228 CHECK_HANDLE(handle
, return NULL
);
229 return handle
->noupgrade
;
232 alpm_list_t SYMEXPORT
*alpm_option_get_noextracts(alpm_handle_t
*handle
)
234 CHECK_HANDLE(handle
, return NULL
);
235 return handle
->noextract
;
238 alpm_list_t SYMEXPORT
*alpm_option_get_ignorepkgs(alpm_handle_t
*handle
)
240 CHECK_HANDLE(handle
, return NULL
);
241 return handle
->ignorepkg
;
244 alpm_list_t SYMEXPORT
*alpm_option_get_ignoregroups(alpm_handle_t
*handle
)
246 CHECK_HANDLE(handle
, return NULL
);
247 return handle
->ignoregroup
;
250 const char SYMEXPORT
*alpm_option_get_arch(alpm_handle_t
*handle
)
252 CHECK_HANDLE(handle
, return NULL
);
256 double SYMEXPORT
alpm_option_get_deltaratio(alpm_handle_t
*handle
)
258 CHECK_HANDLE(handle
, return -1);
259 return handle
->deltaratio
;
262 int SYMEXPORT
alpm_option_get_checkspace(alpm_handle_t
*handle
)
264 CHECK_HANDLE(handle
, return -1);
265 return handle
->checkspace
;
268 int SYMEXPORT
alpm_option_set_logcb(alpm_handle_t
*handle
, alpm_cb_log cb
)
270 CHECK_HANDLE(handle
, return -1);
275 int SYMEXPORT
alpm_option_set_dlcb(alpm_handle_t
*handle
, alpm_cb_download cb
)
277 CHECK_HANDLE(handle
, return -1);
282 int SYMEXPORT
alpm_option_set_fetchcb(alpm_handle_t
*handle
, alpm_cb_fetch cb
)
284 CHECK_HANDLE(handle
, return -1);
285 handle
->fetchcb
= cb
;
289 int SYMEXPORT
alpm_option_set_totaldlcb(alpm_handle_t
*handle
, alpm_cb_totaldl cb
)
291 CHECK_HANDLE(handle
, return -1);
292 handle
->totaldlcb
= cb
;
296 int SYMEXPORT
alpm_option_set_eventcb(alpm_handle_t
*handle
, alpm_cb_event cb
)
298 CHECK_HANDLE(handle
, return -1);
299 handle
->eventcb
= cb
;
303 int SYMEXPORT
alpm_option_set_questioncb(alpm_handle_t
*handle
, alpm_cb_question cb
)
305 CHECK_HANDLE(handle
, return -1);
306 handle
->questioncb
= cb
;
310 int SYMEXPORT
alpm_option_set_progresscb(alpm_handle_t
*handle
, alpm_cb_progress cb
)
312 CHECK_HANDLE(handle
, return -1);
313 handle
->progresscb
= cb
;
317 static char *canonicalize_path(const char *path
) {
321 /* verify path ends in a '/' */
323 if(path
[len
- 1] != '/') {
326 CALLOC(new_path
, len
+ 1, sizeof(char), return NULL
);
327 strcpy(new_path
, path
);
328 new_path
[len
- 1] = '/';
332 alpm_errno_t
_alpm_set_directory_option(const char *value
,
333 char **storage
, int must_exist
)
341 return ALPM_ERR_WRONG_ARGS
;
344 if(stat(path
, &st
) == -1 || !S_ISDIR(st
.st_mode
)) {
345 return ALPM_ERR_NOT_A_DIR
;
347 CALLOC(real
, PATH_MAX
, sizeof(char), return ALPM_ERR_MEMORY
);
348 if(!realpath(path
, real
)) {
350 return ALPM_ERR_NOT_A_DIR
;
358 *storage
= canonicalize_path(path
);
360 return ALPM_ERR_MEMORY
;
366 int SYMEXPORT
alpm_option_add_cachedir(alpm_handle_t
*handle
, const char *cachedir
)
370 CHECK_HANDLE(handle
, return -1);
371 ASSERT(cachedir
!= NULL
, RET_ERR(handle
, ALPM_ERR_WRONG_ARGS
, -1));
372 /* don't stat the cachedir yet, as it may not even be needed. we can
373 * fail later if it is needed and the path is invalid. */
375 newcachedir
= canonicalize_path(cachedir
);
377 RET_ERR(handle
, ALPM_ERR_MEMORY
, -1);
379 handle
->cachedirs
= alpm_list_add(handle
->cachedirs
, newcachedir
);
380 _alpm_log(handle
, ALPM_LOG_DEBUG
, "option 'cachedir' = %s\n", newcachedir
);
384 int SYMEXPORT
alpm_option_set_cachedirs(alpm_handle_t
*handle
, alpm_list_t
*cachedirs
)
387 CHECK_HANDLE(handle
, return -1);
388 if(handle
->cachedirs
) {
389 FREELIST(handle
->cachedirs
);
391 for(i
= cachedirs
; i
; i
= i
->next
) {
392 int ret
= alpm_option_add_cachedir(handle
, i
->data
);
400 int SYMEXPORT
alpm_option_remove_cachedir(alpm_handle_t
*handle
, const char *cachedir
)
404 CHECK_HANDLE(handle
, return -1);
405 ASSERT(cachedir
!= NULL
, RET_ERR(handle
, ALPM_ERR_WRONG_ARGS
, -1));
407 newcachedir
= canonicalize_path(cachedir
);
409 RET_ERR(handle
, ALPM_ERR_MEMORY
, -1);
411 handle
->cachedirs
= alpm_list_remove_str(handle
->cachedirs
, newcachedir
, &vdata
);
420 int SYMEXPORT
alpm_option_set_logfile(alpm_handle_t
*handle
, const char *logfile
)
422 char *oldlogfile
= handle
->logfile
;
424 CHECK_HANDLE(handle
, return -1);
426 handle
->pm_errno
= ALPM_ERR_WRONG_ARGS
;
430 handle
->logfile
= strdup(logfile
);
432 /* free the old logfile path string, and close the stream so logaction
433 * will reopen a new stream on the new logfile */
437 if(handle
->logstream
) {
438 fclose(handle
->logstream
);
439 handle
->logstream
= NULL
;
441 _alpm_log(handle
, ALPM_LOG_DEBUG
, "option 'logfile' = %s\n", handle
->logfile
);
445 int SYMEXPORT
alpm_option_set_gpgdir(alpm_handle_t
*handle
, const char *gpgdir
)
447 CHECK_HANDLE(handle
, return -1);
449 handle
->pm_errno
= ALPM_ERR_WRONG_ARGS
;
454 FREE(handle
->gpgdir
);
456 handle
->gpgdir
= strdup(gpgdir
);
458 _alpm_log(handle
, ALPM_LOG_DEBUG
, "option 'gpgdir' = %s\n", handle
->gpgdir
);
462 int SYMEXPORT
alpm_option_set_usesyslog(alpm_handle_t
*handle
, int usesyslog
)
464 CHECK_HANDLE(handle
, return -1);
465 handle
->usesyslog
= usesyslog
;
469 int SYMEXPORT
alpm_option_add_noupgrade(alpm_handle_t
*handle
, const char *pkg
)
471 CHECK_HANDLE(handle
, return -1);
472 handle
->noupgrade
= alpm_list_add(handle
->noupgrade
, strdup(pkg
));
476 int SYMEXPORT
alpm_option_set_noupgrades(alpm_handle_t
*handle
, alpm_list_t
*noupgrade
)
478 CHECK_HANDLE(handle
, return -1);
479 if(handle
->noupgrade
) FREELIST(handle
->noupgrade
);
480 handle
->noupgrade
= alpm_list_strdup(noupgrade
);
484 int SYMEXPORT
alpm_option_remove_noupgrade(alpm_handle_t
*handle
, const char *pkg
)
487 CHECK_HANDLE(handle
, return -1);
488 handle
->noupgrade
= alpm_list_remove_str(handle
->noupgrade
, pkg
, &vdata
);
496 int SYMEXPORT
alpm_option_add_noextract(alpm_handle_t
*handle
, const char *pkg
)
498 CHECK_HANDLE(handle
, return -1);
499 handle
->noextract
= alpm_list_add(handle
->noextract
, strdup(pkg
));
503 int SYMEXPORT
alpm_option_set_noextracts(alpm_handle_t
*handle
, alpm_list_t
*noextract
)
505 CHECK_HANDLE(handle
, return -1);
506 if(handle
->noextract
) FREELIST(handle
->noextract
);
507 handle
->noextract
= alpm_list_strdup(noextract
);
511 int SYMEXPORT
alpm_option_remove_noextract(alpm_handle_t
*handle
, const char *pkg
)
514 CHECK_HANDLE(handle
, return -1);
515 handle
->noextract
= alpm_list_remove_str(handle
->noextract
, pkg
, &vdata
);
523 int SYMEXPORT
alpm_option_add_ignorepkg(alpm_handle_t
*handle
, const char *pkg
)
525 CHECK_HANDLE(handle
, return -1);
526 handle
->ignorepkg
= alpm_list_add(handle
->ignorepkg
, strdup(pkg
));
530 int SYMEXPORT
alpm_option_set_ignorepkgs(alpm_handle_t
*handle
, alpm_list_t
*ignorepkgs
)
532 CHECK_HANDLE(handle
, return -1);
533 if(handle
->ignorepkg
) FREELIST(handle
->ignorepkg
);
534 handle
->ignorepkg
= alpm_list_strdup(ignorepkgs
);
538 int SYMEXPORT
alpm_option_remove_ignorepkg(alpm_handle_t
*handle
, const char *pkg
)
541 CHECK_HANDLE(handle
, return -1);
542 handle
->ignorepkg
= alpm_list_remove_str(handle
->ignorepkg
, pkg
, &vdata
);
550 int SYMEXPORT
alpm_option_add_ignoregroup(alpm_handle_t
*handle
, const char *grp
)
552 CHECK_HANDLE(handle
, return -1);
553 handle
->ignoregroup
= alpm_list_add(handle
->ignoregroup
, strdup(grp
));
557 int SYMEXPORT
alpm_option_set_ignoregroups(alpm_handle_t
*handle
, alpm_list_t
*ignoregrps
)
559 CHECK_HANDLE(handle
, return -1);
560 if(handle
->ignoregroup
) FREELIST(handle
->ignoregroup
);
561 handle
->ignoregroup
= alpm_list_strdup(ignoregrps
);
565 int SYMEXPORT
alpm_option_remove_ignoregroup(alpm_handle_t
*handle
, const char *grp
)
568 CHECK_HANDLE(handle
, return -1);
569 handle
->ignoregroup
= alpm_list_remove_str(handle
->ignoregroup
, grp
, &vdata
);
577 int SYMEXPORT
alpm_option_set_arch(alpm_handle_t
*handle
, const char *arch
)
579 CHECK_HANDLE(handle
, return -1);
580 if(handle
->arch
) FREE(handle
->arch
);
582 handle
->arch
= strdup(arch
);
589 int SYMEXPORT
alpm_option_set_deltaratio(alpm_handle_t
*handle
, double ratio
)
591 CHECK_HANDLE(handle
, return -1);
592 if(ratio
< 0.0 || ratio
> 2.0) {
593 RET_ERR(handle
, ALPM_ERR_WRONG_ARGS
, -1);
595 handle
->deltaratio
= ratio
;
599 int SYMEXPORT
alpm_option_set_checkspace(alpm_handle_t
*handle
, int checkspace
)
601 CHECK_HANDLE(handle
, return -1);
602 handle
->checkspace
= checkspace
;
606 int SYMEXPORT
alpm_option_set_default_siglevel(alpm_handle_t
*handle
,
607 alpm_siglevel_t level
)
609 CHECK_HANDLE(handle
, return -1);
611 handle
->siglevel
= level
;
613 if(level
!= 0 && level
!= ALPM_SIG_USE_DEFAULT
) {
614 RET_ERR(handle
, ALPM_ERR_WRONG_ARGS
, -1);
620 alpm_siglevel_t SYMEXPORT
alpm_option_get_default_siglevel(alpm_handle_t
*handle
)
622 CHECK_HANDLE(handle
, return -1);
623 return handle
->siglevel
;
626 alpm_db_t SYMEXPORT
*alpm_get_localdb(alpm_handle_t
*handle
)
628 CHECK_HANDLE(handle
, return NULL
);
629 return handle
->db_local
;
632 alpm_list_t SYMEXPORT
*alpm_get_syncdbs(alpm_handle_t
*handle
)
634 CHECK_HANDLE(handle
, return NULL
);
635 return handle
->dbs_sync
;
638 /* vim: set ts=2 sw=2 noet: */