Handle expansion sequences in @exec better (let the expander decide whether
authorespie <espie@openbsd.org>
Fri, 24 Mar 2000 00:20:04 +0000 (00:20 +0000)
committerespie <espie@openbsd.org>
Fri, 24 Mar 2000 00:20:04 +0000 (00:20 +0000)
it needs a file name instead of assuming we always need one).

Sent to *quite a few* people, comments by drahn@... guys, wake up !!!

usr.sbin/pkg_install/add/extract.c
usr.sbin/pkg_install/lib/file.c
usr.sbin/pkg_install/lib/lib.h
usr.sbin/pkg_install/lib/plist.c

index 06e53db..7cbbb96 100644 (file)
@@ -1,7 +1,7 @@
-/*     $OpenBSD: extract.c,v 1.8 1999/07/26 14:40:07 aaron Exp $       */
+/*     $OpenBSD: extract.c,v 1.9 2000/03/24 00:20:04 espie Exp $       */
 
 #ifndef lint
-static const char *rcsid = "$OpenBSD: extract.c,v 1.8 1999/07/26 14:40:07 aaron Exp $";
+static const char *rcsid = "$OpenBSD: extract.c,v 1.9 2000/03/24 00:20:04 espie Exp $";
 #endif
 
 /*
@@ -205,11 +205,14 @@ extract_plist(char *home, package_t *pkg)
            break;
 
        case PLIST_CMD:
-           if (last_file == NULL) {
+           if (!format_cmd(cmd, sizeof(cmd), p->name, Directory, last_file)) {
                cleanup(0);
-               errx(2, "no last file specified for '%s' command", p->name);
+               if (last_file == NULL)
+                   errx(2, "no last file specified for '%s' command", p->name);
+               else 
+                   errx(2, "'%s' command could not expand", p->name);
            }
-           format_cmd(cmd, sizeof(cmd), p->name, Directory, last_file);
+           
            PUSHOUT(Directory);
            if (Verbose)
                printf("extract: execute '%s'\n", cmd);
index a3b050b..353a63e 100644 (file)
@@ -1,7 +1,7 @@
-/*     $OpenBSD: file.c,v 1.9 1999/10/09 20:35:46 beck Exp $   */
+/*     $OpenBSD: file.c,v 1.10 2000/03/24 00:20:04 espie Exp $ */
 
 #ifndef lint
-static const char *rcsid = "$OpenBSD: file.c,v 1.9 1999/10/09 20:35:46 beck Exp $";
+static const char *rcsid = "$OpenBSD: file.c,v 1.10 2000/03/24 00:20:04 espie Exp $";
 #endif
 
 /*
@@ -624,56 +624,88 @@ unpack(char *pkg, char *flist)
  * %B  Return the directory part ("base") of %D/%F
  * %f  Return the filename part of %D/%F
  * 
- * Check that no overflows can occur.
  */
-void
-format_cmd(char *buf, size_t size, char *fmt, char *dir, char *name)
+int
+format_cmd(char *buf, size_t size, const char *fmt, 
+       const char *dir, const char *name)
 {
-       char    scratch[FILENAME_MAX * 2];
-       char   *bufp;
-       char   *cp;
+       char *pos;
+       size_t len;
 
-       for (bufp = buf ; (int)(bufp - buf) < size && *fmt ; ) {
+       while (*fmt != 0 && size != 0) {
                if (*fmt == '%') {
-                       switch (*++fmt) {
+                       switch(fmt[1]) {
+                       case 'f':
+                               if (name == NULL)
+                                       return 0;
+                               pos = strrchr(name, '/');
+                               if (pos != NULL) {
+                                       len = strlen(name) - (pos-name);
+                                       if (len >= size)
+                                               return 0;
+                                       memcpy(buf, pos, len);
+                                       buf += len;
+                                       size -= len;
+                                       fmt += 2;
+                                       continue;
+                               }
+                               /* FALLTHRU */
                        case 'F':
-                               strnncpy(bufp, size - (int)(bufp - buf), name, strlen(name));
-                               bufp += strlen(bufp);
-                               break;
-
+                               if (name == NULL)
+                                       return 0;
+                               len = strlen(name);
+                               if (len >= size)
+                                       return 0;
+                               memcpy(buf, name, len);
+                               buf += len;
+                               size -= len;
+                               fmt += 2;
+                               continue;
                        case 'D':
-                               strnncpy(bufp, size - (int)(bufp - buf), dir, strlen(dir));
-                               bufp += strlen(bufp);
-                               break;
-
+                               if (dir == NULL)
+                                       return 0;
+                               len = strlen(dir);
+                               if (len >= size)
+                                       return 0;
+                               memcpy(buf, dir, len);
+                               buf += len;
+                               size -= len;
+                               fmt += 2;
+                               continue;
                        case 'B':
-                               (void) snprintf(scratch, sizeof(scratch), "%s/%s", dir, name);
-                               if ((cp = strrchr(scratch, '/')) == (char *) NULL) {
-                                       cp = scratch;
+                               if (dir == NULL || name == NULL)
+                                       return 0;
+                               len = strlen(dir);
+                               if (len >= size)
+                                       return 0;
+                               memcpy(buf, dir, len);
+                               buf += len;
+                               size -= len;
+                               if ((pos = strrchr(name, '/')) != NULL) {
+                                       *buf++ = '/';
+                                       size--;
+                                       if (pos - name >= size)
+                                               return 0;
+                                       memcpy(buf, name, pos-name);
+                                       buf += pos-name;
+                                       size -= pos-name;
                                }
-                               strnncpy(bufp, size - (int)(bufp - buf), scratch, (size_t)(cp - scratch));
-                               bufp += strlen(bufp);
-                               break;
-
-                       case 'f':
-                               (void) snprintf(scratch, sizeof(scratch), "%s/%s", dir, name);
-                               if ((cp = strrchr(scratch, '/')) == (char *) NULL) {
-                                       cp = scratch;
-                               } else {
-                                       cp++;
-                               }
-                               strnncpy(bufp, size - (int)(bufp - buf), cp, strlen(cp));
-                               bufp += strlen(bufp);
-                               break;
-
+                               fmt += 2;
+                               continue;
+                       case '%':
+                               fmt++;  
                        default:
-                               *bufp++ = *fmt;
                                break;
+                           
                        }
-                       ++fmt;
-               } else {
-                       *bufp++ = *fmt++;
                }
+               *buf++ = *fmt++;
+               size--;
        }
-       *bufp = '\0';
+       if (size == 0)
+               return 0;
+       else 
+           *buf = '\0';
+       return 1;
 }
+                       
index a92e510..4d7c50e 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: lib.h,v 1.5 1999/10/09 20:35:46 beck Exp $ */
+/* $OpenBSD: lib.h,v 1.6 2000/03/24 00:20:04 espie Exp $ */
 
 /*
  * FreeBSD install - a package for the installation and maintainance
@@ -181,7 +181,8 @@ void                move_file(char *, char *, char *);
 void           copy_hierarchy(char *, char *, Boolean);
 int            delete_hierarchy(char *, Boolean, Boolean);
 int            unpack(char *, char *);
-void           format_cmd(char *, size_t , char *, char *, char *);
+int            format_cmd(char *, size_t , const char *, const char *,
+    const char *);
 
 /* Packing list */
 plist_t                *new_plist_entry(void);
index ac53026..28c7a7e 100644 (file)
@@ -1,6 +1,6 @@
-/*     $OpenBSD: plist.c,v 1.5 1998/10/13 23:09:54 marc Exp $  */
+/*     $OpenBSD: plist.c,v 1.6 2000/03/24 00:20:04 espie Exp $ */
 #ifndef lint
-static const char *rcsid = "$OpenBSD: plist.c,v 1.5 1998/10/13 23:09:54 marc Exp $";
+static const char *rcsid = "$OpenBSD: plist.c,v 1.6 2000/03/24 00:20:04 espie Exp $";
 #endif
 
 /*
@@ -315,12 +315,16 @@ delete_package(Boolean ign_err, Boolean nukedirs, package_t *pkg)
            break;
 
        case PLIST_UNEXEC:
-           format_cmd(tmp, sizeof(tmp), p->name, Where, last_file);
-           if (Verbose)
-               printf("Execute `%s'\n", tmp);
-           if (!Fake && system(tmp)) {
-               warnx("unexec command for `%s' failed", tmp);
+           if (!format_cmd(tmp, sizeof(tmp), p->name, Where, last_file)) {
+               warnx("unexec command `%s' could not expand", p->name);
                fail = FAIL;
+           } else {
+               if (Verbose)
+                   printf("Execute `%s'\n", tmp);
+               if (!Fake && system(tmp)) {
+                   warnx("unexec command for `%s' failed", tmp);
+                   fail = FAIL;
+               }
            }
            break;