Send patches - preferably formatted by git format-patch - to patches at archlinux32 dot org.
summaryrefslogtreecommitdiff
path: root/src/pacman/util.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/pacman/util.c')
-rw-r--r--src/pacman/util.c131
1 files changed, 87 insertions, 44 deletions
diff --git a/src/pacman/util.c b/src/pacman/util.c
index 0facfdd1..d7ac9e38 100644
--- a/src/pacman/util.c
+++ b/src/pacman/util.c
@@ -22,7 +22,6 @@
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/time.h>
-#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
@@ -42,6 +41,33 @@
/* pacman */
#include "util.h"
#include "conf.h"
+#include "callback.h"
+
+
+int trans_init(pmtranstype_t type, pmtransflag_t flags)
+{
+ if(alpm_trans_init(type, flags, cb_trans_evt,
+ cb_trans_conv, cb_trans_progress) == -1) {
+ pm_fprintf(stderr, PM_LOG_ERROR, _("failed to init transaction (%s)\n"),
+ alpm_strerrorlast());
+ if(pm_errno == PM_ERR_HANDLE_LOCK) {
+ fprintf(stderr, _(" if you're sure a package manager is not already\n"
+ " running, you can remove %s\n"), alpm_option_get_lockfile());
+ }
+ return(-1);
+ }
+ return(0);
+}
+
+int trans_release()
+{
+ if(alpm_trans_release() == -1) {
+ pm_fprintf(stderr, PM_LOG_ERROR, _("failed to release transaction (%s)\n"),
+ alpm_strerrorlast());
+ return(-1);
+ }
+ return(0);
+}
int needs_transaction()
{
@@ -94,33 +120,37 @@ int getcols()
/* does the same thing as 'mkdir -p' */
int makepath(const char *path)
{
- char *orig, *str, *ptr;
- char full[PATH_MAX+1] = "";
- mode_t oldmask;
-
- oldmask = umask(0000);
+ /* A bit of pointer hell here. Descriptions:
+ * orig - a copy of path so we can safely butcher it with strsep
+ * str - the current position in the path string (after the delimiter)
+ * ptr - the original position of str after calling strsep
+ * incr - incrementally generated path for use in access/mkdir call
+ */
+ char *orig, *str, *ptr, *incr;
+ mode_t oldmask = umask(0000);
+ int ret = 0;
orig = strdup(path);
+ incr = calloc(strlen(orig) + 1, sizeof(char));
str = orig;
while((ptr = strsep(&str, "/"))) {
if(strlen(ptr)) {
- struct stat buf;
-
- /* TODO we should use strncat */
- strcat(full, "/");
- strcat(full, ptr);
- if(stat(full, &buf)) {
- if(mkdir(full, 0755)) {
- free(orig);
- umask(oldmask);
- return(1);
+ /* we have another path component- append the newest component to
+ * existing string and create one more level of dir structure */
+ strcat(incr, "/");
+ strcat(incr, ptr);
+ if(access(incr, F_OK)) {
+ if(mkdir(incr, 0755)) {
+ ret = 1;
+ break;
}
}
}
}
free(orig);
+ free(incr);
umask(oldmask);
- return(0);
+ return(ret);
}
/* does the same thing as 'rm -rf' */
@@ -234,6 +264,10 @@ void indentprint(const char *str, int indent)
p = wcstr;
cidx = indent;
+ if(!p) {
+ return;
+ }
+
while(*p) {
if(*p == L' ') {
const wchar_t *q, *next;
@@ -457,32 +491,29 @@ void display_targets(const alpm_list_t *syncpkgs, pmdb_t *db_local)
const alpm_list_t *i, *j;
alpm_list_t *targets = NULL, *to_remove = NULL;
/* TODO these are some messy variable names */
- unsigned long isize = 0, rsize = 0, dispsize = 0, dlsize = 0;
+ off_t isize = 0, rsize = 0, dispsize = 0, dlsize = 0;
double mbisize = 0.0, mbrsize = 0.0, mbdispsize = 0.0, mbdlsize = 0.0;
for(i = syncpkgs; i; i = alpm_list_next(i)) {
pmsyncpkg_t *sync = alpm_list_getdata(i);
pmpkg_t *pkg = alpm_sync_get_pkg(sync);
- /* If this sync record is a replacement, the data member contains
- * a list of packages to be removed due to the package that is being
- * installed. */
- if(alpm_sync_get_type(sync) == PM_SYNC_TYPE_REPLACE) {
- alpm_list_t *to_replace = alpm_sync_get_data(sync);
+ /* The removes member contains a list of packages to be removed
+ * due to the package that is being installed. */
+ alpm_list_t *to_replace = alpm_sync_get_removes(sync);
- for(j = to_replace; j; j = alpm_list_next(j)) {
- pmpkg_t *rp = alpm_list_getdata(j);
- const char *name = alpm_pkg_get_name(rp);
+ for(j = to_replace; j; j = alpm_list_next(j)) {
+ pmpkg_t *rp = alpm_list_getdata(j);
+ const char *name = alpm_pkg_get_name(rp);
- if(!alpm_list_find_str(to_remove, name)) {
- rsize += alpm_pkg_get_isize(rp);
- to_remove = alpm_list_add(to_remove, strdup(name));
- }
+ if(!alpm_list_find_str(to_remove, name)) {
+ rsize += alpm_pkg_get_isize(rp);
+ to_remove = alpm_list_add(to_remove, strdup(name));
}
}
dispsize = alpm_pkg_get_size(pkg);
- dlsize += alpm_pkg_download_size(pkg, db_local);
+ dlsize += alpm_pkg_download_size(pkg);
isize += alpm_pkg_get_isize(pkg);
/* print the package size with the output if ShowSize option set */
@@ -520,38 +551,50 @@ void display_targets(const alpm_list_t *syncpkgs, pmdb_t *db_local)
printf("\n");
printf(_("Total Download Size: %.2f MB\n"), mbdlsize);
-
- /* TODO because all pkgs don't include isize, this is a crude hack */
- if(mbisize > mbdlsize) {
- printf(_("Total Installed Size: %.2f MB\n"), mbisize);
- }
+ printf(_("Total Installed Size: %.2f MB\n"), mbisize);
FREELIST(targets);
}
/* presents a prompt and gets a Y/N answer */
-/* TODO there must be a better way */
-int yesno(char *fmt, ...)
+int yesno(short preset, char *fmt, ...)
{
char response[32];
va_list args;
+ FILE *stream;
if(config->noconfirm) {
- return(1);
+ stream = stdout;
+ } else {
+ /* Use stderr so questions are always displayed when redirecting output */
+ stream = stderr;
}
va_start(args, fmt);
- /* Use stderr so questions are always displayed when redirecting output */
- vfprintf(stderr, fmt, args);
+ vfprintf(stream, fmt, args);
va_end(args);
+ if(preset) {
+ fprintf(stream, " %s ", _("[Y/n]"));
+ } else {
+ fprintf(stream, " %s ", _("[y/N]"));
+ }
+
+ if(config->noconfirm) {
+ fprintf(stream, "\n");
+ return(preset);
+ }
+
if(fgets(response, 32, stdin)) {
- if(strlen(response) != 0) {
- strtrim(response);
+ strtrim(response);
+ if(strlen(response) == 0) {
+ return(preset);
}
- if(!strcasecmp(response, _("Y")) || !strcasecmp(response, _("YES")) || strlen(response) == 0) {
+ if(!strcasecmp(response, _("Y")) || !strcasecmp(response, _("YES"))) {
return(1);
+ } else if (!strcasecmp(response, _("N")) || !strcasecmp(response, _("NO"))) {
+ return(0);
}
}
return(0);