Exemplo n.º 1
0
int getpart(char **outbuf, size_t *outlen,
            const char *main, const char *sub, FILE *stream)
{
# define MAX_TAG_LEN 79
  char couter[MAX_TAG_LEN+1]; /* current outermost section */
  char cmain[MAX_TAG_LEN+1];  /* current main section */
  char csub[MAX_TAG_LEN+1];   /* current sub section */
  char ptag[MAX_TAG_LEN+1];   /* potential tag */
  char patt[MAX_TAG_LEN+1];   /* potential attributes */
  char *buffer = NULL;
  char *ptr;
  char *end;
  union {
    ssize_t sig;
     size_t uns;
  } len;
  size_t bufsize = 0;
  size_t outalloc = 256;
  int in_wanted_part = 0;
  int base64 = 0;
  int error;

  enum {
    STATE_OUTSIDE = 0,
    STATE_OUTER   = 1,
    STATE_INMAIN  = 2,
    STATE_INSUB   = 3,
    STATE_ILLEGAL = 4
  } state = STATE_OUTSIDE;

  *outlen = 0;
  *outbuf = malloc(outalloc);
  if(!*outbuf)
    return GPE_OUT_OF_MEMORY;
  *(*outbuf) = '\0';

  couter[0] = cmain[0] = csub[0] = ptag[0] = patt[0] = '\0';

  while((error = readline(&buffer, &bufsize, stream)) == GPE_OK) {

    ptr = buffer;
    EAT_SPACE(ptr);

    if('<' != *ptr) {
      if(in_wanted_part) {
        show(("=> %s", buffer));
        error = appenddata(outbuf, outlen, &outalloc, buffer, base64);
        if(error)
          break;
      }
      continue;
    }

    ptr++;

    if('/' == *ptr) {
      /*
      ** closing section tag
      */

      ptr++;
      end = ptr;
      EAT_WORD(end);
      if((len.sig = end - ptr) > MAX_TAG_LEN) {
        error = GPE_NO_BUFFER_SPACE;
        break;
      }
      memcpy(ptag, ptr, len.uns);
      ptag[len.uns] = '\0';

      if((STATE_INSUB == state) && !strcmp(csub, ptag)) {
        /* end of current sub section */
        state = STATE_INMAIN;
        csub[0] = '\0';
        if(in_wanted_part) {
          /* end of wanted part */
          in_wanted_part = 0;
          break;
        }
      }
      else if((STATE_INMAIN == state) && !strcmp(cmain, ptag)) {
        /* end of current main section */
        state = STATE_OUTER;
        cmain[0] = '\0';
        if(in_wanted_part) {
          /* end of wanted part */
          in_wanted_part = 0;
          break;
        }
      }
      else if((STATE_OUTER == state) && !strcmp(couter, ptag)) {
        /* end of outermost file section */
        state = STATE_OUTSIDE;
        couter[0] = '\0';
        if(in_wanted_part) {
          /* end of wanted part */
          in_wanted_part = 0;
          break;
        }
      }

    }
    else if(!in_wanted_part) {
      /*
      ** opening section tag
      */

      /* get potential tag */
      end = ptr;
      EAT_WORD(end);
      if((len.sig = end - ptr) > MAX_TAG_LEN) {
        error = GPE_NO_BUFFER_SPACE;
        break;
      }
      memcpy(ptag, ptr, len.uns);
      ptag[len.uns] = '\0';

      /* ignore comments, doctypes and xml declarations */
      if(('!' == ptag[0]) || ('?' == ptag[0])) {
        show(("* ignoring (%s)", buffer));
        continue;
      }

      /* get all potential attributes */
      ptr = end;
      EAT_SPACE(ptr);
      end = ptr;
      while(*end && ('>' != *end))
        end++;
      if((len.sig = end - ptr) > MAX_TAG_LEN) {
        error = GPE_NO_BUFFER_SPACE;
        break;
      }
      memcpy(patt, ptr, len.uns);
      patt[len.uns] = '\0';

      if(STATE_OUTSIDE == state) {
        /* outermost element (<testcase>) */
        strcpy(couter, ptag);
        state = STATE_OUTER;
        continue;
      }
      else if(STATE_OUTER == state) {
        /* start of a main section */
        strcpy(cmain, ptag);
        state = STATE_INMAIN;
        continue;
      }
      else if(STATE_INMAIN == state) {
        /* start of a sub section */
        strcpy(csub, ptag);
        state = STATE_INSUB;
        if(!strcmp(cmain, main) && !strcmp(csub, sub)) {
          /* start of wanted part */
          in_wanted_part = 1;
          if(strstr(patt, "base64="))
              /* bit rough test, but "mostly" functional, */
              /* treat wanted part data as base64 encoded */
              base64 = 1;
        }
        continue;
      }

    }

    if(in_wanted_part) {
      show(("=> %s", buffer));
      error = appenddata(outbuf, outlen, &outalloc, buffer, base64);
      if(error)
        break;
    }

  } /* while */

  if(buffer)
    free(buffer);

  if(error != GPE_OK) {
    if(error == GPE_END_OF_FILE)
      error = GPE_OK;
    else {
      if(*outbuf)
        free(*outbuf);
      *outbuf = NULL;
      *outlen = 0;
    }
  }

  return error;
}
Exemplo n.º 2
0
const char *spitout(FILE *stream,
                    const char *main,
                    const char *sub, size_t *size)
{
  char buffer[8192]; /* big enough for anything */
  char cmain[128]=""; /* current main section */
  char csub[128]="";  /* current sub section */
  char *ptr;
  char *end;
  char display = 0;

  char *string;
  size_t stringlen=0;
  size_t stralloc=256;
  char base64 = 0; /* set to 1 if true */

  enum {
    STATE_OUTSIDE,
    STATE_OUTER,
    STATE_INMAIN,
    STATE_INSUB,
    STATE_ILLEGAL
  } state = STATE_OUTSIDE;

  string = malloc(stralloc);
  if(!string)
    return NULL;

  string[0] = 0; /* zero first byte in case of no data */

  while(fgets(buffer, sizeof(buffer), stream)) {

    ptr = buffer;

    /* pass white spaces */
    EAT_SPACE(ptr);

    if('<' != *ptr) {
      if(display) {
        show(("=> %s", buffer));
        string = appendstring(string, buffer, &stringlen, &stralloc, base64);
        show(("* %s\n", buffer));
      }
      continue;
    }

    ptr++;
    EAT_SPACE(ptr);

    if('/' == *ptr) {
      /* end of a section */
      ptr++;
      EAT_SPACE(ptr);

      end = ptr;
      EAT_WORD(end);
      *end = 0;

      if((state == STATE_INSUB) &&
         !strcmp(csub, ptr)) {
        /* this is the end of the currently read sub section */
        state--;
        csub[0]=0; /* no sub anymore */
        display=0;
      }
      else if((state == STATE_INMAIN) &&
              !strcmp(cmain, ptr)) {
        /* this is the end of the currently read main section */
        state--;
        cmain[0]=0; /* no main anymore */
        display=0;
      }
      else if(state == STATE_OUTER) {
        /* this is the end of the outermost file section */
        state--;
      }
    }
    else if(!display) {
      /* this is the beginning of a section */
      end = ptr;
      EAT_WORD(end);

      *end = 0;
      switch(state) {
      case STATE_OUTSIDE:
        /* Skip over the outermost element (<testcase>), but if it turns out
           to be a comment, completely ignore it below */
        strcpy(cmain, ptr);
        state = STATE_OUTER;
        break;
      case STATE_OUTER:
        strcpy(cmain, ptr);
        state = STATE_INMAIN;
        break;
      case STATE_INMAIN:
        strcpy(csub, ptr);
        state = STATE_INSUB;
        break;
      default:
        break;
      }

      if(!end[1] != '>') {
        /* There might be attributes here. Check for those we know of and care
           about. */
        if(strstr(&end[1], "base64=")) {
          /* rough and dirty, but "mostly" functional */
          /* Treat all data as base64 encoded */
          base64 = 1;
        }
      }
    }
    if(display) {
      string = appendstring(string, buffer, &stringlen, &stralloc, base64);
      show(("* %s\n", buffer));
    }

    if((STATE_INSUB == state) &&
       !strcmp(cmain, main) &&
       !strcmp(csub, sub)) {
      show(("* (%d bytes) %s\n", stringlen, buffer));
      display = 1; /* start displaying */
    }
    else if ((*cmain == '?') || (*cmain == '!') || (*csub == '!')) {
        /* Ignore comments, DOCTYPEs and XML declarations */
        show(("%d ignoring (%s/%s)\n", state, cmain, csub));
        state--;
    }
    else {
      show(("%d (%s/%s): %s\n", state, cmain, csub, buffer));
      display = 0; /* no display */
    }
  }

  *size = stringlen;
  return string;
}