summaryrefslogtreecommitdiff
path: root/usr.sbin/pkg_install/add/extract.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/pkg_install/add/extract.c')
-rw-r--r--usr.sbin/pkg_install/add/extract.c186
1 files changed, 186 insertions, 0 deletions
diff --git a/usr.sbin/pkg_install/add/extract.c b/usr.sbin/pkg_install/add/extract.c
new file mode 100644
index 00000000000..605bfafbbd0
--- /dev/null
+++ b/usr.sbin/pkg_install/add/extract.c
@@ -0,0 +1,186 @@
+# $OpenBSD: extract.c,v 1.1 1996/06/04 07:56:03 niklas Exp $
+#ifndef lint
+static const char *rcsid = "$OpenBSD: extract.c,v 1.1 1996/06/04 07:56:03 niklas Exp $";
+#endif
+
+/*
+ * FreeBSD install - a package for the installation and maintainance
+ * of non-core utilities.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Jordan K. Hubbard
+ * 18 July 1993
+ *
+ * This is the package extraction code for the add module.
+ *
+ */
+
+#include "lib.h"
+#include "add.h"
+
+
+#define STARTSTRING "tar cf -"
+#define TOOBIG(str) ((strlen(str) + 6 + strlen(home) + where_count > maxargs) \
+ || (strlen(str) + 6 + strlen(home) + perm_count > maxargs))
+
+#define PUSHOUT(todir) /* push out string */ \
+ if (strlen(where_args) > sizeof(STARTSTRING)-1) { \
+ strcat(where_args, "|tar xf - -C "); \
+ strcat(where_args, todir); \
+ if (system(where_args)) \
+ barf("can't invoke tar pipeline"); \
+ strcpy(where_args, STARTSTRING); \
+ where_count = sizeof(STARTSTRING)-1; \
+ } \
+ if (perm_count) { \
+ if (!isdir(todir)) apply_perms(todir, perm_args); \
+ perm_args[0] = 0;\
+ perm_count = 0; \
+ }
+
+void
+extract_plist(char *home, Package *pkg)
+{
+ PackingList p = pkg->head;
+ char *last_file;
+ char *where_args, *perm_args, *last_chdir;
+ int maxargs, where_count = 0, perm_count = 0, add_count;
+
+ maxargs = sysconf(_SC_ARG_MAX);
+ maxargs -= 64; /* some slop for the tar cmd text,
+ and sh -c */
+ where_args = malloc(maxargs);
+ if (!where_args)
+ barf("can't get argument list space");
+ perm_args = malloc(maxargs);
+ if (!perm_args)
+ barf("can't get argument list space");
+
+ strcpy(where_args, STARTSTRING);
+ where_count = sizeof(STARTSTRING)-1;
+ perm_args[0] = 0;
+
+ last_chdir = 0;
+
+ /* Reset the world */
+ Owner = NULL;
+ Group = NULL;
+ Mode = NULL;
+ last_file = NULL;
+ Directory = home;
+
+ /* Do it */
+ while (p) {
+ char cmd[FILENAME_MAX];
+
+ switch(p->type) {
+ case PLIST_NAME:
+ PkgName = p->name;
+ if (Verbose)
+ printf("extract: Package name is %s\n", p->name);
+ break;
+
+ case PLIST_FILE:
+ last_file = p->name;
+ if (Verbose)
+ printf("extract: %s/%s\n", Directory, p->name);
+ if (!Fake) {
+ char try[FILENAME_MAX];
+
+ /* first try to rename it into place */
+ sprintf(try, "%s/%s", Directory, p->name);
+ if (rename(p->name, try) == 0) {
+ /* try to add to list of perms to be changed,
+ and run in bulk. */
+ add_count = snprintf(&perm_args[perm_count],
+ maxargs - perm_count,
+ "%s ", p->name);
+ if (add_count > maxargs - perm_count)
+ barf("oops, miscounted strings!");
+ perm_count += add_count;
+ if (p->name[0] == '/') {
+ PUSHOUT(Directory);
+ }
+ } else {
+ /* rename failed, try copying with a big tar command */
+ if (p->name[0] == '/' ||
+ TOOBIG(p->name) ||
+ last_chdir != Directory) {
+ PUSHOUT(last_chdir);
+ last_chdir = Directory;
+ }
+ add_count = snprintf(&where_args[where_count],
+ maxargs - where_count,
+ " %s", p->name);
+ if (add_count > maxargs - where_count)
+ barf("oops, miscounted strings!");
+ where_count += add_count;
+ add_count = snprintf(&perm_args[perm_count],
+ maxargs - perm_count,
+ "%s ", p->name);
+ if (add_count > maxargs - perm_count)
+ barf("oops, miscounted strings!");
+ perm_count += add_count;
+ if (p->name[0] == '/') {
+ PUSHOUT(Directory);
+ }
+ }
+ }
+ break;
+
+ case PLIST_CWD:
+ if (Verbose)
+ printf("extract: CWD to %s\n", p->name);
+ PUSHOUT(Directory);
+ if (strcmp(p->name, ".")) {
+ if (!Fake && make_hierarchy(p->name) == FAIL)
+ barf("Unable make directory '%s'.", p->name);
+ Directory = p->name;
+ }
+ else
+ Directory = home;
+ break;
+
+ case PLIST_CMD:
+ format_cmd(cmd, p->name, Directory, last_file);
+ PUSHOUT(Directory);
+ if (Verbose)
+ printf("extract: execute '%s'\n", cmd);
+ if (!Fake && system(cmd))
+ whinge("Command '%s' failed.", cmd);
+ break;
+
+ case PLIST_CHMOD:
+ PUSHOUT(Directory);
+ Mode = p->name;
+ break;
+
+ case PLIST_CHOWN:
+ PUSHOUT(Directory);
+ Owner = p->name;
+ break;
+
+ case PLIST_CHGRP:
+ PUSHOUT(Directory);
+ Group = p->name;
+ break;
+
+ case PLIST_COMMENT:
+ break;
+
+ case PLIST_IGNORE:
+ p = p->next;
+ break;
+ }
+ p = p->next;
+ }
+ PUSHOUT(Directory);
+}