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 if(!realpath(path
, real
)) {
348 return ALPM_ERR_NOT_A_DIR
;
356 *storage
= canonicalize_path(path
);
358 return ALPM_ERR_MEMORY
;
363 int SYMEXPORT
alpm_option_add_cachedir(alpm_handle_t
*handle
, const char *cachedir
)
367 CHECK_HANDLE(handle
, return -1);
368 ASSERT(cachedir
!= NULL
, RET_ERR(handle
, ALPM_ERR_WRONG_ARGS
, -1));
369 /* don't stat the cachedir yet, as it may not even be needed. we can
370 * fail later if it is needed and the path is invalid. */
372 newcachedir
= canonicalize_path(cachedir
);
374 RET_ERR(handle
, ALPM_ERR_MEMORY
, -1);
376 handle
->cachedirs
= alpm_list_add(handle
->cachedirs
, newcachedir
);
377 _alpm_log(handle
, ALPM_LOG_DEBUG
, "option 'cachedir' = %s\n", newcachedir
);
381 int SYMEXPORT
alpm_option_set_cachedirs(alpm_handle_t
*handle
, alpm_list_t
*cachedirs
)
384 CHECK_HANDLE(handle
, return -1);
385 if(handle
->cachedirs
) {
386 FREELIST(handle
->cachedirs
);
388 for(i
= cachedirs
; i
; i
= i
->next
) {
389 int ret
= alpm_option_add_cachedir(handle
, i
->data
);
397 int SYMEXPORT
alpm_option_remove_cachedir(alpm_handle_t
*handle
, const char *cachedir
)
401 CHECK_HANDLE(handle
, return -1);
402 ASSERT(cachedir
!= NULL
, RET_ERR(handle
, ALPM_ERR_WRONG_ARGS
, -1));
404 newcachedir
= canonicalize_path(cachedir
);
406 RET_ERR(handle
, ALPM_ERR_MEMORY
, -1);
408 handle
->cachedirs
= alpm_list_remove_str(handle
->cachedirs
, newcachedir
, &vdata
);
417 int SYMEXPORT
alpm_option_set_logfile(alpm_handle_t
*handle
, const char *logfile
)
419 char *oldlogfile
= handle
->logfile
;
421 CHECK_HANDLE(handle
, return -1);
423 handle
->pm_errno
= ALPM_ERR_WRONG_ARGS
;
427 handle
->logfile
= strdup(logfile
);
429 /* free the old logfile path string, and close the stream so logaction
430 * will reopen a new stream on the new logfile */
434 if(handle
->logstream
) {
435 fclose(handle
->logstream
);
436 handle
->logstream
= NULL
;
438 _alpm_log(handle
, ALPM_LOG_DEBUG
, "option 'logfile' = %s\n", handle
->logfile
);
442 int SYMEXPORT
alpm_option_set_gpgdir(alpm_handle_t
*handle
, const char *gpgdir
)
444 CHECK_HANDLE(handle
, return -1);
446 handle
->pm_errno
= ALPM_ERR_WRONG_ARGS
;
451 FREE(handle
->gpgdir
);
453 handle
->gpgdir
= strdup(gpgdir
);
455 _alpm_log(handle
, ALPM_LOG_DEBUG
, "option 'gpgdir' = %s\n", handle
->gpgdir
);
459 int SYMEXPORT
alpm_option_set_usesyslog(alpm_handle_t
*handle
, int usesyslog
)
461 CHECK_HANDLE(handle
, return -1);
462 handle
->usesyslog
= usesyslog
;
466 int SYMEXPORT
alpm_option_add_noupgrade(alpm_handle_t
*handle
, const char *pkg
)
468 CHECK_HANDLE(handle
, return -1);
469 handle
->noupgrade
= alpm_list_add(handle
->noupgrade
, strdup(pkg
));
473 int SYMEXPORT
alpm_option_set_noupgrades(alpm_handle_t
*handle
, alpm_list_t
*noupgrade
)
475 CHECK_HANDLE(handle
, return -1);
476 if(handle
->noupgrade
) FREELIST(handle
->noupgrade
);
477 handle
->noupgrade
= alpm_list_strdup(noupgrade
);
481 int SYMEXPORT
alpm_option_remove_noupgrade(alpm_handle_t
*handle
, const char *pkg
)
484 CHECK_HANDLE(handle
, return -1);
485 handle
->noupgrade
= alpm_list_remove_str(handle
->noupgrade
, pkg
, &vdata
);
493 int SYMEXPORT
alpm_option_add_noextract(alpm_handle_t
*handle
, const char *pkg
)
495 CHECK_HANDLE(handle
, return -1);
496 handle
->noextract
= alpm_list_add(handle
->noextract
, strdup(pkg
));
500 int SYMEXPORT
alpm_option_set_noextracts(alpm_handle_t
*handle
, alpm_list_t
*noextract
)
502 CHECK_HANDLE(handle
, return -1);
503 if(handle
->noextract
) FREELIST(handle
->noextract
);
504 handle
->noextract
= alpm_list_strdup(noextract
);
508 int SYMEXPORT
alpm_option_remove_noextract(alpm_handle_t
*handle
, const char *pkg
)
511 CHECK_HANDLE(handle
, return -1);
512 handle
->noextract
= alpm_list_remove_str(handle
->noextract
, pkg
, &vdata
);
520 int SYMEXPORT
alpm_option_add_ignorepkg(alpm_handle_t
*handle
, const char *pkg
)
522 CHECK_HANDLE(handle
, return -1);
523 handle
->ignorepkg
= alpm_list_add(handle
->ignorepkg
, strdup(pkg
));
527 int SYMEXPORT
alpm_option_set_ignorepkgs(alpm_handle_t
*handle
, alpm_list_t
*ignorepkgs
)
529 CHECK_HANDLE(handle
, return -1);
530 if(handle
->ignorepkg
) FREELIST(handle
->ignorepkg
);
531 handle
->ignorepkg
= alpm_list_strdup(ignorepkgs
);
535 int SYMEXPORT
alpm_option_remove_ignorepkg(alpm_handle_t
*handle
, const char *pkg
)
538 CHECK_HANDLE(handle
, return -1);
539 handle
->ignorepkg
= alpm_list_remove_str(handle
->ignorepkg
, pkg
, &vdata
);
547 int SYMEXPORT
alpm_option_add_ignoregroup(alpm_handle_t
*handle
, const char *grp
)
549 CHECK_HANDLE(handle
, return -1);
550 handle
->ignoregroup
= alpm_list_add(handle
->ignoregroup
, strdup(grp
));
554 int SYMEXPORT
alpm_option_set_ignoregroups(alpm_handle_t
*handle
, alpm_list_t
*ignoregrps
)
556 CHECK_HANDLE(handle
, return -1);
557 if(handle
->ignoregroup
) FREELIST(handle
->ignoregroup
);
558 handle
->ignoregroup
= alpm_list_strdup(ignoregrps
);
562 int SYMEXPORT
alpm_option_remove_ignoregroup(alpm_handle_t
*handle
, const char *grp
)
565 CHECK_HANDLE(handle
, return -1);
566 handle
->ignoregroup
= alpm_list_remove_str(handle
->ignoregroup
, grp
, &vdata
);
574 int SYMEXPORT
alpm_option_set_arch(alpm_handle_t
*handle
, const char *arch
)
576 CHECK_HANDLE(handle
, return -1);
577 if(handle
->arch
) FREE(handle
->arch
);
579 handle
->arch
= strdup(arch
);
586 int SYMEXPORT
alpm_option_set_deltaratio(alpm_handle_t
*handle
, double ratio
)
588 CHECK_HANDLE(handle
, return -1);
589 if(ratio
< 0.0 || ratio
> 2.0) {
590 RET_ERR(handle
, ALPM_ERR_WRONG_ARGS
, -1);
592 handle
->deltaratio
= ratio
;
596 int SYMEXPORT
alpm_option_set_checkspace(alpm_handle_t
*handle
, int checkspace
)
598 CHECK_HANDLE(handle
, return -1);
599 handle
->checkspace
= checkspace
;
603 int SYMEXPORT
alpm_option_set_default_siglevel(alpm_handle_t
*handle
,
604 alpm_siglevel_t level
)
606 CHECK_HANDLE(handle
, return -1);
608 handle
->siglevel
= level
;
610 if(level
!= 0 && level
!= ALPM_SIG_USE_DEFAULT
) {
611 RET_ERR(handle
, ALPM_ERR_WRONG_ARGS
, -1);
617 alpm_siglevel_t SYMEXPORT
alpm_option_get_default_siglevel(alpm_handle_t
*handle
)
619 CHECK_HANDLE(handle
, return -1);
620 return handle
->siglevel
;
623 alpm_db_t SYMEXPORT
*alpm_get_localdb(alpm_handle_t
*handle
)
625 CHECK_HANDLE(handle
, return NULL
);
626 return handle
->db_local
;
629 alpm_list_t SYMEXPORT
*alpm_get_syncdbs(alpm_handle_t
*handle
)
631 CHECK_HANDLE(handle
, return NULL
);
632 return handle
->dbs_sync
;
635 /* vim: set ts=2 sw=2 noet: */