View | Details | Raw Unified
Collapse All | Expand All

(-)a/src/cmds/qsub.c (-268 / +159 lines)
 Lines 148-153   static char *DefaultXauthPath = XAUTH_PATH; Link Here 
148
#define MAX_PROCS_DIGITS  15 /* A 15 digit number is a lot of processors. 100 trillion 
148
#define MAX_PROCS_DIGITS  15 /* A 15 digit number is a lot of processors. 100 trillion 
149
                                     will this be enough for the future? */
149
                                     will this be enough for the future? */
150
150
151
152
/* Session descriptor for get_name_value() */
153
struct parse_name_value {
154
  char *name;			/* Last name that was processed */
155
  char *buffer;			/* Buffer with input string */
156
  char *curpos;			/* Current position inside buffer */
157
  unsigned char flags;		/* Flags for the session */
158
};
159
#define PNV_BADSYNTAX		0x01
160
161
151
static char PBS_DPREFIX_DEFAULT[] = "#PBS";
162
static char PBS_DPREFIX_DEFAULT[] = "#PBS";
152
163
153
char PBS_Filter[256];
164
char PBS_Filter[256];
 Lines 335-645   static char *x11_get_proto( Link Here 
335
346
336
347
337
348
338
349
/*
339
char *smart_strtok(
350
 * Strips trailing blank characters.
340
351
 */
341
  char  *line,          /* I */
352
static void chomp_blanks(s)
342
  char  *delims,        /* I */
353
char *s;
343
  char **ptrPtr,        /* O */
344
  int    ign_backslash) /* I */
345
346
  {
354
  {
347
  char *head = NULL;
355
  size_t len;
348
  char *start = NULL;
349
356
350
  int dindex;
357
  for (len = strlen(s) - 1; len >= 0 && isspace(s[len]); len--);
351
  int ignchar;
358
  s[len + 1] = '\0';
352
  int ignore;
359
  }  /* END chomp_blanks() */
353
360
354
  int sq_count = 0;
355
  int dq_count = 0;
356
  int sb_count = 0;
357
361
358
  char *tmpLine = NULL;
359
  int   tmpLineSize;
360
  int   tindex;
361
362
362
  char *ptr;
363
/*
364
 * Parses argument lists like 'name=value[,value,value],name=value'.
365
 * The first form, with many values for a single name will be
366
 * permitted only if 'name' is found in the array multiarg_OK.
367
 *
368
 * When 'start' is non-NULL this means that a new parsing session
369
 * with the buffer 'start' is pointing to will be created.
370
 *
371
 * Any subsequent calls to this function with 'start' being NULL
372
 * means "continue the parsing from the last position".
373
 *
374
 * Return values:
375
 * 1: new name/value pair was parsed;
376
 * 0: end of string reached, nothing new was parsed;
377
 * -1: memory allocation error (won't happen when start == NULL);
378
 * -2: bad line contents.
379
 */
380
int get_name_value(session, start, name, value, multiarg_OK)
381
struct parse_name_value *session;
382
char  *start;
383
char **name;
384
char **value;
385
const char *multiarg_OK[];
386
  {
387
  char *p;
363
388
364
  if (ptrPtr == NULL)
389
  assert(session != NULL);
365
    {
390
  assert(name != NULL);
366
    /* FAILURE */
391
  assert(value != NULL);
367
392
368
    return(head);
393
  if (start != NULL)
369
    }
370
  else if (line != NULL)
371
    {
394
    {
372
    *ptrPtr = line;
395
    size_t len = strlen(start);
396
397
    bzero((void *)session, sizeof(*session));
398
    session->buffer = (char *)malloc(len + 1);
399
    if (session->buffer == NULL)
400
      return (-1);
401
    strncpy(session->buffer, start, len);
402
    session->buffer[len] = '\0';
403
    session->curpos = session->buffer;
373
    }
404
    }
374
  else if (*ptrPtr == NULL)
405
  else
375
    {
406
    {
376
    /* FAILURE */
407
    assert(session->buffer != NULL);
377
408
    assert(session->curpos >= session->curpos);
378
    return(head);
409
    if (session->flags & PNV_BADSYNTAX)
410
      return (-2);
379
    }
411
    }
380
412
381
  start = *ptrPtr;
413
  if (session->curpos[0] == '\0')
382
414
    return (0);
383
  tmpLineSize = (line == NULL) ? strlen(*ptrPtr) + 1 : strlen(line) + 1;
384
  tmpLine = (char *)malloc(tmpLineSize * sizeof(char));
385
386
  tmpLine[0] = '\0';
387
388
  tindex = 0;
389
390
  ignchar = FALSE;
391
415
392
  ptr = *ptrPtr;
416
  while (isspace(session->curpos[0]))
417
    session->curpos++;
393
418
394
  while (*ptr != '\0')
419
  /* Look for the name */
420
  for (p = session->curpos; *p != '='; p++)
395
    {
421
    {
396
    if (*ptr == '\'')
422
    if (*p == '\0' || *p == ',')
397
      {
423
      {
398
      sq_count++;
424
      unsigned char permit_multi = 0;
425
      size_t i;
399
426
400
      if ((head != NULL) && !(sq_count % 2) && !(dq_count % 2))
427
      if (session->name != NULL)
401
        {
428
        {
402
        ptr++;
429
        /*
403
430
         * Reuse the last seen name (for second and successive 'value'
404
        ignchar = TRUE;
431
         * in 'name=value[,value,value,...]') if it is permitted
405
        }
432
         * by multiarg_OK.
406
      else 
433
         */
407
        {
434
        for (i = 0; multiarg_OK[i] != NULL; i++)
408
        ignore = TRUE;
435
          if (strcmp(session->name, multiarg_OK[i]) == 0)
409
410
        if (ign_backslash == TRUE)
411
          {
412
          /* check if backslash precedes delimiter */
413
414
          if ((ptr > start) && (*(ptr-1) == '\\'))
415
            {
436
            {
416
            /* check if backslash is backslashed */
437
            permit_multi = 1;
417
438
            break;
418
            if ((ptr > start + 1) && (*(ptr-2) != '\\'))
419
              {
420
              /* delimiter is backslashed, ignore */
421
422
              ignore = FALSE;
423
              
424
              sq_count--;
425
              }
426
            }
439
            }
427
          }
428
429
        if (ignore == TRUE)
430
          {
431
          ptr++;
432
433
          ignchar = TRUE;
434
          }
435
        }
440
        }
436
      }
437
    else if (*ptr == '\"')
438
      {
439
      dq_count++;
440
441
441
      if ((head != NULL) && !(sq_count % 2) && !(dq_count % 2))
442
      if (permit_multi)
442
        {
443
        {
443
        ptr++;
444
        *name = session->name;
444
445
        *value = session->curpos;
445
        ignchar = TRUE;
446
        if (*p != '\0')
446
        }
447
      else 
448
        {
449
        ignore = TRUE;
450
451
        if (ign_backslash == TRUE)
452
          {
447
          {
453
          /* check if backslash precedes delimiter */
448
          *p = '\0';
454
449
          session->curpos = p + 1;
455
          if ((ptr > start) && (*(ptr-1) == '\\'))
456
            {
457
            /* check if backslash is backslashed */
458
459
            if ((ptr > start + 1) && (*(ptr-2) != '\\'))
460
              {
461
              /* delimiter is backslashed, ignore */
462
463
              ignore = FALSE;
464
              
465
              dq_count--;
466
              }
467
            }
468
          }
450
          }
451
        else
452
          session->curpos = p;
469
453
470
        if (ignore == TRUE)
454
        goto _try_to_return_result;
471
          {
472
          ptr++;
473
474
          ignchar = TRUE;
475
          }
476
        }
455
        }
477
      }
478
    else if (*ptr == '[' )
479
      {
480
      sb_count = 1;
481
      }
482
    else if (*ptr == ']')
483
      {
484
      sb_count = 0;
485
      }
486
    else if (*ptr == '{')
487
      {
488
      sb_count = 1;
489
      }
490
    else if (*ptr == '}')
491
      {
492
      sb_count = 0;
493
      }
494
    else if (!(sq_count % 2) && !(dq_count % 2) && (sb_count == 0))
495
      {
496
      /* not in quotations, locate delimiter */
497
498
      for (dindex = 0; delims[dindex] != '\0'; dindex++)
499
        {
500
        if (*ptr != delims[dindex])
501
          continue;
502
456
503
        if ((ign_backslash == TRUE) && (head != NULL))
457
      session->flags |= PNV_BADSYNTAX;
504
          {
458
      return (-2);
505
          /* check if backslash precedes delimiter */
506
          if ((ptr > head) && (*(ptr-1) == '\\'))
507
            {
508
            /* check if backslash is backslashed */
509
510
            if ((ptr > head + 1) && (*(ptr-1) != '\\'))
511
              {
512
              /* delimiter is backslashed, ignore */
513
514
              continue;
515
              }
516
            }
517
          }
518
519
        /* delimiter found */
520
521
        *ptr = '\0';
522
        
523
        ptr++;
524
        
525
        if (head != NULL)
526
          {
527
          *ptrPtr = ptr;
528
529
          tmpLine[tindex] = '\0';
530
          
531
          if (tindex > 0)
532
            strcpy(head,tmpLine);
533
          
534
          free(tmpLine);
535
536
          return(head);
537
          }
538
539
        ignchar = TRUE;
540
541
        break;
542
        } /* END for (dindex) */
543
      }
544
545
    if ((ignchar != TRUE) && (*ptr != '\0'))
546
      {
547
      if (head == NULL)
548
        head = ptr;
549
550
      tmpLine[tindex++] = ptr[0];
551
552
      ptr++;
553
      }
459
      }
460
    }
554
461
555
    ignchar = FALSE;
462
  /* Cache current name and skip blanks */
556
    } /* END while (*ptr != '\0') */
463
  *p = '\0';
557
464
  session->name = session->curpos;
558
  tmpLine[tindex] = '\0';
465
  p++;
559
466
  while (isspace(*p))
560
  if (tindex > 0)
467
    p++;
561
    strcpy(head,tmpLine);
468
  session->curpos = p;
562
563
  free(tmpLine);
564
565
  *ptrPtr = ptr;
566
567
  return(head);
568
  } /* END smart_strtok */
569
570
571
572
469
470
  /* Look for the value */
471
  for (; *p != '\0' && *p != ','; p++);
573
472
574
int get_name_value(start, name, value)
473
  *name = session->name;
575
char  *start;
474
  *value = session->curpos;
576
char **name;
475
  if (*p != '\0')
577
char **value;
578
  {
579
  static char *tok_ptr;
580
  char *curr_ptr;
581
  char *equals;
582
  static char tmpLine[65536];
583
  char *s;
584
585
  /* we've reached the end */
586
  if ((start == NULL) &&
587
      (*tok_ptr == '\0'))
588
    return(0);
589
590
  s = NULL;
591
  /* XXX: may truncate input */
592
  if (start != NULL)
593
    {
476
    {
594
    strncpy(tmpLine, start, sizeof(tmpLine));
477
    *p = '\0';
595
    tmpLine[sizeof(tmpLine) - 1] = '\0';
478
    session->curpos = p + 1;
596
    s = tmpLine;
597
    }
479
    }
480
  else
481
    session->curpos = p;
598
482
599
  curr_ptr = smart_strtok(s,",",&tok_ptr,FALSE);
483
_try_to_return_result:
600
484
  /*
601
  if ((curr_ptr == NULL))
485
   * Almost done, need to strip trailing blanks
602
    return(0);
486
   * and check empty name/value.
603
     
487
   */
604
  if ((*curr_ptr == '=') || 
488
  chomp_blanks(*name);
605
      (*curr_ptr == '\0'))
489
  chomp_blanks(*value);
490
  if (**name == '\0' || **value == '\0')
606
    {
491
    {
607
    /* no name, fail */
492
    session->flags |= PNV_BADSYNTAX;
608
    return(-1);
493
    return (-2);
609
    }
494
    }
610
495
611
  /* skip leading spaces */
496
  return (1);
612
  while (isspace((int)*curr_ptr) && (*curr_ptr))
497
  }  /* END get_name_value() */
613
    curr_ptr++;
614
615
  *name = curr_ptr;
616
617
  equals = *name;
618
619
  /* skip over name */
620
  while ((*equals) && (!isspace((int)*equals)) && (*equals != '='))
621
    equals++;
622
623
  /* strip blanks */
624
  while ((*equals) && (isspace((int)*equals)))
625
    *equals++ = '\0';
626
627
  if (*equals != '=')
628
    return (-1); /* should have found a = as first non blank */
629
630
  *equals++ = '\0';
631
632
  /* skip leading white space */
633
  while (isspace((int)*equals) && *equals)
634
    equals++;
635
498
636
  if (*equals == '\0')
637
    return(-1);
638
499
639
  *value = equals;
500
/*
501
 * Frees memory associated with name/value parsing session.
502
 */
503
void free_name_value_session(session)
504
struct parse_name_value *session;
505
  {
506
  assert(session != NULL);
640
507
641
  return (1);
508
  if (session->buffer != NULL)
642
  }
509
    free((void *)session->buffer);
510
  bzero((void *)session, sizeof(*session));
511
  }  /* END free_name_value_session */
643
512
644
513
645
514
 Lines 2948-2953   int process_opts( Link Here 
2948
  int nitems;
2817
  int nitems;
2949
  char search_string[256];
2818
  char search_string[256];
2950
2819
2820
  struct parse_name_value gnv_session;
2821
2822
  /*
2823
   * Array of directives for -W for which we permit
2824
   * multivalued specifications like name=value1,value2,value3.
2825
   * Must be NULL-terminated.
2826
   */
2827
  static const char *optW_multiarg[] = {
2828
    "stagein", "stageout",
2829
    NULL
2830
  };
2831
2951
#if !defined(PBS_NO_POSIX_VIOLATION)
2832
#if !defined(PBS_NO_POSIX_VIOLATION)
2952
#define GETOPT_ARGS "a:A:b:c:C:d:D:e:fF:hIJ:j:k:l:m:M:N:o:p:P:q:r:S:t:T:u:v:Vw:W:Xxz-:"
2833
#define GETOPT_ARGS "a:A:b:c:C:d:D:e:fF:hIJ:j:k:l:m:M:N:o:p:P:q:r:S:t:T:u:v:Vw:W:Xxz-:"
2953
#else
2834
#else
 Lines 3933-3939   int process_opts( Link Here 
3933
          break;
3814
          break;
3934
          }
3815
          }
3935
3816
3936
        i = get_name_value(optarg, &keyword, &valuewd);
3817
        i = get_name_value(&gnv_session, optarg,
3818
          &keyword, &valuewd, optW_multiarg);
3937
3819
3938
        if (i != 1)
3820
        if (i != 1)
3939
          {
3821
          {
 Lines 3944-3950   int process_opts( Link Here 
3944
          snprintf(tmpLine, sizeof(tmpLine), "x=%s",
3826
          snprintf(tmpLine, sizeof(tmpLine), "x=%s",
3945
                   optarg);
3827
                   optarg);
3946
3828
3947
          i = get_name_value(tmpLine, &keyword, &valuewd);
3829
          i = get_name_value(&gnv_session, tmpLine,
3830
            &keyword, &valuewd, optW_multiarg);
3948
          }
3831
          }
3949
3832
3950
        while (i == 1)
3833
        while (i == 1)
 Lines 4043-4052    Link Here 
4043
            set_attr(&attrib, keyword, valuewd);
4043
            set_attr(&attrib, keyword, valuewd);
4044
            }
4044
            }
4045
4045
4046
          i = get_name_value(NULL, &keyword, &valuewd);
4046
          i = get_name_value(&gnv_session, NULL,
4047
            &keyword, &valuewd, optW_multiarg);
4047
          }  /* END while (i == 1) */
4048
          }  /* END while (i == 1) */
4048
4049
4049
        if (i == -1)
4050
        if (i == -2)
4050
          {
4051
          {
4051
          fprintf(stderr, "qsub: illegal -W value '%s' "
4052
          fprintf(stderr, "qsub: illegal -W value '%s' "
4052
            "for keyword '%s'\n", valuewd, keyword);
4053
            "for keyword '%s'\n", valuewd, keyword);
 Lines 4054-4059    Link Here 
4054
          errflg++;
4055
          errflg++;
4055
          }
4056
          }
4056
4057
4058
        if (i == -1)
4059
          {
4060
          fprintf(stderr, "qsub: not enough memory to parse -W value\n");
4061
4062
          errflg++;
4063
          }
4064
4057
        break;
4065
        break;
4058
4066
4059
#if !defined(PBS_NO_POSIX_VIOLATION)
4067
#if !defined(PBS_NO_POSIX_VIOLATION)