[BACK]Return to apply.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / apply

Diff for /src/usr.bin/apply/apply.c between version 1.27 and 1.28

version 1.27, 2015/10/10 17:48:34 version 1.28, 2018/03/27 10:00:16
Line 44 
Line 44 
 #include <string.h>  #include <string.h>
 #include <unistd.h>  #include <unistd.h>
   
   #define ISMAGICNO(p) \
               (p)[0] == magic && isdigit((unsigned char)(p)[1]) && (p)[1] != '0'
   
 __dead  void    usage(void);  __dead  void    usage(void);
 static  int     mysystem(const char *);  static  int     mysystem(const char *);
   
   char    *str;
   size_t   sz;
   
   void
   stradd(char *p)
   {
           size_t n;
   
           n = strlen(p);
           if (str == NULL || sz - strlen(str) <= n) {
                   sz += (n / 1024 + 1) * 1024;
                   if ((str = realloc(str, sz)) == NULL)
                           err(1, "realloc");
           }
           strlcat(str, p, sz);
   }
   
   void
   strset(char *p)
   {
           if (str != NULL)
                   str[0] = '\0';
           stradd(p);
   }
   
 int  int
 main(int argc, char *argv[])  main(int argc, char *argv[])
 {  {
         int ch, clen, debug, i, l, magic, n, nargs, rval;          int ch, debug, i, magic, n, nargs, rval;
         char *c, *c2, *cmd, *p, *q;          char buf[4], *cmd, *p;
         size_t len;  
   
         if (pledge("stdio proc exec", NULL) == -1)          if (pledge("stdio proc exec", NULL) == -1)
                 err(1, "pledge");                  err(1, "pledge");
Line 63 
Line 90 
         while ((ch = getopt(argc, argv, "a:d0123456789")) != -1)          while ((ch = getopt(argc, argv, "a:d0123456789")) != -1)
                 switch (ch) {                  switch (ch) {
                 case 'a':                  case 'a':
                         if (optarg[1] != '\0')                          if (optarg[0] == '\0' || optarg[1] != '\0')
                                 errx(1,                                  errx(1,
                                     "illegal magic character specification.");                                      "illegal magic character specification.");
                         magic = optarg[0];                          magic = optarg[0];
Line 93 
Line 120 
          * largest one.           * largest one.
          */           */
         for (n = 0, p = argv[0]; *p != '\0'; ++p)          for (n = 0, p = argv[0]; *p != '\0'; ++p)
                 if (p[0] == magic &&                  if (ISMAGICNO(p)) {
                     isdigit((unsigned char)p[1]) && p[1] != '0') {  
                         ++p;                          ++p;
                         if (p[0] - '0' > n)                          if (p[0] - '0' > n)
                                 n = p[0] - '0';                                  n = p[0] - '0';
Line 106 
Line 132 
          * the end to consume (nargs) arguments each time round the loop.           * the end to consume (nargs) arguments each time round the loop.
          * Allocate enough space to hold the maximum command.           * Allocate enough space to hold the maximum command.
          */           */
           strset(argv[0]);
         if (n == 0) {          if (n == 0) {
                 len = sizeof("exec ") - 1 +  
                     strlen(argv[0]) + 9 * (sizeof(" %1") - 1) + 1;  
                 if ((cmd = malloc(len)) == NULL)  
                         err(1, NULL);  
   
                 /* If nargs not set, default to a single argument. */                  /* If nargs not set, default to a single argument. */
                 if (nargs == -1)                  if (nargs == -1)
                         nargs = 1;                          nargs = 1;
   
                 l = snprintf(cmd, len, "exec %s", argv[0]);  
                 if (l >= len || l == -1)  
                         errx(1, "error building exec string");  
                 len -= l;  
                 p = cmd + l;  
   
                 for (i = 1; i <= nargs; i++) {                  for (i = 1; i <= nargs; i++) {
                         l = snprintf(p, len, " %c%d", magic, i);                          snprintf(buf, sizeof(buf), " %c%d", magic, i);
                         if (l >= len || l == -1)                          stradd(buf);
                                 errx(1, "error numbering arguments");  
                         len -= l;  
                         p += l;  
                 }                  }
   
                 /*                  /*
Line 136 
Line 149 
                  */                   */
                 if (nargs == 0)                  if (nargs == 0)
                         nargs = 1;                          nargs = 1;
         } else {          } else
                 if (asprintf(&cmd, "exec %s", argv[0]) == -1)  
                         err(1, NULL);  
                 nargs = n;                  nargs = n;
         }          if ((cmd = strdup(str)) == NULL)
                   err(1, "strdup");
   
         /*          /*
          * Grab some space in which to build the command.  Allocate  
          * as necessary later, but no reason to build it up slowly  
          * for the normal case.  
          */  
         if ((c = malloc(clen = 1024)) == NULL)  
                 err(1, NULL);  
   
         /*  
          * (argc) and (argv) are still offset by one to make it simpler to           * (argc) and (argv) are still offset by one to make it simpler to
          * expand %digit references.  At the end of the loop check for (argc)           * expand %digit references.  At the end of the loop check for (argc)
          * equals 1 means that all the (argv) has been consumed.           * equals 1 means that all the (argv) has been consumed.
          */           */
         for (rval = 0; argc > nargs; argc -= nargs, argv += nargs) {          for (rval = 0; argc > nargs; argc -= nargs, argv += nargs) {
                 /*                  strset("exec ");
                  * Find a max value for the command length, and ensure  
                  * there's enough space to build it.  
                  */  
                 for (l = strlen(cmd), i = 0; i < nargs; i++)  
                         l += strlen(argv[i+1]);  
                 if (l > clen) {  
                         if ((c2 = realloc(c, l)) == NULL)  
                                 err(1, NULL);  
                         c = c2;  
                         clen = l;  
                 }  
   
                 /* Expand command argv references. */                  /* Expand command argv references. */
                 for (p = cmd, q = c; *p != '\0'; ++p)                  for (p = cmd; *p != '\0'; ++p)
                         if (p[0] == magic &&                          if (ISMAGICNO(p))
                             isdigit((unsigned char)p[1]) && p[1] != '0') {                                  stradd(argv[*(++p) - '0']);
                                 strlcpy(q, argv[(++p)[0] - '0'], c + clen - q);                          else {
                                 q += strlen(q);                                  strlcpy(buf, p, 2);
                         } else                                  stradd(buf);
                                 *q++ = *p;                          }
   
                 /* Terminate the command string. */  
                 *q = '\0';  
   
                 /* Run the command. */                  /* Run the command. */
                 if (debug)                  if (debug)
                         (void)printf("%s\n", c);                          (void)printf("%s\n", str);
                 else if (mysystem(c))                  else if (mysystem(str))
                         rval = 1;                          rval = 1;
         }          }
   

Legend:
Removed from v.1.27  
changed lines
  Added in v.1.28