4 * Copyright (c) 2002-2007 by Judd Vinet <jvinet@zeroflux.org>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
31 #include <alpm_list.h>
32 #include <download.h> /* downloadLastErrString */
33 /* TODO remove above download.h inclusion once we abstract more, and also
34 * remove it from Makefile.am on the pacman side */
43 extern pmdb_t
*db_local
;
45 /* if keep_used != 0, then the dirnames which match an used syncdb
47 static int sync_cleandb(const char *dbpath
, int keep_used
) {
51 dir
= opendir(dbpath
);
53 fprintf(stderr
, _("error: could not access database directory\n"));
58 /* step through the directory one file at a time */
59 while((ent
= readdir(dir
)) != NULL
) {
62 alpm_list_t
*syncdbs
= NULL
, *i
;
64 char *dname
= ent
->d_name
;
66 if(!strcmp(dname
, ".") || !strcmp(dname
, "..")) {
69 /* skip the local and sync directories */
70 if(!strcmp(dname
, "sync") || !strcmp(dname
, "local")) {
74 /* build the full path */
75 snprintf(path
, PATH_MAX
, "%s%s", dbpath
, ent
->d_name
);
76 /* skip entries that are not dirs (lock file, etc.) */
78 if(!S_ISDIR(buf
.st_mode
)) {
83 syncdbs
= alpm_option_get_syncdbs();
84 for(i
= syncdbs
; i
&& !found
; i
= alpm_list_next(i
)) {
85 pmdb_t
*db
= alpm_list_getdata(i
);
86 found
= !strcmp(dname
, alpm_db_get_name(db
));
89 /* We have a directory that doesn't match any syncdb.
90 * Ask the user if he wants to remove it. */
92 if(!yesno(1, _("Do you want to remove %s?"), path
)) {
97 fprintf(stderr
, _("error: could not remove repository directory\n"));
106 static int sync_cleandb_all(void) {
107 const char *dbpath
= alpm_option_get_dbpath();
108 char newdbpath
[PATH_MAX
];
110 printf(_("Database directory: %s\n"), dbpath
);
111 if(!yesno(1, _("Do you want to remove unused repositories?"))) {
114 /* The sync dbs were previously put in dbpath/, but are now in dbpath/sync/,
115 * so we will clean everything in dbpath/ (except dbpath/local/ and dbpath/sync/,
116 * and only the unused sync dbs in dbpath/sync/ */
117 sync_cleandb(dbpath
, 0);
119 sprintf(newdbpath
, "%s%s", dbpath
, "sync/");
120 sync_cleandb(newdbpath
, 1);
122 printf(_("Database directory cleaned up\n"));
126 static int sync_cleancache(int level
)
128 /* TODO for now, just mess with the first cache directory */
129 alpm_list_t
* cachedirs
= alpm_option_get_cachedirs();
130 const char *cachedir
= alpm_list_getdata(cachedirs
);
133 /* incomplete cleanup */
136 /* Open up each package and see if it should be deleted,
137 * depending on the clean method used */
138 printf(_("Cache directory: %s\n"), cachedir
);
139 switch(config
->cleanmethod
) {
140 case PM_CLEAN_KEEPINST
:
141 if(!yesno(1, _("Do you want to remove uninstalled packages from cache?"))) {
145 case PM_CLEAN_KEEPCUR
:
146 if(!yesno(1, _("Do you want to remove outdated packages from cache?"))) {
151 /* this should not happen : the config parsing doesn't set any other value */
154 printf(_("removing old packages from cache... "));
156 dir
= opendir(cachedir
);
158 fprintf(stderr
, _("error: could not access cache directory\n"));
163 /* step through the directory one file at a time */
164 while((ent
= readdir(dir
)) != NULL
) {
167 pmpkg_t
*localpkg
= NULL
, *pkg
= NULL
;
168 alpm_list_t
*sync_dbs
= alpm_option_get_syncdbs();
171 if(!strcmp(ent
->d_name
, ".") || !strcmp(ent
->d_name
, "..")) {
174 /* build the full filepath */
175 snprintf(path
, PATH_MAX
, "%s%s", cachedir
, ent
->d_name
);
177 /* attempt to load the package, skip file on failures as we may have
178 * files here that aren't valid packages. we also don't need a full
179 * load of the package, just the metadata. */
180 if(alpm_pkg_load(path
, 0, &localpkg
) != 0 || localpkg
== NULL
) {
183 switch(config
->cleanmethod
) {
184 case PM_CLEAN_KEEPINST
:
185 /* check if this package is in the local DB */
186 pkg
= alpm_db_get_pkg(db_local
, alpm_pkg_get_name(localpkg
));
187 if(pkg
!= NULL
&& alpm_pkg_vercmp(alpm_pkg_get_version(localpkg
),
188 alpm_pkg_get_version(pkg
)) == 0) {
189 /* package was found in local DB and version matches, keep it */
193 case PM_CLEAN_KEEPCUR
:
194 /* check if this package is in a sync DB */
195 for(j
= sync_dbs
; j
&& delete; j
= alpm_list_next(j
)) {
196 pmdb_t
*db
= alpm_list_getdata(j
);
197 pkg
= alpm_db_get_pkg(db
, alpm_pkg_get_name(localpkg
));
198 if(pkg
!= NULL
&& alpm_pkg_vercmp(alpm_pkg_get_version(localpkg
),
199 alpm_pkg_get_version(pkg
)) == 0) {
200 /* package was found in a sync DB and version matches, keep it */
206 /* this should not happen : the config parsing doesn't set any other value */
210 /* free the local file package */
211 alpm_pkg_free(localpkg
);
217 printf(_("done.\n"));
220 printf(_("Cache directory: %s\n"), cachedir
);
221 if(!yesno(0, _("Do you want to remove ALL packages from cache?"))) {
224 printf(_("removing all packages from cache... "));
227 fprintf(stderr
, _("error: could not remove cache directory\n"));
231 if(makepath(cachedir
)) {
232 fprintf(stderr
, _("error: could not create new cache directory\n"));
235 printf(_("done.\n"));
241 static int sync_trans_init(pmtransflag_t flags
) {
242 if(alpm_trans_init(PM_TRANS_TYPE_SYNC
, flags
, cb_trans_evt
,
243 cb_trans_conv
, cb_trans_progress
) == -1) {
244 fprintf(stderr
, _("error: failed to init transaction (%s)\n"),
245 alpm_strerrorlast());
246 if(pm_errno
== PM_ERR_HANDLE_LOCK
) {
247 printf(_(" if you're sure a package manager is not already\n"
248 " running, you can remove %s.\n"), alpm_option_get_lockfile());
255 static int sync_trans_release() {
256 if(alpm_trans_release() == -1) {
257 fprintf(stderr
, _("error: failed to release transaction (%s)\n"),
258 alpm_strerrorlast());
263 static int sync_synctree(int level
, alpm_list_t
*syncs
)
266 int success
= 0, ret
;
268 if(sync_trans_init(0) == -1) {
272 for(i
= syncs
; i
; i
= alpm_list_next(i
)) {
273 pmdb_t
*db
= alpm_list_getdata(i
);
275 ret
= alpm_db_update((level
< 2 ? 0 : 1), db
);
277 if(pm_errno
== PM_ERR_DB_SYNC
) {
278 /* use libdownload error */
279 /* TODO breaking abstraction barrier here?
280 * pacman -> libalpm -> libdownload
282 * Yes. This will be here until we add a nice pacman "pm_errstr" or
283 * something, OR add all libdownload error codes into the pm_error enum
285 fprintf(stderr
, _("error: failed to synchronize %s: %s\n"),
286 alpm_db_get_name(db
), downloadLastErrString
);
288 fprintf(stderr
, _("error: failed to update %s (%s)\n"),
289 alpm_db_get_name(db
), alpm_strerrorlast());
291 } else if(ret
== 1) {
292 printf(_(" %s is up to date\n"), alpm_db_get_name(db
));
299 if(sync_trans_release() == -1) {
302 /* We should always succeed if at least one DB was upgraded - we may possibly
303 * fail later with unresolved deps, but that should be rare, and would be
307 fprintf(stderr
, _("error: failed to synchronize any databases\n"));
312 /* search the sync dbs for a matching package */
313 static int sync_search(alpm_list_t
*syncs
, alpm_list_t
*targets
)
315 alpm_list_t
*i
, *j
, *ret
;
319 for(i
= syncs
; i
; i
= alpm_list_next(i
)) {
320 pmdb_t
*db
= alpm_list_getdata(i
);
321 /* if we have a targets list, search for packages matching it */
323 ret
= alpm_db_search(db
, targets
);
326 ret
= alpm_db_getpkgcache(db
);
334 for(j
= ret
; j
; j
= alpm_list_next(j
)) {
335 /* print repo/name (group) info about each package in our list */
338 pmpkg_t
*pkg
= alpm_list_getdata(j
);
340 if (!config
->quiet
) {
341 printf("%s/%s %s", alpm_db_get_name(db
), alpm_pkg_get_name(pkg
),
342 alpm_pkg_get_version(pkg
));
344 printf("%s", alpm_pkg_get_name(pkg
));
347 /* print the package size with the output if ShowSize option set */
348 if(config
->showsize
) {
349 /* Convert byte size to MB */
350 double mbsize
= alpm_pkg_get_size(pkg
) / (1024.0 * 1024.0);
352 printf(" [%.2f MB]", mbsize
);
355 if (!config
->quiet
) {
356 /* TODO package in multiple groups needs to be handled, do a loop */
357 if((grp
= alpm_pkg_get_groups(pkg
)) != NULL
) {
358 group
= alpm_list_getdata(grp
);
359 printf(" (%s)", group
);
362 /* we need a newline and initial indent first */
364 indentprint(alpm_pkg_get_desc(pkg
), 4);
368 /* we only want to free if the list was a search list */
377 static int sync_group(int level
, alpm_list_t
*syncs
, alpm_list_t
*targets
)
379 alpm_list_t
*i
, *j
, *k
;
380 alpm_list_t
*pkgnames
= NULL
;
383 for(i
= targets
; i
; i
= alpm_list_next(i
)) {
384 char *grpname
= alpm_list_getdata(i
);
385 for(j
= syncs
; j
; j
= alpm_list_next(j
)) {
386 pmdb_t
*db
= alpm_list_getdata(j
);
387 pmgrp_t
*grp
= alpm_db_readgrp(db
, grpname
);
390 printf("%s\n", (char *)alpm_grp_get_name(grp
));
391 /* get names of packages in group */
392 for(k
= alpm_grp_get_pkgs(grp
); k
; k
= alpm_list_next(k
)) {
393 pkgnames
= alpm_list_add(pkgnames
,
394 (char*)alpm_pkg_get_name(k
->data
));
396 list_display(" ", pkgnames
);
397 alpm_list_free(pkgnames
);
402 for(i
= syncs
; i
; i
= alpm_list_next(i
)) {
403 pmdb_t
*db
= alpm_list_getdata(i
);
405 for(j
= alpm_db_getgrpcache(db
); j
; j
= alpm_list_next(j
)) {
406 pmgrp_t
*grp
= alpm_list_getdata(j
);
408 printf("%s\n", (char *)alpm_grp_get_name(grp
));
409 if(grp
&& level
> 1) {
410 for(k
= alpm_grp_get_pkgs(grp
); k
; k
= alpm_list_next(k
)) {
411 pkgnames
= alpm_list_add(pkgnames
,
412 (char*)alpm_pkg_get_name(k
->data
));
414 list_display(" ", pkgnames
);
415 alpm_list_free(pkgnames
);
424 static int sync_info(alpm_list_t
*syncs
, alpm_list_t
*targets
)
426 alpm_list_t
*i
, *j
, *k
;
430 for(i
= targets
; i
; i
= alpm_list_next(i
)) {
434 char target
[512]; /* TODO is this enough space? */
435 char *repo
= NULL
, *pkgstr
= NULL
;
437 strncpy(target
, i
->data
, 512);
438 pkgstr
= strchr(target
, '/');
444 for(j
= syncs
; j
; j
= alpm_list_next(j
)) {
445 db
= alpm_list_getdata(j
);
446 if(strcmp(repo
, alpm_db_get_name(db
)) == 0) {
453 fprintf(stderr
, _("error: repository '%s' does not exist\n"), repo
);
457 for(k
= alpm_db_getpkgcache(db
); k
; k
= alpm_list_next(k
)) {
458 pmpkg_t
*pkg
= alpm_list_getdata(k
);
460 if(strcmp(alpm_pkg_get_name(pkg
), pkgstr
) == 0) {
461 dump_pkg_sync(pkg
, alpm_db_get_name(db
));
468 fprintf(stderr
, _("error: package '%s' was not found in repository '%s'\n"), pkgstr
, repo
);
474 for(j
= syncs
; j
; j
= alpm_list_next(j
)) {
475 pmdb_t
*db
= alpm_list_getdata(j
);
477 for(k
= alpm_db_getpkgcache(db
); k
; k
= alpm_list_next(k
)) {
478 pmpkg_t
*pkg
= alpm_list_getdata(k
);
480 if(strcmp(alpm_pkg_get_name(pkg
), pkgstr
) == 0) {
481 dump_pkg_sync(pkg
, alpm_db_get_name(db
));
488 fprintf(stderr
, _("error: package '%s' was not found\n"), pkgstr
);
494 for(i
= syncs
; i
; i
= alpm_list_next(i
)) {
495 pmdb_t
*db
= alpm_list_getdata(i
);
497 for(j
= alpm_db_getpkgcache(db
); j
; j
= alpm_list_next(j
)) {
498 dump_pkg_sync(alpm_list_getdata(j
), alpm_db_get_name(db
));
506 static int sync_list(alpm_list_t
*syncs
, alpm_list_t
*targets
)
508 alpm_list_t
*i
, *j
, *ls
= NULL
;
511 for(i
= targets
; i
; i
= alpm_list_next(i
)) {
512 const char *repo
= alpm_list_getdata(i
);
515 for(j
= syncs
; j
; j
= alpm_list_next(j
)) {
516 pmdb_t
*d
= alpm_list_getdata(j
);
518 if(strcmp(repo
, alpm_db_get_name(d
)) == 0) {
525 fprintf(stderr
, _("error: repository \"%s\" was not found.\n"),repo
);
530 ls
= alpm_list_add(ls
, db
);
536 for(i
= ls
; i
; i
= alpm_list_next(i
)) {
537 pmdb_t
*db
= alpm_list_getdata(i
);
539 for(j
= alpm_db_getpkgcache(db
); j
; j
= alpm_list_next(j
)) {
540 pmpkg_t
*pkg
= alpm_list_getdata(j
);
541 if (!config
->quiet
) {
542 printf("%s %s %s\n", alpm_db_get_name(db
), alpm_pkg_get_name(pkg
),
543 alpm_pkg_get_version(pkg
));
545 printf("%s\n", alpm_pkg_get_name(pkg
));
557 static int sync_trans(alpm_list_t
*targets
)
560 alpm_list_t
*data
= NULL
;
561 alpm_list_t
*sync_dbs
= alpm_option_get_syncdbs();
563 /* Step 1: create a new transaction... */
564 if(sync_trans_init(config
->flags
) == -1) {
568 if(config
->op_s_upgrade
) {
569 alpm_list_t
*pkgs
, *i
;
570 printf(_(":: Starting full system upgrade...\n"));
571 alpm_logaction("starting full system upgrade\n");
572 if(alpm_trans_sysupgrade() == -1) {
573 fprintf(stderr
, _("error: %s\n"), alpm_strerrorlast());
578 if(!(alpm_trans_get_flags() & (PM_TRANS_FLAG_DOWNLOADONLY
| PM_TRANS_FLAG_PRINTURIS
))) {
579 /* check if pacman itself is one of the packages to upgrade.
580 * this can prevent some of the "syntax error" problems users can have
581 * when sysupgrade'ing with an older version of pacman.
583 pkgs
= alpm_trans_get_pkgs();
584 for(i
= pkgs
; i
; i
= alpm_list_next(i
)) {
585 pmsyncpkg_t
*sync
= alpm_list_getdata(i
);
586 pmpkg_t
*spkg
= alpm_sync_get_pkg(sync
);
587 /* TODO pacman name should probably not be hardcoded. In addition, we
588 * have problems on an -Syu if pacman has to pull in deps, so recommend
589 * an '-S pacman' operation */
590 if(strcmp("pacman", alpm_pkg_get_name(spkg
)) == 0) {
592 printf(_(":: pacman has detected a newer version of itself.\n"));
593 if(yesno(1, _(":: Do you want to cancel the current operation\n"
594 ":: and install the new pacman version now?"))) {
595 if(sync_trans_release() == -1) {
598 if(sync_trans_init(0) == -1) {
601 if(alpm_trans_addtarget("pacman") == -1) {
602 fprintf(stderr
, _("error: pacman: %s\n"), alpm_strerrorlast());
613 /* process targets */
614 for(i
= targets
; i
; i
= alpm_list_next(i
)) {
615 char *targ
= alpm_list_getdata(i
);
616 if(alpm_trans_addtarget(targ
) == -1) {
621 if(pm_errno
== PM_ERR_TRANS_DUP_TARGET
) {
622 /* just ignore duplicate targets */
625 if(pm_errno
!= PM_ERR_PKG_NOT_FOUND
) {
626 fprintf(stderr
, _("error: '%s': %s\n"),
627 targ
, alpm_strerrorlast());
631 /* target not found: check if it's a group */
633 for(j
= sync_dbs
; j
; j
= alpm_list_next(j
)) {
634 pmdb_t
*db
= alpm_list_getdata(j
);
635 grp
= alpm_db_readgrp(db
, targ
);
637 alpm_list_t
*k
, *pkgnames
= NULL
;
640 printf(_(":: group %s (including ignored packages):\n"), targ
);
641 /* remove dupe entries in case a package exists in multiple repos */
642 alpm_list_t
*grppkgs
= alpm_grp_get_pkgs(grp
);
643 alpm_list_t
*pkgs
= alpm_list_remove_dupes(grppkgs
);
644 for(k
= pkgs
; k
; k
= alpm_list_next(k
)) {
645 pkgnames
= alpm_list_add(pkgnames
,
646 (char*)alpm_pkg_get_name(k
->data
));
648 list_display(" ", pkgnames
);
649 if(yesno(1, _(":: Install whole content?"))) {
650 for(k
= pkgnames
; k
; k
= alpm_list_next(k
)) {
651 targets
= alpm_list_add(targets
, strdup(alpm_list_getdata(k
)));
654 for(k
= pkgnames
; k
; k
= alpm_list_next(k
)) {
655 char *pkgname
= alpm_list_getdata(k
);
656 if(yesno(1, _(":: Install %s from group %s?"), pkgname
, targ
)) {
657 targets
= alpm_list_add(targets
, strdup(pkgname
));
661 alpm_list_free(pkgnames
);
662 alpm_list_free(pkgs
);
666 /* targ not found in sync db, searching for providers... */
667 alpm_list_t
*prov
= NULL
;
668 for(j
= sync_dbs
; j
; j
= alpm_list_next(j
)) {
669 pmdb_t
*db
= alpm_list_getdata(j
);
670 prov
= alpm_list_join(prov
, alpm_db_whatprovides(db
, targ
));
673 if(alpm_list_count(prov
) == 1) {
674 const char *pname
= NULL
;
675 pmpkg_t
*pkg
= alpm_list_getdata(prov
);
676 pname
= alpm_pkg_get_name(pkg
);
677 alpm_list_free(prov
);
678 printf(_("Warning: %s provides %s\n"), pname
, targ
);
679 targets
= alpm_list_add(targets
, strdup(pname
));
682 fprintf(stderr
, _("error: several packages provide %s, please specify one :\n"), targ
);
683 for(k
= prov
; k
; k
= alpm_list_next(k
)) {
684 pmpkg_t
*pkg
= alpm_list_getdata(k
);
685 printf("%s ", alpm_pkg_get_name(pkg
));
688 alpm_list_free(prov
);
693 fprintf(stderr
, _("error: '%s': not found in sync db\n"), targ
);
702 /* Step 2: "compute" the transaction based on targets and flags */
703 if(alpm_trans_prepare(&data
) == -1) {
704 fprintf(stderr
, _("error: failed to prepare transaction (%s)\n"),
705 alpm_strerrorlast());
708 case PM_ERR_UNSATISFIED_DEPS
:
709 for(i
= data
; i
; i
= alpm_list_next(i
)) {
710 pmdepmissing_t
*miss
= alpm_list_getdata(i
);
711 pmdepend_t
*dep
= alpm_miss_get_dep(miss
);
712 char *depstring
= alpm_dep_get_string(dep
);
713 printf(_(":: %s: requires %s\n"), alpm_miss_get_target(miss
),
718 case PM_ERR_CONFLICTING_DEPS
:
719 for(i
= data
; i
; i
= alpm_list_next(i
)) {
720 pmconflict_t
*conflict
= alpm_list_getdata(i
);
721 printf(_(":: %s: conflicts with %s\n"),
722 alpm_conflict_get_package1(conflict
), alpm_conflict_get_package2(conflict
));
732 alpm_list_t
*packages
= alpm_trans_get_pkgs();
733 if(packages
== NULL
) {
734 /* nothing to do: just exit without complaining */
735 printf(_(" local database is up to date\n"));
739 if(!(alpm_trans_get_flags() & PM_TRANS_FLAG_PRINTURIS
)) {
742 display_targets(packages
, db_local
);
745 if(config
->op_s_downloadonly
) {
746 confirm
= yesno(1, _("Proceed with download?"));
748 confirm
= yesno(1, _("Proceed with installation?"));
753 }/* else 'print uris' requested. We're done at this point */
755 /* Step 3: actually perform the installation */
756 if(alpm_trans_commit(&data
) == -1) {
757 fprintf(stderr
, _("error: failed to commit transaction (%s)\n"),
758 alpm_strerrorlast());
761 case PM_ERR_FILE_CONFLICTS
:
762 for(i
= data
; i
; i
= alpm_list_next(i
)) {
763 pmfileconflict_t
*conflict
= alpm_list_getdata(i
);
764 switch(alpm_fileconflict_get_type(conflict
)) {
765 case PM_FILECONFLICT_TARGET
:
766 printf(_("%s exists in both '%s' and '%s'\n"),
767 alpm_fileconflict_get_file(conflict
),
768 alpm_fileconflict_get_target(conflict
),
769 alpm_fileconflict_get_ctarget(conflict
));
771 case PM_FILECONFLICT_FILESYSTEM
:
772 printf(_("%s: %s exists in filesystem\n"),
773 alpm_fileconflict_get_target(conflict
),
774 alpm_fileconflict_get_file(conflict
));
779 case PM_ERR_PKG_INVALID
:
780 case PM_ERR_DLT_INVALID
:
781 for(i
= data
; i
; i
= alpm_list_next(i
)) {
782 char *filename
= alpm_list_getdata(i
);
783 printf(_("%s is invalid or corrupted\n"), filename
);
790 printf(_("Errors occurred, no packages were upgraded.\n"));
795 /* Step 4: release transaction resources */
800 if(sync_trans_release() == -1) {
807 int pacman_sync(alpm_list_t
*targets
)
809 alpm_list_t
*sync_dbs
= NULL
;
811 /* clean the cache */
812 if(config
->op_s_clean
) {
815 if(sync_trans_init(0) == -1) {
819 ret
+= sync_cleancache(config
->op_s_clean
);
820 ret
+= sync_cleandb_all();
822 if(sync_trans_release() == -1) {
829 /* ensure we have at least one valid sync db set up */
830 sync_dbs
= alpm_option_get_syncdbs();
831 if(sync_dbs
== NULL
|| alpm_list_count(sync_dbs
) == 0) {
832 pm_printf(PM_LOG_ERROR
, _("no usable package repositories configured.\n"));
836 if(targets
== NULL
&& !(config
->op_s_sync
|| config
->op_s_upgrade
837 || config
->op_s_search
|| config
->group
838 || config
->op_s_info
|| config
->op_q_list
)) {
839 /* don't proceed here unless we have an operation that doesn't require
841 pm_printf(PM_LOG_ERROR
, _("no targets specified (use -h for help)\n"));
845 if(config
->op_s_sync
) {
846 /* grab a fresh package list */
847 printf(_(":: Synchronizing package databases...\n"));
848 alpm_logaction("synchronizing package lists\n");
849 if(!sync_synctree(config
->op_s_sync
, sync_dbs
)) {
852 config
->op_s_sync
= 0;
855 if(needs_transaction()) {
856 if(sync_trans(targets
) == 1) {
861 /* search for a package */
862 if(config
->op_s_search
) {
863 return(sync_search(sync_dbs
, targets
));
866 /* look for groups */
868 return(sync_group(config
->group
, sync_dbs
, targets
));
871 /* get package info */
872 if(config
->op_s_info
) {
873 return(sync_info(sync_dbs
, targets
));
876 /* get a listing of files in sync DBs */
877 if(config
->op_q_list
) {
878 return(sync_list(sync_dbs
, targets
));
884 /* vim: set ts=2 sw=2 noet: */