summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/pacman/pacman.c108
-rw-r--r--src/pacman/remove.c6
-rw-r--r--src/pacman/sync.c6
-rw-r--r--src/pacman/upgrade.c6
-rw-r--r--src/pacman/util.c130
5 files changed, 167 insertions, 89 deletions
diff --git a/src/pacman/pacman.c b/src/pacman/pacman.c
index 77c558d1..454505a0 100644
--- a/src/pacman/pacman.c
+++ b/src/pacman/pacman.c
@@ -149,6 +149,7 @@ static void usage(int op, const char * const myname)
printf(_(" -r, --root <path> set an alternate installation root\n"));
printf(_(" -b, --dbpath <path> set an alternate database location\n"));
printf(_(" --cachedir <dir> set an alternate package cache location\n"));
+ printf(_(" --arch <arch> set an alternate architecture\n"));
}
}
@@ -195,6 +196,19 @@ static void setuseragent(void)
setenv("HTTP_USER_AGENT", agent, 0);
}
+static void setarch(const char *arch)
+{
+ if (strcmp(arch, "auto") == 0) {
+ struct utsname un;
+ uname(&un);
+ pm_printf(PM_LOG_DEBUG, "config: architecture: %s\n", un.machine);
+ alpm_option_set_arch(un.machine);
+ } else {
+ pm_printf(PM_LOG_DEBUG, "config: architecture: %s\n", arch);
+ alpm_option_set_arch(arch);
+ }
+}
+
/** Free the resources.
*
* @param ret the return value
@@ -376,6 +390,7 @@ static int parseargs(int argc, char *argv[])
{"ignoregroup", required_argument, 0, 1010},
{"needed", no_argument, 0, 1011},
{"asexplicit", no_argument, 0, 1012},
+ {"arch", required_argument, 0, 1013},
{0, 0, 0, 0}
};
@@ -450,6 +465,9 @@ static int parseargs(int argc, char *argv[])
case 1012:
config->flags |= PM_TRANS_FLAG_ALLEXPLICIT;
break;
+ case 1013:
+ setarch(optarg);
+ break;
case 'Q': config->op = (config->op != PM_OP_MAIN ? 0 : PM_OP_QUERY); break;
case 'R': config->op = (config->op != PM_OP_MAIN ? 0 : PM_OP_REMOVE); break;
case 'S': config->op = (config->op != PM_OP_MAIN ? 0 : PM_OP_SYNC); break;
@@ -615,9 +633,7 @@ int download_with_xfercommand(const char *url, const char *localpath,
int ret = 0;
int retval;
int usepart = 0;
- char *ptr1, *ptr2;
- char origCmd[PATH_MAX];
- char parsedCmd[PATH_MAX] = "";
+ char *parsedcmd,*tempcmd;
char cwd[PATH_MAX];
char *destfile, *tempfile, *filename;
@@ -632,28 +648,18 @@ int download_with_xfercommand(const char *url, const char *localpath,
destfile = get_destfile(localpath, filename);
tempfile = get_tempfile(localpath, filename);
- strncpy(origCmd, config->xfercommand, sizeof(origCmd));
+ tempcmd = strdup(config->xfercommand);
/* replace all occurrences of %o with fn.part */
- ptr1 = origCmd;
- while((ptr2 = strstr(ptr1, "%o"))) {
+ if(strstr(tempcmd, "%o")) {
usepart = 1;
- ptr2[0] = '\0';
- strcat(parsedCmd, ptr1);
- strcat(parsedCmd, tempfile);
- ptr1 = ptr2 + 2;
+ parsedcmd = strreplace(tempcmd, "%o", tempfile);
+ free(tempcmd);
+ tempcmd = parsedcmd;
}
- strcat(parsedCmd, ptr1);
/* replace all occurrences of %u with the download URL */
- strncpy(origCmd, parsedCmd, sizeof(origCmd));
- parsedCmd[0] = '\0';
- ptr1 = origCmd;
- while((ptr2 = strstr(ptr1, "%u"))) {
- ptr2[0] = '\0';
- strcat(parsedCmd, ptr1);
- strcat(parsedCmd, url);
- ptr1 = ptr2 + 2;
- }
- strcat(parsedCmd, ptr1);
+ parsedcmd = strreplace(tempcmd, "%u", url);
+ free(tempcmd);
+
/* cwd to the download directory */
getcwd(cwd, PATH_MAX);
if(chdir(localpath)) {
@@ -662,8 +668,8 @@ int download_with_xfercommand(const char *url, const char *localpath,
goto cleanup;
}
/* execute the parsed command via /bin/sh -c */
- pm_printf(PM_LOG_DEBUG, "running command: %s\n", parsedCmd);
- retval = system(parsedCmd);
+ pm_printf(PM_LOG_DEBUG, "running command: %s\n", parsedcmd);
+ retval = system(parsedcmd);
if(retval == -1) {
pm_printf(PM_LOG_WARNING, "running XferCommand: fork failed!\n");
@@ -689,6 +695,7 @@ cleanup:
}
free(destfile);
free(tempfile);
+ free(parsedcmd);
return(ret);
}
@@ -787,10 +794,7 @@ static int _parseconfig(const char *file, const char *givensection,
}
if(ptr == NULL && strcmp(section, "options") == 0) {
/* directives without settings, all in [options] */
- if(strcmp(key, "NoPassiveFtp") == 0) {
- alpm_option_set_nopassiveftp(1);
- pm_printf(PM_LOG_DEBUG, "config: nopassiveftp\n");
- } else if(strcmp(key, "UseSyslog") == 0) {
+ if(strcmp(key, "UseSyslog") == 0) {
alpm_option_set_usesyslog(1);
pm_printf(PM_LOG_DEBUG, "config: usesyslog\n");
} else if(strcmp(key, "ILoveCandy") == 0) {
@@ -830,6 +834,10 @@ static int _parseconfig(const char *file, const char *givensection,
setrepeatingoption(ptr, "HoldPkg", option_add_holdpkg);
} else if(strcmp(key, "SyncFirst") == 0) {
setrepeatingoption(ptr, "SyncFirst", option_add_syncfirst);
+ } else if(strcmp(key, "Architecture") == 0) {
+ if(!alpm_option_get_arch()) {
+ setarch(ptr);
+ }
} else if(strcmp(key, "DBPath") == 0) {
/* don't overwrite a path specified on the command line */
if(!config->dbpath) {
@@ -878,7 +886,23 @@ static int _parseconfig(const char *file, const char *givensection,
}
} else if(strcmp(key, "Server") == 0) {
/* let's attempt a replacement for the current repo */
- char *server = strreplace(ptr, "$repo", section);
+ char *temp = strreplace(ptr, "$repo", section);
+ /* let's attempt a replacement for the arch */
+ const char *arch = alpm_option_get_arch();
+ char *server;
+ if(arch) {
+ server = strreplace(temp, "$arch", arch);
+ free(temp);
+ } else {
+ if(strstr(temp, "$arch")) {
+ free(temp);
+ pm_printf(PM_LOG_ERROR, _("The mirror '%s' contains the $arch"
+ " variable, but no Architecture is defined.\n"), ptr);
+ ret = 1;
+ goto cleanup;
+ }
+ server = temp;
+ }
if(alpm_db_setserver(db, server) != 0) {
/* pm_errno is set by alpm_db_setserver */
@@ -923,6 +947,29 @@ static int parseconfig(const char *file)
return(_parseconfig(file, NULL, NULL));
}
+/** print commandline to logfile
+ */
+static void cl_to_log(int argc, char* argv[])
+{
+ size_t size = 0;
+ int i;
+ for(i = 0; i<argc; i++) {
+ size += strlen(argv[i]) + 1;
+ }
+ char *cl_text = malloc(size);
+ if(!cl_text)
+ return;
+ char *p = cl_text;
+ for(i = 0; i<argc-1; i++) {
+ strcpy(p, argv[i]);
+ p += strlen(argv[i]);
+ *p++ = ' ';
+ }
+ strcpy(p, argv[i]);
+ alpm_logaction("Running '%s'\n", cl_text);
+ free(cl_text);
+}
+
/** Main function.
* @param argc argc
* @param argv argv
@@ -1049,6 +1096,11 @@ int main(int argc, char *argv[])
cleanup(EXIT_FAILURE);
}
+ /* Log commandline */
+ if(needs_root()) {
+ cl_to_log(argc, argv);
+ }
+
/* start the requested operation */
switch(config->op) {
case PM_OP_REMOVE:
diff --git a/src/pacman/remove.c b/src/pacman/remove.c
index 0efbd94e..b5119fa5 100644
--- a/src/pacman/remove.c
+++ b/src/pacman/remove.c
@@ -103,6 +103,12 @@ int pacman_remove(alpm_list_t *targets)
pm_fprintf(stderr, PM_LOG_ERROR, _("failed to prepare transaction (%s)\n"),
alpm_strerrorlast());
switch(pm_errno) {
+ case PM_ERR_PKG_INVALID_ARCH:
+ for(i = data; i; i = alpm_list_next(i)) {
+ char *pkg = alpm_list_getdata(i);
+ printf(_(":: package %s does not have a valid architecture\n"), pkg);
+ }
+ break;
case PM_ERR_UNSATISFIED_DEPS:
for(i = data; i; i = alpm_list_next(i)) {
pmdepmissing_t *miss = alpm_list_getdata(i);
diff --git a/src/pacman/sync.c b/src/pacman/sync.c
index dc936219..4f101f99 100644
--- a/src/pacman/sync.c
+++ b/src/pacman/sync.c
@@ -639,6 +639,12 @@ static int sync_trans(alpm_list_t *targets)
alpm_strerrorlast());
switch(pm_errno) {
alpm_list_t *i;
+ case PM_ERR_PKG_INVALID_ARCH:
+ for(i = data; i; i = alpm_list_next(i)) {
+ char *pkg = alpm_list_getdata(i);
+ printf(_(":: package %s does not have a valid architecture\n"), pkg);
+ }
+ break;
case PM_ERR_UNSATISFIED_DEPS:
for(i = data; i; i = alpm_list_next(i)) {
pmdepmissing_t *miss = alpm_list_getdata(i);
diff --git a/src/pacman/upgrade.c b/src/pacman/upgrade.c
index 1570f95e..e7691185 100644
--- a/src/pacman/upgrade.c
+++ b/src/pacman/upgrade.c
@@ -87,6 +87,12 @@ int pacman_upgrade(alpm_list_t *targets)
pm_fprintf(stderr, PM_LOG_ERROR, _("failed to prepare transaction (%s)\n"),
alpm_strerrorlast());
switch(pm_errno) {
+ case PM_ERR_PKG_INVALID_ARCH:
+ for(i = data; i; i = alpm_list_next(i)) {
+ char *pkg = alpm_list_getdata(i);
+ printf(_(":: package %s does not have a valid architecture\n"), pkg);
+ }
+ break;
case PM_ERR_UNSATISFIED_DEPS:
for(i = data; i; i = alpm_list_next(i)) {
pmdepmissing_t *miss = alpm_list_getdata(i);
diff --git a/src/pacman/util.c b/src/pacman/util.c
index a02b43cd..1e8515c6 100644
--- a/src/pacman/util.c
+++ b/src/pacman/util.c
@@ -85,34 +85,18 @@ int needs_root(void)
/* gets the current screen column width */
int getcols(void)
{
- if(!isatty(1)) {
- /* We will default to 80 columns if we're not a tty
- * this seems a fairly standard file width.
- */
- return 80;
- } else {
#ifdef TIOCGSIZE
- struct ttysize win;
- if(ioctl(1, TIOCGSIZE, &win) == 0) {
- return win.ts_cols;
- }
-#elif defined(TIOCGWINSZ)
- struct winsize win;
- if(ioctl(1, TIOCGWINSZ, &win) == 0) {
- return win.ws_col;
- }
-#endif
- /* If we can't figure anything out, we'll just assume 80 columns */
- /* TODO any problems caused by this assumption? */
- return 80;
+ struct ttysize win;
+ if(ioctl(1, TIOCGSIZE, &win) == 0) {
+ return win.ts_cols;
}
- /* Original envvar way - prone to display issues
- const char *cenv = getenv("COLUMNS");
- if(cenv != NULL) {
- return atoi(cenv);
+#elif defined(TIOCGWINSZ)
+ struct winsize win;
+ if(ioctl(1, TIOCGWINSZ, &win) == 0) {
+ return win.ws_col;
}
- return -1;
- */
+#endif
+ return 0;
}
/* does the same thing as 'mkdir -p' */
@@ -256,6 +240,14 @@ void indentprint(const char *str, int indent)
return;
}
+ cols = getcols();
+
+ /* if we're not a tty, print without indenting */
+ if(cols == 0) {
+ printf("%s", str);
+ return;
+ }
+
len = strlen(str) + 1;
wcstr = calloc(len, sizeof(wchar_t));
len = mbstowcs(wcstr, str, len);
@@ -265,7 +257,6 @@ void indentprint(const char *str, int indent)
if(!p) {
return;
}
- cols = getcols();
while(*p) {
if(*p == L' ') {
@@ -284,7 +275,7 @@ void indentprint(const char *str, int indent)
}
if(len > (cols - cidx - 1)) {
/* wrap to a newline and reindent */
- fprintf(stdout, "\n%-*s", indent, "");
+ printf("\n%-*s", indent, "");
cidx = indent;
} else {
printf(" ");
@@ -292,7 +283,7 @@ void indentprint(const char *str, int indent)
}
continue;
}
- fprintf(stdout, "%lc", (wint_t)*p);
+ printf("%lc", (wint_t)*p);
cidx += wcwidth(*p);
p++;
}
@@ -344,48 +335,65 @@ char *strtrim(char *str)
return(str);
}
-/* Helper function for strreplace */
-static void _strnadd(char **str, const char *append, unsigned int count)
-{
- if(*str) {
- *str = realloc(*str, strlen(*str) + count + 1);
- } else {
- *str = calloc(sizeof(char), count + 1);
- }
-
- strncat(*str, append, count);
-}
-
/* Replace all occurances of 'needle' with 'replace' in 'str', returning
* a new string (must be free'd) */
char *strreplace(const char *str, const char *needle, const char *replace)
{
- const char *p, *q;
- p = q = str;
+ const char *p = NULL, *q = NULL;
+ char *newstr = NULL, *newp = NULL;
+ alpm_list_t *i = NULL, *list = NULL;
+ size_t needlesz = strlen(needle), replacesz = strlen(replace);
+ size_t newsz;
- char *newstr = NULL;
- unsigned int needlesz = strlen(needle),
- replacesz = strlen(replace);
+ if(!str) {
+ return(NULL);
+ }
- while (1) {
+ p = str;
+ q = strstr(p, needle);
+ while(q) {
+ list = alpm_list_add(list, (char *)q);
+ p = q + needlesz;
q = strstr(p, needle);
- if(!q) { /* not found */
- if(*p) {
- /* add the rest of 'p' */
- _strnadd(&newstr, p, strlen(p));
- }
- break;
- } else { /* found match */
- if(q > p){
- /* add chars between this occurance and last occurance, if any */
- _strnadd(&newstr, p, q - p);
- }
- _strnadd(&newstr, replace, replacesz);
- p = q + needlesz;
+ }
+
+ /* no occurences of needle found */
+ if(!list) {
+ return(strdup(str));
+ }
+ /* size of new string = size of old string + "number of occurences of needle"
+ * x "size difference between replace and needle" */
+ newsz = strlen(str) + 1 +
+ alpm_list_count(list) * (replacesz - needlesz);
+ newstr = malloc(newsz);
+ if(!newstr) {
+ return(NULL);
+ }
+ *newstr = '\0';
+
+ p = str;
+ newp = newstr;
+ for(i = list; i; i = alpm_list_next(i)) {
+ q = alpm_list_getdata(i);
+ if(q > p){
+ /* add chars between this occurence and last occurence, if any */
+ strncpy(newp, p, q - p);
+ newp += q - p;
}
+ strncpy(newp, replace, replacesz);
+ newp += replacesz;
+ p = q + needlesz;
+ }
+ alpm_list_free(list);
+
+ if(*p) {
+ /* add the rest of 'p' */
+ strcpy(newp, p);
+ newp += strlen(p);
}
+ *newp = '\0';
- return newstr;
+ return(newstr);
}
/** Splits a string into a list of strings using the chosen character as
@@ -476,7 +484,7 @@ void list_display(const char *title, const alpm_list_t *list)
/* two additional spaces are added to the length */
s += 2;
int maxcols = getcols();
- if(s + cols > maxcols) {
+ if(s + cols > maxcols && maxcols > 0) {
int j;
cols = len;
printf("\n");