4 * Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
5 * Copyright (c) 2005 by Aurelien Foret <orelien@chez.com>
6 * Copyright (c) 2005 by Christian Hamar <krics@linuxforum.hu>
7 * Copyright (c) 2006 by David Kimpe <dnaku@frugalware.org>
8 * Copyright (c) 2005, 2006 by Miklos Vajna <vmiklos@frugalware.org>
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
34 #if defined(__APPLE__) || defined(__OpenBSD__)
35 #include <sys/syslimits.h>
42 #include <limits.h> /* PATH_MAX */
47 #include "alpm_list.h"
56 pmdb_t
*_alpm_db_new(const char *root
, const char *dbpath
, const char *treename
)
62 db
= calloc(1, sizeof(pmdb_t
));
64 _alpm_log(PM_LOG_ERROR
, _("malloc failed: could not allocate %d bytes"),
66 RET_ERR(PM_ERR_MEMORY
, NULL
);
69 db
->path
= calloc(1, strlen(root
)+strlen(dbpath
)+strlen(treename
)+2);
70 if(db
->path
== NULL
) {
71 _alpm_log(PM_LOG_ERROR
, _("malloc failed: could not allocate %d bytes"),
72 strlen(root
)+strlen(dbpath
)+strlen(treename
)+2);
74 RET_ERR(PM_ERR_MEMORY
, NULL
);
76 sprintf(db
->path
, "%s%s%s/", root
, dbpath
, treename
);
78 STRNCPY(db
->treename
, treename
, PATH_MAX
);
83 void _alpm_db_free(pmdb_t
*db
)
87 _FREELIST(db
->servers
, _alpm_server_free
);
94 int _alpm_db_cmp(const void *db1
, const void *db2
)
97 return(strcmp(((pmdb_t
*)db1
)->treename
, ((pmdb_t
*)db2
)->treename
));
100 alpm_list_t
*_alpm_db_search(pmdb_t
*db
, alpm_list_t
*needles
)
102 alpm_list_t
*i
, *j
, *k
, *ret
= NULL
;
106 for(i
= needles
; i
; i
= i
->next
) {
110 if(i
->data
== NULL
) {
114 _alpm_log(PM_LOG_DEBUG
, "searching for target '%s'", targ
);
116 if(regcomp(®
, targ
, REG_EXTENDED
| REG_NOSUB
| REG_ICASE
| REG_NEWLINE
) != 0) {
117 RET_ERR(PM_ERR_INVALID_REGEX
, NULL
);
120 for(j
= _alpm_db_get_pkgcache(db
); j
; j
= j
->next
) {
121 pmpkg_t
*pkg
= j
->data
;
122 const char *matched
= NULL
;
125 if (regexec(®
, alpm_pkg_get_name(pkg
), 0, 0, 0) == 0) {
126 matched
= alpm_pkg_get_name(pkg
);
129 else if (regexec(®
, alpm_pkg_get_desc(pkg
), 0, 0, 0) == 0) {
130 matched
= alpm_pkg_get_desc(pkg
);
133 /* TODO: should we be doing this, and should we print something
134 * differently when we do match it since it isn't currently printed? */
136 for(k
= alpm_pkg_get_provides(pkg
); k
; k
= k
->next
) {
137 if (regexec(®
, k
->data
, 0, 0, 0) == 0) {
144 if(matched
!= NULL
) {
145 _alpm_log(PM_LOG_DEBUG
, " search target '%s' matched '%s'",
147 ret
= alpm_list_add(ret
, pkg
);
157 pmdb_t
*_alpm_db_register(const char *treename
, alpm_cb_db_register callback
)
165 if(strcmp(treename
, "local") == 0) {
166 if(handle
->db_local
!= NULL
) {
167 _alpm_log(PM_LOG_WARNING
, _("attempt to re-register the 'local' DB"));
168 RET_ERR(PM_ERR_DB_NOT_NULL
, NULL
);
172 for(i
= handle
->dbs_sync
; i
; i
= i
->next
) {
173 pmdb_t
*sdb
= i
->data
;
174 if(strcmp(treename
, sdb
->treename
) == 0) {
175 _alpm_log(PM_LOG_DEBUG
, _("attempt to re-register the '%s' database, using existing"), sdb
->treename
);
181 _alpm_log(PM_LOG_DEBUG
, _("registering database '%s'"), treename
);
183 /* make sure the database directory exists */
184 snprintf(path
, PATH_MAX
, "%s%s/%s", handle
->root
, handle
->dbpath
, treename
);
185 if(stat(path
, &buf
) != 0 || !S_ISDIR(buf
.st_mode
)) {
186 _alpm_log(PM_LOG_DEBUG
, _("database directory '%s' does not exist, creating it"), path
);
187 if(_alpm_makepath(path
) != 0) {
188 RET_ERR(PM_ERR_SYSTEM
, NULL
);
192 db
= _alpm_db_new(handle
->root
, handle
->dbpath
, treename
);
194 RET_ERR(PM_ERR_DB_CREATE
, NULL
);
197 _alpm_log(PM_LOG_DEBUG
, _("opening database '%s'"), db
->treename
);
198 if(_alpm_db_open(db
) == -1) {
200 RET_ERR(PM_ERR_DB_OPEN
, NULL
);
203 /* Only call callback on NEW registration. */
204 if(callback
) callback(treename
, db
);
206 if(strcmp(treename
, "local") == 0) {
207 handle
->db_local
= db
;
209 handle
->dbs_sync
= alpm_list_add(handle
->dbs_sync
, db
);
215 const char SYMEXPORT
*alpm_db_get_name(pmdb_t
*db
)
220 ASSERT(handle
!= NULL
, return(NULL
));
221 ASSERT(db
!= NULL
, return(NULL
));
226 const char *alpm_db_get_url(pmdb_t
*db
)
234 ASSERT(handle
!= NULL
, return(NULL
));
235 ASSERT(db
!= NULL
, return(NULL
));
237 s
= (pmserver_t
*)db
->servers
->data
;
239 snprintf(path
, PATH_MAX
, "%s://%s%s", s
->s_url
->scheme
, s
->s_url
->host
, s
->s_url
->doc
);
243 /* vim: set ts=2 sw=2 noet: */