[pacman-dev] CVS update of pacman-lib/lib/libalpm (alpm.h error.c remove.c)
Aaron Griffin
aaron at archlinux.org
Thu Feb 8 03:09:35 EST 2007
Date: Thursday, February 8, 2007 @ 03:09:35
Author: aaron
Path: /home/cvs-pacman/pacman-lib/lib/libalpm
Modified: alpm.h (1.71 -> 1.72) error.c (1.16 -> 1.17)
remove.c (1.60 -> 1.61)
Attempt to NOT remove packages on filesystem errors (like a read-only
filesystem). See FS#5887
----------+
alpm.h | 1
error.c | 2 +
remove.c | 95 +++++++++++++++++++++++++++++++++++++++++++------------------
3 files changed, 71 insertions(+), 27 deletions(-)
Index: pacman-lib/lib/libalpm/alpm.h
diff -u pacman-lib/lib/libalpm/alpm.h:1.71 pacman-lib/lib/libalpm/alpm.h:1.72
--- pacman-lib/lib/libalpm/alpm.h:1.71 Sun Feb 4 03:26:52 2007
+++ pacman-lib/lib/libalpm/alpm.h Thu Feb 8 03:09:34 2007
@@ -450,6 +450,7 @@
PM_ERR_PKG_LOAD,
PM_ERR_PKG_INSTALLED,
PM_ERR_PKG_CANT_FRESH,
+ PM_ERR_PKG_CANT_REMOVE,
PM_ERR_PKG_INVALID_NAME,
PM_ERR_PKG_CORRUPTED,
PM_ERR_PKG_REPO_NOT_FOUND,
Index: pacman-lib/lib/libalpm/error.c
diff -u pacman-lib/lib/libalpm/error.c:1.16 pacman-lib/lib/libalpm/error.c:1.17
--- pacman-lib/lib/libalpm/error.c:1.16 Tue Jan 30 02:47:20 2007
+++ pacman-lib/lib/libalpm/error.c Thu Feb 8 03:09:35 2007
@@ -97,6 +97,8 @@
return _("package already installed");
case PM_ERR_PKG_CANT_FRESH:
return _("package not installed or lesser version");
+ case PM_ERR_PKG_CANT_REMOVE:
+ return _("cannot remove all files for package");
case PM_ERR_PKG_INVALID_NAME:
return _("package name is not valid");
case PM_ERR_PKG_CORRUPTED:
Index: pacman-lib/lib/libalpm/remove.c
diff -u pacman-lib/lib/libalpm/remove.c:1.60 pacman-lib/lib/libalpm/remove.c:1.61
--- pacman-lib/lib/libalpm/remove.c:1.60 Wed Jan 31 01:10:21 2007
+++ pacman-lib/lib/libalpm/remove.c Thu Feb 8 03:09:35 2007
@@ -162,8 +162,40 @@
return(strcmp(s1, s2));
}
+
+static int can_remove_file(const char *path)
+{
+ alpm_list_t *i;
+ char file[PATH_MAX+1];
+
+ snprintf(file, PATH_MAX, "%s%s", handle->root, path);
+
+ for(i = handle->trans->skiplist; i; i = i->next) {
+ if(strcmp(file, i->data) == 0) {
+ /* skipping this file, return success because "removing" this
+ * file does nothing */
+ return(1);
+ }
+ }
+ /* If we fail write permissions due to a read-only filesystem, abort.
+ * Assume all other possible failures are covered somewhere else */
+ if(access(file, W_OK) == -1) {
+ if(access(file, F_OK) == 0) {
+ /* only return failure if the file ACTUALLY exists and we don't have
+ * permissions */
+ _alpm_log(PM_LOG_WARNING, _("cannot remove file '%s': %s"), file, strerror(errno));
+ return(0);
+ }
+ }
+
+ return(1);
+}
+
/* Helper function for iterating through a package's file and deleting them
* Used by _alpm_remove_commit
+ *
+ * TODO the parameters are a bit out of control here. This function doesn't
+ * need to report PROGRESS, do it in the parent function.
*/
static void unlink_file(pmpkg_t *info, alpm_list_t *lp, alpm_list_t *targ,
pmtrans_t *trans, int filenum, int *position)
@@ -171,34 +203,35 @@
struct stat buf;
int nb = 0;
double percent = 0.0;
- char *file = lp->data;
- char line[PATH_MAX+1];
+ char file[PATH_MAX+1];
char *checksum = _alpm_needbackup(lp->data, info->backup);
ALPM_LOG_FUNC;
- if ( *position != 0 ) {
+ if(*position != 0) {
percent = (double)*position / filenum;
- } if ( checksum ) {
+ }
+ if(checksum) {
nb = 1;
FREE(checksum);
- } if ( !nb && trans->type == PM_TRANS_TYPE_UPGRADE ) {
+ }
+ if(!nb && trans->type == PM_TRANS_TYPE_UPGRADE) {
/* check noupgrade */
- if ( alpm_list_find_str(handle->noupgrade, file) ) {
+ if(alpm_list_find_str(handle->noupgrade, lp->data)) {
nb = 1;
}
}
- snprintf(line, PATH_MAX, "%s%s", handle->root, file);
- if ( lstat(line, &buf) ) {
- _alpm_log(PM_LOG_DEBUG, _("file %s does not exist"), line);
+ snprintf(file, PATH_MAX, "%s%s", handle->root, (char *)lp->data);
+ if(lstat(file, &buf)) {
+ _alpm_log(PM_LOG_DEBUG, _("file %s does not exist"), file);
return;
}
- if ( S_ISDIR(buf.st_mode) ) {
- if ( rmdir(line) ) {
+ if(S_ISDIR(buf.st_mode)) {
+ if(rmdir(file)) {
/* this is okay, other pakcages are probably using it (like /usr) */
- _alpm_log(PM_LOG_DEBUG, _("keeping directory %s"), line);
+ _alpm_log(PM_LOG_DEBUG, _("keeping directory %s"), file);
} else {
- _alpm_log(PM_LOG_DEBUG, _("removing directory %s"), line);
+ _alpm_log(PM_LOG_DEBUG, _("removing directory %s"), file);
}
} else {
/* check the "skip list" before removing the file.
@@ -206,35 +239,36 @@
* explanation. */
int skipit = 0;
alpm_list_t *j;
- for ( j = trans->skiplist; j; j = j->next ) {
- if ( !strcmp(file, (char*)j->data) ) {
+ for(j = trans->skiplist; j; j = j->next) {
+ if(!strcmp(lp->data, (char*)j->data)) {
skipit = 1;
}
}
- if ( skipit ) {
- _alpm_log(PM_LOG_DEBUG, _("skipping removal of %s as it has moved to another package"),
- line);
+ if(skipit) {
+ _alpm_log(PM_LOG_WARNING, _("skipping removal of %s as it has moved to another package"),
+ file);
} else {
/* if the file is flagged, back it up to .pacsave */
- if ( nb ) {
- if ( !(trans->type == PM_TRANS_TYPE_UPGRADE) ) {
+ if(nb) {
+ if(!(trans->type == PM_TRANS_TYPE_UPGRADE)) {
/* if it was an upgrade, the file would be left alone because
* pacman_add() would handle it */
- if ( !(trans->type & PM_TRANS_FLAG_NOSAVE) ) {
+ if(!(trans->type & PM_TRANS_FLAG_NOSAVE)) {
char newpath[PATH_MAX];
- snprintf(newpath, PATH_MAX, "%s.pacsave", line);
- rename(line, newpath);
- _alpm_log(PM_LOG_WARNING, _("%s saved as %s"), line, newpath);
+ snprintf(newpath, PATH_MAX, "%s.pacsave", file);
+ rename(file, newpath);
+ _alpm_log(PM_LOG_WARNING, _("%s saved as %s"), file, newpath);
}
}
} else {
- _alpm_log(PM_LOG_DEBUG, _("unlinking %s"), line);
+ _alpm_log(PM_LOG_DEBUG, _("unlinking %s"), file);
int list_count = alpm_list_count(trans->packages); /* this way we don't have to call alpm_list_count twice during PROGRESS */
+
PROGRESS(trans, PM_TRANS_PROGRESS_REMOVE_START, info->name, (double)(percent * 100), list_count, (list_count - alpm_list_count(targ) + 1));
++(*position);
- if (unlink(line) == -1) {
- _alpm_log(PM_LOG_ERROR, _("cannot remove file %s: %s"), file, strerror(errno));
+ if(unlink(file) == -1) {
+ _alpm_log(PM_LOG_ERROR, _("cannot remove file %s: %s"), lp->data, strerror(errno));
}
}
}
@@ -272,6 +306,13 @@
}
if(!(trans->flags & PM_TRANS_FLAG_DBONLY)) {
+ for(lp = info->files; lp; lp = lp->next) {
+ if(!can_remove_file(lp->data)) {
+ _alpm_log(PM_LOG_DEBUG, _("not removing package '%s', can't remove all files"), info->name);
+ RET_ERR(PM_ERR_PKG_CANT_REMOVE, -1);
+ }
+ }
+
int filenum = alpm_list_count(info->files);
_alpm_log(PM_LOG_DEBUG, _("removing files"));
More information about the pacman-dev
mailing list