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
->siglevel
= ALPM_SIG_PACKAGE
| ALPM_SIG_PACKAGE_OPTIONAL
|
49 ALPM_SIG_DATABASE
| ALPM_SIG_DATABASE_OPTIONAL
;
54 void _alpm_handle_free(alpm_handle_t
*handle
)
61 if(handle
->logstream
) {
62 fclose(handle
->logstream
);
63 handle
->logstream
= NULL
;
65 if(handle
->usesyslog
) {
66 handle
->usesyslog
= 0;
71 /* release curl handle */
72 curl_easy_cleanup(handle
->curl
);
76 _alpm_trans_free(handle
->trans
);
79 FREELIST(handle
->cachedirs
);
80 FREE(handle
->logfile
);
81 FREE(handle
->lockfile
);
84 FREELIST(handle
->dbs_sync
);
85 FREELIST(handle
->noupgrade
);
86 FREELIST(handle
->noextract
);
87 FREELIST(handle
->ignorepkg
);
88 FREELIST(handle
->ignoregroup
);
92 /** Lock the database */
93 int _alpm_handle_lock(alpm_handle_t
*handle
)
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
, '/');
107 if(_alpm_makepath(dir
)) {
114 fd
= open(handle
->lockfile
, O_WRONLY
| O_CREAT
| O_EXCL
, 0000);
115 } while(fd
== -1 && errno
== EINTR
);
117 FILE *f
= fdopen(fd
, "w");
118 fprintf(f
, "%ld\n", (long)getpid());
121 handle
->lckstream
= f
;
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
) {
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
);
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
);
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
);
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);
271 int SYMEXPORT
alpm_option_set_dlcb(alpm_handle_t
*handle
, alpm_cb_download cb
)
273 CHECK_HANDLE(handle
, return -1);
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
;
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
;
292 static char *canonicalize_path(const char *path
) {
296 /* verify path ends in a '/' */
298 if(path
[len
- 1] != '/') {
301 CALLOC(new_path
, len
+ 1, sizeof(char), return NULL
);
302 strcpy(new_path
, path
);
303 new_path
[len
- 1] = '/';
307 enum _alpm_errno_t
_alpm_set_directory_option(const char *value
,
308 char **storage
, int must_exist
)
316 return ALPM_ERR_WRONG_ARGS
;
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
)) {
325 return ALPM_ERR_NOT_A_DIR
;
333 *storage
= canonicalize_path(path
);
335 return ALPM_ERR_MEMORY
;
341 int SYMEXPORT
alpm_option_add_cachedir(alpm_handle_t
*handle
, const char *cachedir
)
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
);
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
);
359 int SYMEXPORT
alpm_option_set_cachedirs(alpm_handle_t
*handle
, alpm_list_t
*cachedirs
)
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
);
375 int SYMEXPORT
alpm_option_remove_cachedir(alpm_handle_t
*handle
, const char *cachedir
)
379 CHECK_HANDLE(handle
, return -1);
380 ASSERT(cachedir
!= NULL
, RET_ERR(handle
, ALPM_ERR_WRONG_ARGS
, -1));
382 newcachedir
= canonicalize_path(cachedir
);
384 RET_ERR(handle
, ALPM_ERR_MEMORY
, -1);
386 handle
->cachedirs
= alpm_list_remove_str(handle
->cachedirs
, newcachedir
, &vdata
);
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);
401 handle
->pm_errno
= ALPM_ERR_WRONG_ARGS
;
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 */
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
);
420 int SYMEXPORT
alpm_option_set_gpgdir(alpm_handle_t
*handle
, const char *gpgdir
)
422 CHECK_HANDLE(handle
, return -1);
424 handle
->pm_errno
= ALPM_ERR_WRONG_ARGS
;
429 FREE(handle
->gpgdir
);
431 handle
->gpgdir
= strdup(gpgdir
);
433 _alpm_log(handle
, ALPM_LOG_DEBUG
, "option 'gpgdir' = %s\n", handle
->gpgdir
);
437 int SYMEXPORT
alpm_option_set_usesyslog(alpm_handle_t
*handle
, int usesyslog
)
439 CHECK_HANDLE(handle
, return -1);
440 handle
->usesyslog
= usesyslog
;
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
));
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
);
459 int SYMEXPORT
alpm_option_remove_noupgrade(alpm_handle_t
*handle
, const char *pkg
)
462 CHECK_HANDLE(handle
, return -1);
463 handle
->noupgrade
= alpm_list_remove_str(handle
->noupgrade
, pkg
, &vdata
);
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
));
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
);
486 int SYMEXPORT
alpm_option_remove_noextract(alpm_handle_t
*handle
, const char *pkg
)
489 CHECK_HANDLE(handle
, return -1);
490 handle
->noextract
= alpm_list_remove_str(handle
->noextract
, pkg
, &vdata
);
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
));
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
);
513 int SYMEXPORT
alpm_option_remove_ignorepkg(alpm_handle_t
*handle
, const char *pkg
)
516 CHECK_HANDLE(handle
, return -1);
517 handle
->ignorepkg
= alpm_list_remove_str(handle
->ignorepkg
, pkg
, &vdata
);
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
));
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
);
540 int SYMEXPORT
alpm_option_remove_ignoregroup(alpm_handle_t
*handle
, const char *grp
)
543 CHECK_HANDLE(handle
, return -1);
544 handle
->ignoregroup
= alpm_list_remove_str(handle
->ignoregroup
, grp
, &vdata
);
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
);
557 handle
->arch
= strdup(arch
);
564 int SYMEXPORT
alpm_option_set_usedelta(alpm_handle_t
*handle
, int usedelta
)
566 CHECK_HANDLE(handle
, return -1);
567 handle
->usedelta
= usedelta
;
571 int SYMEXPORT
alpm_option_set_checkspace(alpm_handle_t
*handle
, int checkspace
)
573 CHECK_HANDLE(handle
, return -1);
574 handle
->checkspace
= checkspace
;
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
;
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: */