[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

[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: