2005-03-19 04:00:40 -05:00
|
|
|
/*
|
2007-04-25 20:02:07 -04:00
|
|
|
* callback.c
|
|
|
|
*
|
|
|
|
* Copyright (c) 2002-2007 by Judd Vinet <jvinet@zeroflux.org>
|
|
|
|
*
|
2005-03-19 04:00:40 -05:00
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
2007-12-10 23:55:22 -05:00
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
2005-03-19 04:00:40 -05:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include "config.h"
|
2007-03-05 17:13:33 -05:00
|
|
|
|
2005-03-19 04:00:40 -05:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
2007-04-25 20:02:07 -04:00
|
|
|
#include <sys/time.h>
|
2005-03-19 04:00:40 -05:00
|
|
|
#include <unistd.h>
|
|
|
|
#include <dirent.h>
|
2007-03-03 04:43:16 -05:00
|
|
|
#include <wchar.h>
|
2005-03-19 04:00:40 -05:00
|
|
|
|
|
|
|
#include <alpm.h>
|
2007-03-05 17:13:33 -05:00
|
|
|
|
2005-03-19 04:00:40 -05:00
|
|
|
/* pacman */
|
2007-04-25 20:02:07 -04:00
|
|
|
#include "callback.h"
|
2005-10-10 16:42:48 -04:00
|
|
|
#include "util.h"
|
2006-02-22 15:39:24 -05:00
|
|
|
#include "conf.h"
|
2005-03-19 04:00:40 -05:00
|
|
|
|
2007-04-25 17:24:23 -04:00
|
|
|
/* TODO this should not have to be defined twice- trans.c & log.c */
|
2005-04-02 15:31:40 -05:00
|
|
|
#define LOG_STR_LEN 256
|
2007-04-25 20:02:07 -04:00
|
|
|
#define FILENAME_TRIM_LEN 23
|
2005-04-02 15:31:40 -05:00
|
|
|
|
2007-04-25 20:02:07 -04:00
|
|
|
/* download progress bar */
|
|
|
|
static float rate_last;
|
|
|
|
static int xfered_last;
|
|
|
|
static struct timeval initial_time;
|
|
|
|
|
2007-12-03 16:57:54 -05:00
|
|
|
/* transaction progress bar */
|
|
|
|
static int prevpercent = 0; /* for less progressbar output */
|
|
|
|
|
|
|
|
/* delayed output during progress bar */
|
|
|
|
static int on_progress = 0;
|
|
|
|
static alpm_list_t *output = NULL;
|
2006-02-22 15:39:24 -05:00
|
|
|
|
2007-04-26 19:03:24 -04:00
|
|
|
/* Silly little helper function, determines if the caller needs a visual update
|
|
|
|
* since the last time this function was called.
|
|
|
|
* This is made for the two progress bar functions, to prevent flicker
|
|
|
|
*
|
|
|
|
* first_call indicates if this is the first time it is called, for
|
|
|
|
* initialization purposes */
|
|
|
|
static float get_update_timediff(int first_call)
|
|
|
|
{
|
|
|
|
float retval = 0.0;
|
2007-08-16 16:19:06 -04:00
|
|
|
static struct timeval last_time = {0, 0};
|
2007-04-26 19:03:24 -04:00
|
|
|
|
|
|
|
/* on first call, simply set the last time and return */
|
|
|
|
if(first_call) {
|
|
|
|
gettimeofday(&last_time, NULL);
|
|
|
|
} else {
|
|
|
|
struct timeval this_time;
|
|
|
|
float diff_sec, diff_usec;
|
|
|
|
|
|
|
|
gettimeofday(&this_time, NULL);
|
|
|
|
diff_sec = this_time.tv_sec - last_time.tv_sec;
|
|
|
|
diff_usec = this_time.tv_usec - last_time.tv_usec;
|
|
|
|
|
|
|
|
retval = diff_sec + (diff_usec / 1000000.0);
|
|
|
|
|
|
|
|
/* return 0 and do not update last_time if interval was too short */
|
|
|
|
if(retval < UPDATE_SPEED_SEC) {
|
|
|
|
retval = 0.0;
|
|
|
|
} else {
|
|
|
|
last_time = this_time;
|
|
|
|
/* printf("\nupdate retval: %f\n", retval); DEBUG*/
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return(retval);
|
|
|
|
}
|
|
|
|
|
2007-04-25 20:02:07 -04:00
|
|
|
/* refactored from cb_trans_progress */
|
2007-11-09 19:54:19 -05:00
|
|
|
static void fill_progress(const int graph_percent, const int display_percent,
|
|
|
|
const int proglen)
|
2007-04-25 20:02:07 -04:00
|
|
|
{
|
|
|
|
const unsigned int hashlen = proglen - 8;
|
2007-11-09 19:54:19 -05:00
|
|
|
const unsigned int hash = graph_percent * hashlen / 100;
|
2007-04-25 20:02:07 -04:00
|
|
|
static unsigned int lasthash = 0, mouth = 0;
|
|
|
|
unsigned int i;
|
|
|
|
|
|
|
|
/* printf("\ndebug: proglen: %i\n", proglen); DEBUG*/
|
|
|
|
|
2007-11-09 19:54:19 -05:00
|
|
|
if(graph_percent == 0) {
|
2007-04-25 20:02:07 -04:00
|
|
|
lasthash = 0;
|
|
|
|
mouth = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* magic numbers, how I loathe thee */
|
|
|
|
if(proglen > 8) {
|
|
|
|
printf(" [");
|
|
|
|
for(i = hashlen; i > 1; --i) {
|
|
|
|
/* if special progress bar enabled */
|
2007-06-04 12:51:23 -04:00
|
|
|
if(config->chomp) {
|
2007-04-25 20:02:07 -04:00
|
|
|
if(i > hashlen - hash) {
|
|
|
|
printf("-");
|
|
|
|
} else if(i == hashlen - hash) {
|
|
|
|
if(lasthash == hash) {
|
|
|
|
if(mouth) {
|
|
|
|
printf("\033[1;33mC\033[m");
|
|
|
|
} else {
|
|
|
|
printf("\033[1;33mc\033[m");
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
lasthash = hash;
|
|
|
|
mouth = mouth == 1 ? 0 : 1;
|
|
|
|
if(mouth) {
|
|
|
|
printf("\033[1;33mC\033[m");
|
|
|
|
} else {
|
|
|
|
printf("\033[1;33mc\033[m");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if(i%3 == 0) {
|
|
|
|
printf("\033[0;37mo\033[m");
|
|
|
|
} else {
|
|
|
|
printf("\033[0;37m \033[m");
|
|
|
|
}
|
|
|
|
} /* else regular progress bar */
|
|
|
|
else if(i > hashlen - hash) {
|
|
|
|
printf("#");
|
|
|
|
} else {
|
|
|
|
printf("-");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
printf("]");
|
|
|
|
}
|
|
|
|
/* print percent after progress bar */
|
|
|
|
if(proglen > 5) {
|
2007-11-09 19:54:19 -05:00
|
|
|
printf(" %3d%%", display_percent);
|
2007-04-25 20:02:07 -04:00
|
|
|
}
|
|
|
|
|
2007-11-09 19:54:19 -05:00
|
|
|
if(graph_percent == 100) {
|
2007-04-25 20:02:07 -04:00
|
|
|
printf("\n");
|
|
|
|
} else {
|
|
|
|
printf("\r");
|
|
|
|
}
|
|
|
|
fflush(stdout);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* callback to handle messages/notifications from libalpm transactions */
|
2007-01-23 22:02:53 -05:00
|
|
|
void cb_trans_evt(pmtransevt_t event, void *data1, void *data2)
|
2005-03-19 04:00:40 -05:00
|
|
|
{
|
2005-04-02 15:31:40 -05:00
|
|
|
char str[LOG_STR_LEN] = "";
|
2005-03-19 04:00:40 -05:00
|
|
|
|
|
|
|
switch(event) {
|
2005-04-02 15:31:40 -05:00
|
|
|
case PM_TRANS_EVT_CHECKDEPS_START:
|
2007-12-02 14:48:49 -05:00
|
|
|
printf(_("checking dependencies...\n"));
|
2007-01-23 22:02:53 -05:00
|
|
|
break;
|
2005-04-02 15:31:40 -05:00
|
|
|
case PM_TRANS_EVT_FILECONFLICTS_START:
|
2006-10-15 19:54:43 -04:00
|
|
|
if(config->noprogressbar) {
|
2007-12-02 14:48:49 -05:00
|
|
|
printf(_("checking for file conflicts...\n"));
|
2006-10-15 19:54:43 -04:00
|
|
|
}
|
2007-01-23 22:02:53 -05:00
|
|
|
break;
|
2005-04-02 15:31:40 -05:00
|
|
|
case PM_TRANS_EVT_RESOLVEDEPS_START:
|
2007-12-02 14:48:49 -05:00
|
|
|
printf(_("resolving dependencies...\n"));
|
2007-01-23 22:02:53 -05:00
|
|
|
break;
|
2005-04-13 15:59:04 -04:00
|
|
|
case PM_TRANS_EVT_INTERCONFLICTS_START:
|
2007-12-02 14:48:49 -05:00
|
|
|
printf(_("looking for inter-conflicts...\n"));
|
2007-01-23 22:02:53 -05:00
|
|
|
break;
|
2005-03-19 04:00:40 -05:00
|
|
|
case PM_TRANS_EVT_ADD_START:
|
2006-10-15 15:34:52 -04:00
|
|
|
if(config->noprogressbar) {
|
2007-12-02 14:48:49 -05:00
|
|
|
printf(_("installing %s...\n"), alpm_pkg_get_name(data1));
|
2006-10-15 15:34:52 -04:00
|
|
|
}
|
2007-01-23 22:02:53 -05:00
|
|
|
break;
|
2005-03-19 04:00:40 -05:00
|
|
|
case PM_TRANS_EVT_ADD_DONE:
|
2007-11-04 14:53:34 -05:00
|
|
|
snprintf(str, LOG_STR_LEN, "installed %s (%s)\n",
|
2006-11-20 04:10:23 -05:00
|
|
|
alpm_pkg_get_name(data1),
|
|
|
|
alpm_pkg_get_version(data1));
|
2005-03-19 04:00:40 -05:00
|
|
|
alpm_logaction(str);
|
2007-01-23 22:02:53 -05:00
|
|
|
break;
|
2005-03-19 04:00:40 -05:00
|
|
|
case PM_TRANS_EVT_REMOVE_START:
|
2006-10-15 15:34:52 -04:00
|
|
|
if(config->noprogressbar) {
|
2007-12-02 14:48:49 -05:00
|
|
|
printf(_("removing %s...\n"), alpm_pkg_get_name(data1));
|
2006-10-15 15:34:52 -04:00
|
|
|
}
|
2007-01-23 22:02:53 -05:00
|
|
|
break;
|
2005-03-19 04:00:40 -05:00
|
|
|
case PM_TRANS_EVT_REMOVE_DONE:
|
2007-11-04 14:53:34 -05:00
|
|
|
snprintf(str, LOG_STR_LEN, "removed %s (%s)\n",
|
2006-11-20 04:10:23 -05:00
|
|
|
alpm_pkg_get_name(data1),
|
|
|
|
alpm_pkg_get_version(data1));
|
2005-03-19 04:00:40 -05:00
|
|
|
alpm_logaction(str);
|
2007-01-23 22:02:53 -05:00
|
|
|
break;
|
2005-03-19 04:00:40 -05:00
|
|
|
case PM_TRANS_EVT_UPGRADE_START:
|
2006-10-15 15:34:52 -04:00
|
|
|
if(config->noprogressbar) {
|
2007-12-02 14:48:49 -05:00
|
|
|
printf(_("upgrading %s...\n"), alpm_pkg_get_name(data1));
|
2006-10-15 15:34:52 -04:00
|
|
|
}
|
2007-01-23 22:02:53 -05:00
|
|
|
break;
|
2005-03-19 04:00:40 -05:00
|
|
|
case PM_TRANS_EVT_UPGRADE_DONE:
|
2007-11-04 14:53:34 -05:00
|
|
|
snprintf(str, LOG_STR_LEN, "upgraded %s (%s -> %s)\n",
|
2006-11-20 04:10:23 -05:00
|
|
|
(char *)alpm_pkg_get_name(data1),
|
|
|
|
(char *)alpm_pkg_get_version(data2),
|
|
|
|
(char *)alpm_pkg_get_version(data1));
|
2005-03-19 04:00:40 -05:00
|
|
|
alpm_logaction(str);
|
2007-01-23 22:02:53 -05:00
|
|
|
break;
|
2006-10-15 15:34:52 -04:00
|
|
|
case PM_TRANS_EVT_INTEGRITY_START:
|
2007-12-02 14:48:49 -05:00
|
|
|
printf(_("checking package integrity...\n"));
|
2007-01-23 22:02:53 -05:00
|
|
|
break;
|
2007-10-19 13:17:53 -04:00
|
|
|
case PM_TRANS_EVT_DELTA_INTEGRITY_START:
|
2007-12-02 14:48:49 -05:00
|
|
|
printf(_("checking delta integrity...\n"));
|
2007-10-19 13:17:53 -04:00
|
|
|
break;
|
|
|
|
case PM_TRANS_EVT_DELTA_PATCHES_START:
|
|
|
|
printf(_("applying deltas...\n"));
|
|
|
|
break;
|
|
|
|
case PM_TRANS_EVT_DELTA_PATCH_START:
|
|
|
|
printf(_("generating %s with %s... "), (char *)data1, (char *)data2);
|
|
|
|
break;
|
2007-12-02 14:48:49 -05:00
|
|
|
case PM_TRANS_EVT_DELTA_PATCH_DONE:
|
|
|
|
printf(_("success!\n"));
|
|
|
|
break;
|
2007-10-19 13:17:53 -04:00
|
|
|
case PM_TRANS_EVT_DELTA_PATCH_FAILED:
|
|
|
|
printf(_("failed.\n"));
|
|
|
|
break;
|
2007-11-04 10:47:21 -05:00
|
|
|
case PM_TRANS_EVT_SCRIPTLET_INFO:
|
|
|
|
printf("%s", (char*)data1);
|
|
|
|
break;
|
2006-10-15 15:34:52 -04:00
|
|
|
case PM_TRANS_EVT_PRINTURI:
|
2007-04-26 15:28:54 -04:00
|
|
|
printf("%s/%s\n", (char*)data1, (char*)data2);
|
2007-01-23 22:02:53 -05:00
|
|
|
break;
|
2006-10-15 15:34:52 -04:00
|
|
|
case PM_TRANS_EVT_RETRIEVE_START:
|
2007-04-26 15:28:54 -04:00
|
|
|
printf(_(":: Retrieving packages from %s...\n"), (char*)data1);
|
2007-11-09 00:41:05 -05:00
|
|
|
break;
|
|
|
|
/* all the simple done events, with fallthrough for each */
|
2007-12-02 14:48:49 -05:00
|
|
|
case PM_TRANS_EVT_FILECONFLICTS_DONE:
|
|
|
|
case PM_TRANS_EVT_EXTRACT_DONE:
|
2007-11-09 00:41:05 -05:00
|
|
|
case PM_TRANS_EVT_CHECKDEPS_DONE:
|
|
|
|
case PM_TRANS_EVT_RESOLVEDEPS_DONE:
|
|
|
|
case PM_TRANS_EVT_INTERCONFLICTS_DONE:
|
|
|
|
case PM_TRANS_EVT_INTEGRITY_DONE:
|
|
|
|
case PM_TRANS_EVT_DELTA_INTEGRITY_DONE:
|
2007-12-02 14:48:49 -05:00
|
|
|
case PM_TRANS_EVT_DELTA_PATCHES_DONE:
|
|
|
|
/* nothing */
|
2007-01-23 22:02:53 -05:00
|
|
|
break;
|
2005-03-19 04:00:40 -05:00
|
|
|
}
|
2007-11-09 00:41:05 -05:00
|
|
|
fflush(stdout);
|
2005-03-19 04:00:40 -05:00
|
|
|
}
|
|
|
|
|
2007-04-25 20:02:07 -04:00
|
|
|
/* callback to handle questions from libalpm transactions (yes/no) */
|
2007-04-26 16:59:38 -04:00
|
|
|
/* TODO this is one of the worst ever functions written. void *data ? wtf */
|
2007-01-23 22:02:53 -05:00
|
|
|
void cb_trans_conv(pmtransconv_t event, void *data1, void *data2,
|
|
|
|
void *data3, int *response)
|
2005-10-09 02:09:57 -04:00
|
|
|
{
|
|
|
|
char str[LOG_STR_LEN] = "";
|
|
|
|
|
|
|
|
switch(event) {
|
|
|
|
case PM_TRANS_CONV_INSTALL_IGNOREPKG:
|
2007-08-20 16:34:43 -04:00
|
|
|
if(data2) {
|
2007-03-06 10:00:26 -05:00
|
|
|
/* TODO we take this route based on data2 being not null? WTF */
|
2007-11-09 20:13:29 -05:00
|
|
|
snprintf(str, LOG_STR_LEN, _(":: %s requires installing %s from IgnorePkg/IgnoreGroup. Install anyway? [Y/n] "),
|
2007-08-20 16:34:43 -04:00
|
|
|
alpm_pkg_get_name(data1),
|
|
|
|
alpm_pkg_get_name(data2));
|
2006-10-15 15:34:52 -04:00
|
|
|
*response = yesno(str);
|
2007-02-22 21:10:56 -05:00
|
|
|
} else {
|
2007-11-09 20:13:29 -05:00
|
|
|
snprintf(str, LOG_STR_LEN, _(":: %s is in IgnorePkg/IgnoreGroup. Install anyway? [Y/n] "),
|
2007-08-20 16:34:43 -04:00
|
|
|
alpm_pkg_get_name(data1));
|
2007-02-22 21:10:56 -05:00
|
|
|
*response = yesno(str);
|
2006-10-15 15:34:52 -04:00
|
|
|
}
|
2007-01-23 22:02:53 -05:00
|
|
|
break;
|
2006-10-15 15:34:52 -04:00
|
|
|
case PM_TRANS_CONV_REMOVE_HOLDPKG:
|
2007-08-20 16:34:43 -04:00
|
|
|
snprintf(str, LOG_STR_LEN, _(":: %s is designated as a HoldPkg. Remove anyway? [Y/n] "),
|
|
|
|
alpm_pkg_get_name(data1));
|
|
|
|
*response = yesno(str);
|
2007-01-23 22:02:53 -05:00
|
|
|
break;
|
2005-10-09 02:09:57 -04:00
|
|
|
case PM_TRANS_CONV_REPLACE_PKG:
|
2008-01-01 02:01:52 -05:00
|
|
|
if(!config->noconfirm) {
|
|
|
|
snprintf(str, LOG_STR_LEN, _(":: Replace %s with %s/%s? [Y/n] "),
|
|
|
|
alpm_pkg_get_name(data1),
|
|
|
|
(char *)data3,
|
|
|
|
alpm_pkg_get_name(data2));
|
|
|
|
*response = yesno(str);
|
|
|
|
} else {
|
2008-01-20 08:11:25 -05:00
|
|
|
printf(_("Replacing %s with %s/%s\n"),
|
2008-01-01 02:01:52 -05:00
|
|
|
alpm_pkg_get_name(data1),
|
|
|
|
(char *)data3,
|
|
|
|
alpm_pkg_get_name(data2));
|
|
|
|
*response = 1;
|
|
|
|
}
|
2007-01-23 22:02:53 -05:00
|
|
|
break;
|
2005-12-26 01:40:29 -05:00
|
|
|
case PM_TRANS_CONV_CONFLICT_PKG:
|
2007-08-20 16:34:43 -04:00
|
|
|
snprintf(str, LOG_STR_LEN, _(":: %s conflicts with %s. Remove %s? [Y/n] "),
|
|
|
|
(char *)data1,
|
|
|
|
(char *)data2,
|
|
|
|
(char *)data2);
|
|
|
|
*response = yesno(str);
|
2007-01-23 22:02:53 -05:00
|
|
|
break;
|
2005-10-09 02:09:57 -04:00
|
|
|
case PM_TRANS_CONV_LOCAL_NEWER:
|
2007-08-20 16:34:43 -04:00
|
|
|
if(!config->op_s_downloadonly) {
|
|
|
|
snprintf(str, LOG_STR_LEN, _(":: %s-%s: local version is newer. Upgrade anyway? [Y/n] "),
|
|
|
|
alpm_pkg_get_name(data1),
|
|
|
|
alpm_pkg_get_version(data1));
|
|
|
|
*response = yesno(str);
|
2006-10-15 15:34:52 -04:00
|
|
|
} else {
|
2007-08-20 16:34:43 -04:00
|
|
|
*response = 1;
|
2006-10-15 15:34:52 -04:00
|
|
|
}
|
2007-01-23 22:02:53 -05:00
|
|
|
break;
|
2006-10-15 15:34:52 -04:00
|
|
|
case PM_TRANS_CONV_CORRUPTED_PKG:
|
2007-08-20 16:34:43 -04:00
|
|
|
if(!config->noconfirm) {
|
2007-10-19 13:17:53 -04:00
|
|
|
snprintf(str, LOG_STR_LEN, _(":: File %s is corrupted. Do you want to delete it? [Y/n] "),
|
2007-08-20 16:34:43 -04:00
|
|
|
(char *)data1);
|
|
|
|
*response = yesno(str);
|
2006-02-22 15:39:24 -05:00
|
|
|
} else {
|
2007-08-20 16:34:43 -04:00
|
|
|
*response = 1;
|
2006-02-22 15:39:24 -05:00
|
|
|
}
|
2007-01-23 22:02:53 -05:00
|
|
|
break;
|
2005-10-09 02:09:57 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-04-25 20:02:07 -04:00
|
|
|
/* callback to handle display of transaction progress */
|
2007-03-03 03:13:59 -05:00
|
|
|
void cb_trans_progress(pmtransprog_t event, const char *pkgname, int percent,
|
|
|
|
int howmany, int remain)
|
2006-10-15 15:34:52 -04:00
|
|
|
{
|
2007-02-03 20:36:45 -05:00
|
|
|
float timediff;
|
|
|
|
|
2007-01-30 20:37:41 -05:00
|
|
|
/* size of line to allocate for text printing (e.g. not progressbar) */
|
|
|
|
const int infolen = 50;
|
2007-03-03 04:43:16 -05:00
|
|
|
int tmp, digits, oprlen, textlen, pkglen;
|
2007-02-14 14:35:41 -05:00
|
|
|
char *opr = NULL;
|
2007-03-03 04:43:16 -05:00
|
|
|
wchar_t *wcopr = NULL;
|
2006-10-15 15:34:52 -04:00
|
|
|
|
|
|
|
if(config->noprogressbar) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2006-12-22 02:11:20 -05:00
|
|
|
if(percent == 0) {
|
2007-02-03 20:36:45 -05:00
|
|
|
timediff = get_update_timediff(1);
|
|
|
|
} else {
|
|
|
|
timediff = get_update_timediff(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
if(percent > 0 && percent < 100 && !timediff) {
|
|
|
|
/* only update the progress bar when
|
|
|
|
* a) we first start
|
|
|
|
* b) we end the progress
|
|
|
|
* c) it has been long enough since the last call
|
|
|
|
*/
|
|
|
|
return;
|
2006-12-22 02:11:20 -05:00
|
|
|
}
|
|
|
|
|
2007-01-30 20:37:41 -05:00
|
|
|
/* if no pkgname, percent is too high or unchanged, then return */
|
2007-02-03 20:36:45 -05:00
|
|
|
if(!pkgname || percent == prevpercent) {
|
2006-10-15 15:34:52 -04:00
|
|
|
return;
|
2007-01-30 20:37:41 -05:00
|
|
|
}
|
2006-10-15 15:34:52 -04:00
|
|
|
|
|
|
|
prevpercent=percent;
|
2007-03-03 04:43:16 -05:00
|
|
|
/* set text of message to display */
|
2006-10-15 15:34:52 -04:00
|
|
|
switch (event) {
|
|
|
|
case PM_TRANS_PROGRESS_ADD_START:
|
2007-02-14 14:35:41 -05:00
|
|
|
opr = _("installing");
|
2007-01-23 22:02:53 -05:00
|
|
|
break;
|
2006-10-15 15:34:52 -04:00
|
|
|
case PM_TRANS_PROGRESS_UPGRADE_START:
|
2007-02-14 14:35:41 -05:00
|
|
|
opr = _("upgrading");
|
2007-01-23 22:02:53 -05:00
|
|
|
break;
|
2006-10-15 15:34:52 -04:00
|
|
|
case PM_TRANS_PROGRESS_REMOVE_START:
|
2007-02-14 14:35:41 -05:00
|
|
|
opr = _("removing");
|
2007-01-23 22:02:53 -05:00
|
|
|
break;
|
2006-10-15 19:54:43 -04:00
|
|
|
case PM_TRANS_PROGRESS_CONFLICTS_START:
|
2007-02-14 14:35:41 -05:00
|
|
|
opr = _("checking for file conflicts");
|
2007-01-23 22:02:53 -05:00
|
|
|
break;
|
2006-10-15 15:34:52 -04:00
|
|
|
}
|
2007-03-03 04:43:16 -05:00
|
|
|
/* convert above strings to wide chars */
|
|
|
|
oprlen = strlen(opr);
|
2007-05-14 03:16:55 -04:00
|
|
|
wcopr = calloc(oprlen, sizeof(wchar_t));
|
2007-03-03 04:43:16 -05:00
|
|
|
if(!wcopr) {
|
2007-10-30 00:32:58 -04:00
|
|
|
fprintf(stderr, "malloc failure: could not allocate %zd bytes\n",
|
2007-03-03 04:43:16 -05:00
|
|
|
strlen(opr) * sizeof(wchar_t));
|
2007-10-30 00:32:58 -04:00
|
|
|
return;
|
2007-03-03 04:43:16 -05:00
|
|
|
}
|
|
|
|
oprlen = mbstowcs(wcopr, opr, oprlen);
|
2006-10-15 15:34:52 -04:00
|
|
|
|
2007-01-30 20:37:41 -05:00
|
|
|
/* find # of digits in package counts to scale output */
|
|
|
|
digits = 1;
|
2007-03-03 04:43:16 -05:00
|
|
|
tmp = howmany;
|
|
|
|
while((tmp /= 10)) {
|
2007-01-30 20:37:41 -05:00
|
|
|
++digits;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* determine room left for non-digits text [not ( 1/12) part] */
|
|
|
|
textlen = infolen - 3 - (2 * digits);
|
|
|
|
/* room left for package name */
|
2007-03-03 04:43:16 -05:00
|
|
|
pkglen = textlen - oprlen - 1;
|
2006-10-15 15:34:52 -04:00
|
|
|
|
2006-10-15 19:54:43 -04:00
|
|
|
switch (event) {
|
2007-01-30 20:37:41 -05:00
|
|
|
case PM_TRANS_PROGRESS_ADD_START:
|
|
|
|
case PM_TRANS_PROGRESS_UPGRADE_START:
|
|
|
|
case PM_TRANS_PROGRESS_REMOVE_START:
|
2007-04-26 16:59:38 -04:00
|
|
|
/* old way of doing it, but ISO C does not recognize it
|
2007-02-21 23:32:09 -05:00
|
|
|
printf("(%2$*1$d/%3$*1$d) %4$s %6$-*5$.*5$s", digits, remain, howmany,
|
2007-04-26 16:59:38 -04:00
|
|
|
opr, pkglen, pkgname);*/
|
|
|
|
printf("(%*d/%*d) %s %-*.*s", digits, remain, digits, howmany,
|
|
|
|
opr, pkglen, pkglen, pkgname);
|
2007-01-30 20:37:41 -05:00
|
|
|
break;
|
|
|
|
case PM_TRANS_PROGRESS_CONFLICTS_START:
|
2007-04-26 16:59:38 -04:00
|
|
|
/* old way of doing it, but ISO C does not recognize it
|
2007-02-21 23:46:34 -05:00
|
|
|
printf("(%2$*1$d/%3$*1$d) %5$-*4$s", digits, remain, howmany,
|
2007-04-26 16:59:38 -04:00
|
|
|
textlen, opr);*/
|
|
|
|
printf("(%*d/%*d) %-*s", digits, remain, digits, howmany,
|
2007-02-14 14:35:41 -05:00
|
|
|
textlen, opr);
|
2007-01-30 20:37:41 -05:00
|
|
|
break;
|
2006-10-15 15:34:52 -04:00
|
|
|
}
|
2006-10-31 01:41:42 -05:00
|
|
|
|
2007-03-03 04:43:16 -05:00
|
|
|
free(wcopr);
|
|
|
|
|
2007-01-30 20:37:41 -05:00
|
|
|
/* call refactored fill progress function */
|
2007-11-09 19:54:19 -05:00
|
|
|
fill_progress(percent, percent, getcols() - infolen);
|
2007-12-03 16:57:54 -05:00
|
|
|
|
|
|
|
if(percent == 100) {
|
|
|
|
alpm_list_t *i = NULL;
|
|
|
|
on_progress = 0;
|
|
|
|
for(i = output; i; i = i->next) {
|
|
|
|
printf("%s", (char *)i->data);
|
|
|
|
}
|
|
|
|
fflush(stdout);
|
2007-12-08 03:58:49 -05:00
|
|
|
FREELIST(output);
|
2007-12-03 16:57:54 -05:00
|
|
|
} else {
|
|
|
|
on_progress = 1;
|
|
|
|
}
|
2007-04-25 20:02:07 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/* callback to handle display of download progress */
|
2007-11-09 19:54:19 -05:00
|
|
|
void cb_dl_progress(const char *filename, int file_xfered, int file_total,
|
|
|
|
int list_xfered, int list_total)
|
2007-04-25 20:02:07 -04:00
|
|
|
{
|
|
|
|
const int infolen = 50;
|
2007-11-16 21:18:45 -05:00
|
|
|
char *fname, *p;
|
2007-04-25 20:02:07 -04:00
|
|
|
|
|
|
|
float rate = 0.0, timediff = 0.0, f_xfered = 0.0;
|
|
|
|
unsigned int eta_h = 0, eta_m = 0, eta_s = 0;
|
2007-11-09 19:54:19 -05:00
|
|
|
int graph_percent = 0, display_percent = 0;
|
2007-04-25 20:02:07 -04:00
|
|
|
char rate_size = 'K', xfered_size = 'K';
|
2007-11-09 19:54:19 -05:00
|
|
|
int xfered = 0, total = 0;
|
|
|
|
|
|
|
|
/* Need this variable when TotalDownload is set to know if we should
|
|
|
|
* reset xfered_last and rate_last. */
|
|
|
|
static int has_init = 0;
|
2007-04-25 20:02:07 -04:00
|
|
|
|
|
|
|
if(config->noprogressbar) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2007-11-09 19:54:19 -05:00
|
|
|
/* Choose how to display the amount downloaded, rate, ETA, and
|
|
|
|
* percentage depending on the TotalDownload option. */
|
|
|
|
if (config->totaldownload && list_total > 0) {
|
|
|
|
xfered = list_xfered;
|
|
|
|
total = list_total;
|
|
|
|
} else {
|
|
|
|
xfered = file_xfered;
|
|
|
|
total = file_total;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* this is basically a switch on file_xferred: 0, file_total, and
|
|
|
|
* anything else */
|
|
|
|
if(file_xfered == 0) {
|
|
|
|
/* set default starting values, but only once for TotalDownload */
|
|
|
|
if (!(config->totaldownload && list_total > 0) ||
|
|
|
|
(config->totaldownload && list_total > 0 && !has_init)) {
|
|
|
|
gettimeofday(&initial_time, NULL);
|
|
|
|
timediff = get_update_timediff(1);
|
|
|
|
xfered_last = 0;
|
|
|
|
rate_last = 0.0;
|
|
|
|
has_init = 1;
|
|
|
|
}
|
2007-04-25 20:02:07 -04:00
|
|
|
rate = 0.0;
|
|
|
|
eta_s = 0;
|
2007-11-09 19:54:19 -05:00
|
|
|
} else if(file_xfered == file_total) {
|
2007-04-25 20:02:07 -04:00
|
|
|
/* compute final values */
|
|
|
|
struct timeval current_time;
|
|
|
|
float diff_sec, diff_usec;
|
2007-11-16 21:18:45 -05:00
|
|
|
|
2007-04-25 20:02:07 -04:00
|
|
|
gettimeofday(¤t_time, NULL);
|
|
|
|
diff_sec = current_time.tv_sec - initial_time.tv_sec;
|
|
|
|
diff_usec = current_time.tv_usec - initial_time.tv_usec;
|
|
|
|
timediff = diff_sec + (diff_usec / 1000000.0);
|
2007-11-09 19:54:19 -05:00
|
|
|
rate = xfered / (timediff * 1024.0);
|
2007-04-25 20:02:07 -04:00
|
|
|
|
|
|
|
/* round elapsed time to the nearest second */
|
2007-10-31 16:12:33 -04:00
|
|
|
eta_s = (int)(timediff + 0.5);
|
2007-04-25 20:02:07 -04:00
|
|
|
} else {
|
|
|
|
/* compute current average values */
|
|
|
|
timediff = get_update_timediff(0);
|
|
|
|
|
|
|
|
if(timediff < UPDATE_SPEED_SEC) {
|
|
|
|
/* return if the calling interval was too short */
|
|
|
|
return;
|
|
|
|
}
|
2007-05-14 03:16:55 -04:00
|
|
|
rate = (xfered - xfered_last) / (timediff * 1024.0);
|
2007-04-25 20:02:07 -04:00
|
|
|
/* average rate to reduce jumpiness */
|
2007-05-14 03:16:55 -04:00
|
|
|
rate = (rate + 2*rate_last) / 3;
|
|
|
|
eta_s = (total - xfered) / (rate * 1024.0);
|
2007-04-25 20:02:07 -04:00
|
|
|
rate_last = rate;
|
|
|
|
xfered_last = xfered;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* fix up time for display */
|
|
|
|
eta_h = eta_s / 3600;
|
|
|
|
eta_s -= eta_h * 3600;
|
|
|
|
eta_m = eta_s / 60;
|
|
|
|
eta_s -= eta_m * 60;
|
2007-02-03 20:36:45 -05:00
|
|
|
|
2007-04-25 20:02:07 -04:00
|
|
|
fname = strdup(filename);
|
2007-09-27 23:47:25 -04:00
|
|
|
/* strip package or DB extension for cleaner look */
|
2007-05-31 02:51:28 -04:00
|
|
|
if((p = strstr(fname, PKGEXT)) || (p = strstr(fname, DBEXT))) {
|
2007-04-25 20:02:07 -04:00
|
|
|
*p = '\0';
|
|
|
|
}
|
|
|
|
if(strlen(fname) > FILENAME_TRIM_LEN) {
|
|
|
|
strcpy(fname + FILENAME_TRIM_LEN -3,"...");
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Awesome formatting for progress bar. We need a mess of Kb->Mb->Gb stuff
|
|
|
|
* here. We'll use limit of 2048 for each until we get some empirical */
|
|
|
|
/* rate_size = 'K'; was set above */
|
|
|
|
if(rate > 2048.0) {
|
|
|
|
rate /= 1024.0;
|
|
|
|
rate_size = 'M';
|
|
|
|
if(rate > 2048.0) {
|
|
|
|
rate /= 1024.0;
|
|
|
|
rate_size = 'G';
|
|
|
|
/* we should not go higher than this for a few years (9999.9 Gb/s?)*/
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-05-14 03:16:55 -04:00
|
|
|
f_xfered = xfered / 1024.0; /* convert to K by default */
|
2007-04-25 20:02:07 -04:00
|
|
|
/* xfered_size = 'K'; was set above */
|
|
|
|
if(f_xfered > 2048.0) {
|
|
|
|
f_xfered /= 1024.0;
|
|
|
|
xfered_size = 'M';
|
|
|
|
if(f_xfered > 2048.0) {
|
|
|
|
f_xfered /= 1024.0;
|
|
|
|
xfered_size = 'G';
|
|
|
|
/* I should seriously hope that archlinux packages never break
|
|
|
|
* the 9999.9GB mark... we'd have more serious problems than the progress
|
2007-11-16 21:18:45 -05:00
|
|
|
* bar in pacman */
|
2007-04-25 20:02:07 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-11-16 21:18:45 -05:00
|
|
|
printf(" %-*s %6.1f%c %#6.1f%c/s %02u:%02u:%02u", FILENAME_TRIM_LEN, fname,
|
2007-04-25 20:02:07 -04:00
|
|
|
f_xfered, xfered_size, rate, rate_size, eta_h, eta_m, eta_s);
|
|
|
|
|
|
|
|
free(fname);
|
2007-11-16 21:18:45 -05:00
|
|
|
|
2007-11-09 19:54:19 -05:00
|
|
|
/* The progress bar is based on the file percent regardless of the
|
|
|
|
* TotalDownload option. */
|
|
|
|
graph_percent = (int)((float)file_xfered) / ((float)file_total) * 100;
|
|
|
|
display_percent = (int)((float)xfered) / ((float)total) * 100;
|
|
|
|
fill_progress(graph_percent, display_percent, getcols() - infolen);
|
2007-04-25 20:02:07 -04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Callback to handle notifications from the library */
|
2007-06-07 20:55:13 -04:00
|
|
|
void cb_log(pmloglevel_t level, char *fmt, va_list args)
|
2007-04-25 20:02:07 -04:00
|
|
|
{
|
2007-06-07 20:55:13 -04:00
|
|
|
if(!strlen(fmt)) {
|
2007-04-25 20:02:07 -04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2007-12-03 16:57:54 -05:00
|
|
|
if(on_progress) {
|
|
|
|
char *string = NULL;
|
|
|
|
pm_vasprintf(&string, level, fmt, args);
|
|
|
|
if(string != NULL) {
|
|
|
|
output = alpm_list_add(output, string);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
pm_vfprintf(stdout, level, fmt, args);
|
|
|
|
}
|
2006-10-15 15:34:52 -04:00
|
|
|
}
|
|
|
|
|
2005-03-19 04:00:40 -05:00
|
|
|
/* vim: set ts=2 sw=2 noet: */
|