[PATCH 6/6] Split some useful functions from help.c to (new) util.c
A small number of functions from help.c are required for the new
dpkg-conffile cmdline program, but it's not currently possible
to link help.c into other programs (without defining a large quantity
of unused global variables to satisfy all the extern's in main.h).
Therefore, the following functions have been moved to a new util.c file:
* void debug(int which, const char *fmt, ...)
* void ensure_pathname_nonexisting(const char *pathname)
* int secure_unlink(const char *pathname)
* int secure_unlink_statted(const char *pathname, const struct stat *stab)
Note that debug still references an external int f_debug, which must be
provided by a cmdline program. It's left for discussion and/or future
implementation to fix that.
The Makefile.am automake template has also been updated to include this file
in dpkg_SOURCES and no further changes are required to dpkg source code.
---
src/Makefile.am | 3 +-
src/help.c | 72 -----------------------------------
src/util.c | 111 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 113 insertions(+), 73 deletions(-)
create mode 100644 src/util.c
diff --git a/src/Makefile.am b/src/Makefile.am
index 24583de..9c1fc15 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -36,7 +36,8 @@ dpkg_SOURCES = \
remove.c \
select.c \
trigproc.c \
- update.c
+ update.c \
+ util.c
dpkg_LDADD = \
../lib/dpkg/libdpkg.a \
diff --git a/src/help.c b/src/help.c
index 62221ce..db7b22d 100644
--- a/src/help.c
+++ b/src/help.c
@@ -461,16 +461,6 @@ void clear_istobes(void) {
iterpkgend(it);
}
-void debug(int which, const char *fmt, ...) {
- va_list ap;
- if (!(f_debug & which)) return;
- fprintf(stderr,"D0%05o: ",which);
- va_start(ap,fmt);
- vfprintf(stderr,fmt,ap);
- va_end(ap);
- putc('\n',stderr);
-}
-
/*
* Returns true if the directory contains conffiles belonging to pkg,
* false otherwise.
@@ -535,68 +525,6 @@ void oldconffsetflags(const struct conffile *searchconff) {
}
}
-/*
- * If the pathname to remove is:
- *
- * 1. a sticky or set-id file, or
- * 2. an unknown object (i.e., not a file, link, directory, fifo or socket)
- *
- * we change its mode so that a malicious user cannot use it, even if it's
- * linked to another file.
- */
-int
-secure_unlink(const char *pathname)
-{
- struct stat stab;
-
- if (lstat(pathname,&stab)) return -1;
-
- return secure_unlink_statted(pathname, &stab);
-}
-
-int
-secure_unlink_statted(const char *pathname, const struct stat *stab)
-{
- if (S_ISREG(stab->st_mode) ? (stab->st_mode & 07000) :
- !(S_ISLNK(stab->st_mode) || S_ISDIR(stab->st_mode) ||
- S_ISFIFO(stab->st_mode) || S_ISSOCK(stab->st_mode))) {
- if (chmod(pathname, 0600))
- return -1;
- }
- if (unlink(pathname)) return -1;
- return 0;
-}
-
-void ensure_pathname_nonexisting(const char *pathname) {
- int c1;
- const char *u;
-
- u = path_skip_slash_dotslash(pathname);
- assert(*u);
-
- debug(dbg_eachfile,"ensure_pathname_nonexisting `%s'",pathname);
- if (!rmdir(pathname)) return; /* Deleted it OK, it was a directory. */
- if (errno == ENOENT || errno == ELOOP) return;
- if (errno == ENOTDIR) {
- /* Either it's a file, or one of the path components is. If one
- * of the path components is this will fail again ...
- */
- if (secure_unlink(pathname) == 0)
- return; /* OK, it was */
- if (errno == ENOTDIR) return;
- }
- if (errno != ENOTEMPTY && errno != EEXIST) { /* Huh ? */
- ohshite(_("unable to securely remove '%.255s'"), pathname);
- }
- c1= m_fork();
- if (!c1) {
- execlp(RM, "rm", "-rf", "--", pathname, NULL);
- ohshite(_("failed to exec rm for cleanup"));
- }
- debug(dbg_eachfile,"ensure_pathname_nonexisting running rm -rf");
- waitsubproc(c1,"rm cleanup",0);
-}
-
void log_action(const char *action, struct pkginfo *pkg) {
log_message("%s %s %s %s", action, pkg->name,
versiondescribe(&pkg->installed.version, vdew_nonambig),
diff --git a/src/util.c b/src/util.c
new file mode 100644
index 0000000..bade26c
--- /dev/null
+++ b/src/util.c
@@ -0,0 +1,111 @@
+/*
+ * util.c - misc utility functions
+ *
+ * Copyright © 1995 Ian Jackson <ian@chiark.greenend.org.uk>
+ *
+ * This 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,
+ * or (at your option) any later version.
+ *
+ * This 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 along with dpkg; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <config.h>
+#include <compat.h>
+
+#include <assert.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "main.h"
+
+#include "dpkg/dpkg.h"
+#include "dpkg/i18n.h"
+#include "dpkg/path.h"
+#include "dpkg/subproc.h"
+
+void
+debug(int which, const char *fmt, ...)
+{
+ va_list ap;
+ if (!(f_debug & which)) return;
+ fprintf(stderr,"D0%05o: ",which);
+ va_start(ap,fmt);
+ vfprintf(stderr,fmt,ap);
+ va_end(ap);
+ putc('\n',stderr);
+}
+
+void
+ensure_pathname_nonexisting(const char *pathname)
+{
+ int c1;
+ const char *u;
+
+ u = path_skip_slash_dotslash(pathname);
+ assert(*u);
+
+ debug(dbg_eachfile,"ensure_pathname_nonexisting `%s'",pathname);
+ if (!rmdir(pathname)) return; /* Deleted it OK, it was a directory. */
+ if (errno == ENOENT || errno == ELOOP) return;
+ if (errno == ENOTDIR) {
+ /* Either it's a file, or one of the path components is. If one
+ * of the path components is this will fail again ...
+ */
+ if (secure_unlink(pathname) == 0)
+ return; /* OK, it was */
+ if (errno == ENOTDIR) return;
+ }
+ if (errno != ENOTEMPTY && errno != EEXIST) { /* Huh ? */
+ ohshite(_("unable to securely remove '%.255s'"), pathname);
+ }
+ c1= m_fork();
+ if (!c1) {
+ execlp(RM, "rm", "-rf", "--", pathname, NULL);
+ ohshite(_("failed to exec rm for cleanup"));
+ }
+ debug(dbg_eachfile,"ensure_pathname_nonexisting running rm -rf");
+ waitsubproc(c1,"rm cleanup",0);
+}
+
+/*
+ * If the pathname to remove is:
+ *
+ * 1. a sticky or set-id file, or
+ * 2. an unknown object (i.e., not a file, link, directory, fifo or socket)
+ *
+ * we change its mode so that a malicious user cannot use it, even if it's
+ * linked to another file.
+ */
+int
+secure_unlink(const char *pathname)
+{
+ struct stat stab;
+
+ if (lstat(pathname,&stab))
+ return -1;
+
+ return secure_unlink_statted(pathname, &stab);
+}
+
+int
+secure_unlink_statted(const char *pathname, const struct stat *stab)
+{
+ if (S_ISREG(stab->st_mode) ? (stab->st_mode & 07000) :
+ !(S_ISLNK(stab->st_mode) || S_ISDIR(stab->st_mode) ||
+ S_ISFIFO(stab->st_mode) || S_ISSOCK(stab->st_mode))) {
+ if (chmod(pathname, 0600))
+ return -1;
+ }
+ if (unlink(pathname)) return -1;
+ return 0;
+}
--
1.6.4.3
Reply to: