summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/pacman.c110
-rw-r--r--src/pacman.h6
-rw-r--r--src/util.c91
-rw-r--r--src/util.h1
-rw-r--r--src/vercmp.c25
5 files changed, 187 insertions, 46 deletions
diff --git a/src/pacman.c b/src/pacman.c
index 4d2cbb4b..b6714d22 100644
--- a/src/pacman.c
+++ b/src/pacman.c
@@ -54,7 +54,7 @@ char* MDFile(char *);
*/
/* pacman options */
-char* pmo_root = NULL;
+char *pmo_root = NULL;
unsigned short pmo_op = PM_MAIN;
unsigned short pmo_verbose = 0;
unsigned short pmo_version = 0;
@@ -62,8 +62,10 @@ unsigned short pmo_help = 0;
unsigned short pmo_force = 0;
unsigned short pmo_nodeps = 0;
unsigned short pmo_upgrade = 0;
+unsigned short pmo_freshen = 0;
unsigned short pmo_nosave = 0;
-unsigned short pmo_vertest = 0;
+unsigned short pmo_d_vertest = 0;
+unsigned short pmo_d_resolve = 0;
unsigned short pmo_q_isfile = 0;
unsigned short pmo_q_info = 0;
unsigned short pmo_q_list = 0;
@@ -134,7 +136,7 @@ int main(int argc, char *argv[])
fprintf(stderr, "error: unable to lock pacman database.\n");
fprintf(stderr, " if you're sure pacman is not already running, you\n");
fprintf(stderr, " can remove %s\n", lckfile);
- return(127);
+ return(32);
}
/* set signal handlers */
@@ -208,7 +210,7 @@ int pacman_deptest(pacdb_t *db, PMList *targets)
PMList *lp, *deps;
pkginfo_t *dummy;
- if(pmo_vertest) {
+ if(pmo_d_vertest) {
if(targets && targets->data && targets->next && targets->next->data) {
int ret = rpmvercmp(targets->data, targets->next->data);
printf("%d\n", ret);
@@ -231,24 +233,46 @@ int pacman_deptest(pacdb_t *db, PMList *targets)
list_free(list);
if(deps) {
+ /* return 126 = deps were missing, but successfully resolved
+ * return 127 = deps were missing, and failed to resolve; OR
+ * = deps were missing, but no resolution was attempted; OR
+ * = unresolvable conflicts were found
+ */
+ int ret = 126;
+ PMList *synctargs = NULL;
for(lp = deps; lp; lp = lp->next) {
depmissing_t *miss = (depmissing_t*)lp->data;
if(miss->type == CONFLICT) {
+ /* we can't auto-resolve conflicts */
printf("conflict: %s\n", miss->depend.name);
+ ret = 127;
} else if(miss->type == DEPEND || miss->type == REQUIRED) {
- printf("requires: %s", miss->depend.name);
- switch(miss->depend.mod) {
- case DEP_EQ: printf("=%s", miss->depend.version); break;
- case DEP_GE: printf(">=%s", miss->depend.version); break;
- case DEP_LE: printf("<=%s", miss->depend.version); break;
+ if(!pmo_d_resolve) {
+ printf("requires: %s", miss->depend.name);
+ switch(miss->depend.mod) {
+ case DEP_EQ: printf("=%s", miss->depend.version); break;
+ case DEP_GE: printf(">=%s", miss->depend.version); break;
+ case DEP_LE: printf("<=%s", miss->depend.version); break;
+ }
+ printf("\n");
}
- printf("\n");
+ synctargs = list_add(synctargs, strdup(miss->depend.name));
}
FREE(miss);
lp->data = NULL;
}
FREE(deps);
- return(127);
+ /* attempt to resolve missing dependencies */
+ /* TODO: handle version comparators (eg, glibc>=2.2.5) */
+ if(ret == 126 && synctargs != NULL) {
+ if(!pmo_d_resolve || pacman_sync(db, synctargs)) {
+ /* error (or -D not used) */
+ ret = 127;
+ }
+ }
+ list_free(synctargs);
+ synctargs = NULL;
+ return(ret);
}
return(0);
}
@@ -278,7 +302,7 @@ int pacman_sync(pacdb_t *db, PMList *targets)
}
oldmask = umask(0000);
- if(mkdir("/var/cache/pacman", 0755) && mkdir("/var/cache/pacman/pkg", 0755)) {
+ if(makepath("/var/cache/pacman/pkg")) {
fprintf(stderr, "error: could not create new cache directory: %s\n", strerror(errno));
return(1);
}
@@ -333,14 +357,18 @@ int pacman_sync(pacdb_t *db, PMList *targets)
haystack = strdup(pkg->name);
strtoupper(haystack);
if(strstr(haystack, targ)) {
- printf("%s %s\n", pkg->name, pkg->version);
+ printf("%s/%s %s\n ", dbs->sync->treename, pkg->name, pkg->version);
+ indentprint(pkg->desc, 4);
+ printf("\n");
} else {
/* check description */
FREE(haystack);
haystack = strdup(pkg->desc);
strtoupper(haystack);
if(strstr(haystack, targ)) {
- printf("%s %s\n", pkg->name, pkg->version);
+ printf("%s/%s %s\n ", dbs->sync->treename, pkg->name, pkg->version);
+ indentprint(pkg->desc, 4);
+ printf("\n");
}
}
FREE(haystack);
@@ -409,7 +437,7 @@ int pacman_sync(pacdb_t *db, PMList *targets)
}
}
}
- if(newer) {
+ if(newer && allgood) {
fprintf(stderr, ":: Above packages will be skipped. To manually upgrade use 'pacman -S <pkg>'\n");
}
} else {
@@ -439,6 +467,7 @@ int pacman_sync(pacdb_t *db, PMList *targets)
}
if(!found) {
fprintf(stderr, "%s: not found in sync db\n", (char*)i->data);
+ allgood = 0;
continue;
}
if(local) {
@@ -500,7 +529,7 @@ int pacman_sync(pacdb_t *db, PMList *targets)
for(i = deps; i; i = i->next) {
depmissing_t *miss = (depmissing_t*)i->data;
if(miss->type == CONFLICT) {
- fprintf(stderr, " %s: conflicts with %s\n", miss->target, miss->depend.name);
+ fprintf(stderr, " %s: conflicts with %s\n", miss->target, miss->depend.name);
} else if(miss->type == DEPEND || miss->type == REQUIRED) {
fprintf(stderr, " %s: requires %s", miss->target, miss->depend.name);
switch(miss->depend.mod) {
@@ -556,7 +585,12 @@ int pacman_sync(pacdb_t *db, PMList *targets)
if(pmo_s_downloadonly) {
confirm = yesno("\nDo you want to download these packages? [Y/n] ");
} else {
- confirm = yesno("\nDo you want to install/upgrade these packages? [Y/n] ");
+ /* don't get any confirmation if we're called from makepkg */
+ if(pmo_d_resolve) {
+ confirm = 1;
+ } else {
+ confirm = yesno("\nDo you want to install/upgrade these packages? [Y/n] ");
+ }
}
}
}
@@ -657,7 +691,7 @@ int pacman_sync(pacdb_t *db, PMList *targets)
}
}
if(allgood) {
- pacman_upgrade(db, files);
+ allgood = !pacman_upgrade(db, files);
}
}
@@ -714,11 +748,20 @@ int pacman_add(pacdb_t *db, PMList *targets)
fflush(stdout);
for(targ = targets; targ; targ = targ->next) {
/* Populate the package struct */
- vprint(" %s\n", (char*)targ->data);
+ vprint("reading %s\n", (char*)targ->data);
info = load_pkg((char*)targ->data, 0);
if(info == NULL) {
return(1);
}
+ if(pmo_freshen) {
+ /* only upgrade/install this package if it is already installed */
+ pkginfo_t *dummy = db_scan(db, info->name, INFRQ_DESC);
+ if(dummy == NULL) {
+ freepkg(info);
+ info = NULL;
+ continue;
+ }
+ }
alltargs = list_add(alltargs, info);
filenames = list_add(filenames, strdup(targ->data));
}
@@ -991,8 +1034,13 @@ int pacman_add(pacdb_t *db, PMList *targets)
tar_close(tar);
if(errors) {
ret = 1;
- fprintf(stderr, "error installing %s - skipping db update for this package\n", info->name);
- } else {
+ fprintf(stderr, "errors occurred while %s %s\n",
+ (pmo_upgrade ? "upgrading" : "installing"), info->name);
+
+/* XXX: this "else" is disabled so the db_write() ALWAYS occurs. If it doesn't
+ * packages can get lost during an upgrade.
+ */
+ } /*else*/ {
time_t t = time(NULL);
/* if this is an upgrade then propagate the old package's requiredby list over to
@@ -1001,8 +1049,7 @@ int pacman_add(pacdb_t *db, PMList *targets)
list_free(info->requiredby);
info->requiredby = NULL;
for(lp = oldpkg->requiredby; lp; lp = lp->next) {
- char *s = strdup(lp->data);
- info->requiredby = list_add(info->requiredby, s);
+ info->requiredby = list_add(info->requiredby, strdup(lp->data));
}
}
@@ -1230,6 +1277,18 @@ int pacman_remove(pacdb_t *db, PMList *targets)
}
}
+ /* run ldconfig if it exists */
+ snprintf(line, PATH_MAX, "%setc/ld.so.conf", pmo_root);
+ if(!stat(line, &buf)) {
+ snprintf(line, PATH_MAX, "%ssbin/ldconfig", pmo_root);
+ if(!stat(line, &buf)) {
+ char cmd[PATH_MAX];
+ snprintf(cmd, PATH_MAX, "%s -r %s", line, pmo_root);
+ vprint("running \"%s\"\n", cmd);
+ system(cmd);
+ }
+ }
+
return(0);
}
@@ -1477,7 +1536,8 @@ int resolvedeps(pacdb_t *local, PMList *databases, syncpkg_t *syncpkg, PMList *l
continue;
}
if(miss->type == CONFLICT) {
- fprintf(stderr, "error: %s conflicts with %s\n", miss->target, miss->depend.name);
+ fprintf(stderr, "error: cannot resolve dependencies for \"%s\":\n", miss->target);
+ fprintf(stderr, " %s conflicts with %s\n", miss->target, miss->depend.name);
return(1);
} else if(miss->type == DEPEND) {
/*printf("resolving %s\n", sync->pkg->name); fflush(stdout);*/
@@ -1639,7 +1699,7 @@ PMList* checkdeps(pacdb_t *db, unsigned short op, PMList *targets)
miss->depend.mod = DEP_ANY;
miss->depend.version[0] = '\0';
strncpy(miss->target, tp->name, 256);
- strncpy(miss->depend.name, (char*)j->data, 256);
+ strncpy(miss->depend.name, info->name, 256);
baddeps = list_add(baddeps, miss);
}
}
diff --git a/src/pacman.h b/src/pacman.h
index c9794737..c9b06219 100644
--- a/src/pacman.h
+++ b/src/pacman.h
@@ -22,7 +22,7 @@
#define _PAC_PACMAN_H
#ifndef PACVER
-#define PACVER "2.2"
+#define PACVER "2.3"
#endif
#ifndef PKGDIR
@@ -37,8 +37,8 @@
#define PM_MAIN 1
#define PM_ADD 2
#define PM_REMOVE 3
-#define PM_QUERY 4
-#define PM_UPGRADE 5
+#define PM_UPGRADE 4
+#define PM_QUERY 5
#define PM_SYNC 6
#define PM_DEPTEST 7
diff --git a/src/util.c b/src/util.c
index 6d4c1bc7..cba4a050 100644
--- a/src/util.c
+++ b/src/util.c
@@ -45,8 +45,10 @@ extern unsigned short pmo_help;
extern unsigned short pmo_force;
extern unsigned short pmo_nodeps;
extern unsigned short pmo_upgrade;
+extern unsigned short pmo_freshen;
extern unsigned short pmo_nosave;
-extern unsigned short pmo_vertest;
+extern unsigned short pmo_d_vertest;
+extern unsigned short pmo_d_resolve;
extern unsigned short pmo_q_isfile;
extern unsigned short pmo_q_info;
extern unsigned short pmo_q_list;
@@ -139,10 +141,12 @@ int parseargs(int op, int argc, char **argv)
{"add", no_argument, 0, 'A'},
{"remove", no_argument, 0, 'R'},
{"upgrade", no_argument, 0, 'U'},
+ {"freshen", no_argument, 0, 'F'},
{"query", no_argument, 0, 'Q'},
{"sync", no_argument, 0, 'S'},
{"deptest", no_argument, 0, 'T'},
{"vertest", no_argument, 0, 'Y'},
+ {"resolve", no_argument, 0, 'D'},
{"root", required_argument, 0, 'r'},
{"verbose", no_argument, 0, 'v'},
{"version", no_argument, 0, 'V'},
@@ -162,7 +166,7 @@ int parseargs(int op, int argc, char **argv)
{0, 0, 0, 0}
};
- while((opt = getopt_long(argc, argv, "ARUQSTYr:vhscVfnoldpiuwy", opts, &option_index))) {
+ while((opt = getopt_long(argc, argv, "ARUFQSTDYr:vhscVfnoldpiuwy", opts, &option_index))) {
if(opt < 0) {
break;
}
@@ -171,10 +175,12 @@ int parseargs(int op, int argc, char **argv)
case 'A': pmo_op = (pmo_op != PM_MAIN ? 0 : PM_ADD); break;
case 'R': pmo_op = (pmo_op != PM_MAIN ? 0 : PM_REMOVE); break;
case 'U': pmo_op = (pmo_op != PM_MAIN ? 0 : PM_UPGRADE); break;
+ case 'F': pmo_op = (pmo_op != PM_MAIN ? 0 : PM_UPGRADE); pmo_freshen = 1; break;
case 'Q': pmo_op = (pmo_op != PM_MAIN ? 0 : PM_QUERY); break;
case 'S': pmo_op = (pmo_op != PM_MAIN ? 0 : PM_SYNC); break;
- case 'T': pmo_op = (pmo_op != PM_MAIN ? 0 : PM_DEPTEST); break;
- case 'Y': pmo_op = (pmo_op != PM_MAIN ? 0 : PM_DEPTEST); pmo_vertest = 1; break;
+ case 'T': pmo_op = (pmo_op != PM_MAIN ? 0 : PM_DEPTEST); break;
+ case 'Y': pmo_op = (pmo_op != PM_MAIN ? 0 : PM_DEPTEST); pmo_d_vertest = 1; break;
+ case 'D': pmo_op = (pmo_op != PM_MAIN ? 0 : PM_DEPTEST); pmo_d_resolve = 1; break;
case 'h': pmo_help = 1; break;
case 'V': pmo_version = 1; break;
case 'v': pmo_verbose = 1; break;
@@ -483,6 +489,7 @@ void usage(int op, char *myname)
printf(" %s {-A --add} [options] <file>\n", myname);
printf(" %s {-R --remove} [options] <package>\n", myname);
printf(" %s {-U --upgrade} [options] <file>\n", myname);
+ printf(" %s {-F --freshen} [options] <file>\n", myname);
printf(" %s {-Q --query} [options] [package]\n", myname);
printf(" %s {-S --sync} [options] [package]\n", myname);
printf("\nuse '%s --help' with other options for more syntax\n\n", myname);
@@ -490,26 +497,30 @@ void usage(int op, char *myname)
if(op == PM_ADD) {
printf("usage: %s {-A --add} [options] <file>\n", myname);
printf("options:\n");
- printf(" -f, --force force install, overwrite conflicting files\n");
- printf(" -d, --nodeps skip dependency checks\n");
+ printf(" -f, --force force install, overwrite conflicting files\n");
+ printf(" -d, --nodeps skip dependency checks\n");
} else if(op == PM_REMOVE) {
printf("usage: %s {-R --remove} [options] <package>\n", myname);
printf("options:\n");
- printf(" -d, --nodeps skip dependency checks\n");
- printf(" -n, --nosave remove configuration files as well\n");
+ printf(" -d, --nodeps skip dependency checks\n");
+ printf(" -n, --nosave remove configuration files as well\n");
} else if(op == PM_UPGRADE) {
- printf("usage: %s {-U --upgrade} [options] <file>\n", myname);
+ if(pmo_freshen) {
+ printf("usage: %s {-F --freshen} [options] <file>\n", myname);
+ } else {
+ printf("usage: %s {-U --upgrade} [options] <file>\n", myname);
+ }
printf("options:\n");
- printf(" -f, --force force install, overwrite conflicting files\n");
- printf(" -d, --nodeps skip dependency checks\n");
+ printf(" -f, --force force install, overwrite conflicting files\n");
+ printf(" -d, --nodeps skip dependency checks\n");
} else if(op == PM_QUERY) {
printf("usage: %s {-Q --query} [options] [package]\n", myname);
printf("options:\n");
- printf(" -o, --owns <file> query the package that owns <file>\n");
- printf(" -l, --list list the contents of the queried package\n");
- printf(" -i, --info view package information\n");
- printf(" -p, --file pacman will query the package file [package] instead of\n");
- printf(" looking in the database\n");
+ printf(" -o, --owns <file> query the package that owns <file>\n");
+ printf(" -l, --list list the contents of the queried package\n");
+ printf(" -i, --info view package information\n");
+ printf(" -p, --file pacman will query the package file [package] instead of\n");
+ printf(" looking in the database\n");
} else if(op == PM_SYNC) {
printf("usage: %s {-S --sync} [options] [package]\n", myname);
printf("options:\n");
@@ -521,8 +532,8 @@ void usage(int op, char *myname)
printf(" -w, --downloadonly download packages, but do not install/upgrade anything\n");
printf(" -c, --clean remove packages from cache directory to free up diskspace\n");
}
- printf(" -v, --verbose be verbose\n");
- printf(" -r, --root <path> set an alternate installation root\n");
+ printf(" -v, --verbose be verbose\n");
+ printf(" -r, --root <path> set an alternate installation root\n");
}
}
@@ -570,6 +581,50 @@ int yesno(char *fmt, ...)
}
return(0);
}
+
+/* output a string, but wrap words properly with a specified indentation
+ */
+void indentprint(char *str, int indent)
+{
+ char *p = str;
+ char *cenv = NULL;
+ int cols = 80;
+ int cidx = indent;
+
+ cenv = getenv("COLUMNS");
+ if(cenv) {
+ cols = atoi(cenv);
+ }
+
+ while(*p) {
+ if(*p == ' ') {
+ char *next = NULL;
+ int len;
+ p++;
+ if(p == NULL || *p == ' ') continue;
+ next = strchr(p, ' ');
+ if(next == NULL) {
+ next = p + strlen(p);
+ }
+ len = next - p;
+ if(len > (cols-cidx-1)) {
+ /* newline */
+ int i;
+ printf("\n");
+ for(i = 0; i < indent; i++) {
+ printf(" ");
+ }
+ cidx = indent;
+ } else {
+ printf(" ");
+ cidx++;
+ }
+ }
+ printf("%c", *p);
+ p++;
+ cidx++;
+ }
+}
/* Test for existence of a string in a PMList
*/
diff --git a/src/util.h b/src/util.h
index 132d7c06..222c00fa 100644
--- a/src/util.h
+++ b/src/util.h
@@ -38,6 +38,7 @@ int copyfile(char *src, char *dest);
int makepath(char *path);
int rmrf(char *path);
int vprint(char *fmt, ...);
+void indentprint(char *str, int indent);
int yesno(char* fmt, ...);
void usage(int op, char *myname);
void version(void);
diff --git a/src/vercmp.c b/src/vercmp.c
new file mode 100644
index 00000000..850ebea6
--- /dev/null
+++ b/src/vercmp.c
@@ -0,0 +1,25 @@
+#include <stdio.h>
+#include <string.h>
+
+int rpmvercmp(const char *a, const char *b);
+
+int main(int argc, char *argv[])
+{
+ char s1[255] = "";
+ char s2[255] = "";
+ int ret;
+
+ if(argc > 1) {
+ strncpy(s1, argv[1], 255);
+ }
+ if(argc > 2) {
+ strncpy(s2, argv[2], 255);
+ } else {
+ printf("0\n");
+ return(0);
+ }
+
+ ret = rpmvercmp(s1, s2);
+ printf("%d\n", ret);
+ return(ret);
+}