~ubuntu-branches/debian/experimental/ncbi-tools6/experimental

« back to all changes in this revision

Viewing changes to demo/testcgi.c

  • Committer: Bazaar Package Importer
  • Author(s): Aaron M. Ucko
  • Date: 2008-07-14 19:43:15 UTC
  • mfrom: (2.1.12 intrepid)
  • Revision ID: james.westby@ubuntu.com-20080714194315-ed44u9ek7txva2rz
Tags: 6.1.20080302-3
tools/readdb.c: enable madvise()-based code on all glibc (hence all
Debian) systems, not just Linux.  (Closes: #490437.)

Show diffs side-by-side

added added

removed removed

Lines of Context:
29
29
*
30
30
* Version Creation Date:   4/24/98
31
31
*
32
 
* $Revision: 6.32 $
 
32
* $Revision: 6.37 $
33
33
*
34
34
* File Description: 
35
35
*
104
104
#endif
105
105
 
106
106
#ifndef MIN
107
 
#define MIN(a,b)        ((a)>(b)?(b):(a))
 
107
#define MIN(a,b) ((a)>(b)?(b):(a))
108
108
#endif
109
109
 
110
110
/* useful portable character macros from NCBI toolkit (assumes ASCII) */
111
111
 
112
 
#define IS_DIGIT(c)     ('0'<=(c) && (c)<='9')
113
 
#define IS_UPPER(c)     ('A'<=(c) && (c)<='Z')
114
 
#define IS_LOWER(c)     ('a'<=(c) && (c)<='z')
115
 
#define IS_ALPHA(c)     (IS_UPPER(c) || IS_LOWER(c))
116
 
#define TO_LOWER(c)     ((Char)(IS_UPPER(c) ? (c)+' ' : (c)))
117
 
#define TO_UPPER(c)     ((Char)(IS_LOWER(c) ? (c)-' ' : (c)))
 
112
#define IS_DIGIT(c) ('0'<=(c) && (c)<='9')
 
113
#define IS_UPPER(c) ('A'<=(c) && (c)<='Z')
 
114
#define IS_LOWER(c) ('a'<=(c) && (c)<='z')
 
115
#define IS_ALPHA(c) (IS_UPPER(c) || IS_LOWER(c))
 
116
#define TO_LOWER(c) ((Char)(IS_UPPER(c) ? (c)+' ' : (c)))
 
117
#define TO_UPPER(c) ((Char)(IS_LOWER(c) ? (c)-' ' : (c)))
118
118
#define IS_WHITESP(c) (((c) == ' ') || ((c) == '\n') || ((c) == '\r') || ((c) == '\t'))
119
119
#define IS_ALPHANUM(c) (IS_ALPHA(c) || IS_DIGIT(c))
120
 
#define IS_PRINT(c)     (' '<=(c) && (c)<='~')
 
120
#define IS_PRINT(c) (' '<=(c) && (c)<='~')
121
121
 
122
122
/* url decode/encode functions modified from NCBI toolkit */
123
123
 
173
173
};
174
174
#define VALID_URL_SYMBOL(ch)  (s_Encode[(unsigned char)ch][0] != '%')
175
175
 
176
 
static Bool Url_Decode
177
 
(const void* src_buf,
178
 
 size_t      src_size,
179
 
 size_t*     src_read,
180
 
 void*       dst_buf,
181
 
 size_t      dst_size,
182
 
 size_t*     dst_written)
 
176
static Bool Url_Decode (
 
177
  const void* src_buf,
 
178
  size_t      src_size,
 
179
  size_t*     src_read,
 
180
  void*       dst_buf,
 
181
  size_t      dst_size,
 
182
  size_t*     dst_written
 
183
)
 
184
 
183
185
{
184
186
  unsigned char *src = (unsigned char*)src_buf;
185
187
  unsigned char *dst = (unsigned char*)dst_buf;
228
230
  return TRUE;
229
231
}
230
232
 
231
 
static void Url_Encode
232
 
(const void* src_buf,
233
 
 size_t      src_size,
234
 
 size_t*     src_read,
235
 
 void*       dst_buf,
236
 
 size_t      dst_size,
237
 
 size_t*     dst_written)
 
233
static void Url_Encode (
 
234
  const void* src_buf,
 
235
  size_t      src_size,
 
236
  size_t*     src_read,
 
237
  void*       dst_buf,
 
238
  size_t      dst_size,
 
239
  size_t*     dst_written
 
240
)
 
241
 
238
242
{
239
243
  unsigned char *src = (unsigned char*)src_buf;
240
244
  unsigned char *dst = (unsigned char*)dst_buf;
340
344
  size_t   len;
341
345
  CharPtr  ptr;
342
346
 
343
 
/*
344
 
*  given a query string enzyme=EcoRI&pattern=GAATTC
345
 
*/
 
347
  /*
 
348
  *  given a query string enzyme=EcoRI&pattern=GAATTC
 
349
  */
346
350
 
347
 
/* The >Message prefix causes Sequin to display the message to the user */
 
351
  /* The >Message prefix causes Sequin to display the message to the user */
348
352
 
349
353
  if (qstr == NULL) {
350
354
    printf ("Content-type: text/html\r\n\r\n");
353
357
    return FALSE;
354
358
  }
355
359
 
356
 
/* allocates a copy of query string that can be modified during parsing */
 
360
  /* allocates a copy of query string that can be modified during parsing */
357
361
 
358
362
  len = strlen (qstr);
359
363
  query = malloc (len + 3);
368
372
  memset (query, 0, len + 2);
369
373
  strcpy (query, qstr);
370
374
 
371
 
/* parse tag=value&tag=value query into arrays for easier interpretation */
 
375
  /* parse tag=value&tag=value query into arrays for easier interpretation */
372
376
 
373
377
  memset (tag, 0, sizeof (tag));
374
378
  memset (val, 0, sizeof (val));
383
387
    }
384
388
  }
385
389
 
386
 
/*
387
 
*  given the above query example, the tag and val arrays are now:
388
 
*
389
 
*   tag [0] = "enzyme"    val [0] = "EcoRI"
390
 
*   tag [1] = "pattern"   val [1] = "GAATTC"
391
 
*   tag [2] = NULL        val [2] = NULL
392
 
*
393
 
*  and num_tags is 2
394
 
*/
 
390
  /*
 
391
  *  given the above query example, the tag and val arrays are now:
 
392
  *
 
393
  *   tag [0] = "enzyme"    val [0] = "EcoRI"
 
394
  *   tag [1] = "pattern"   val [1] = "GAATTC"
 
395
  *   tag [2] = NULL        val [2] = NULL
 
396
  *
 
397
  *  and num_tags is 2
 
398
  */
395
399
 
396
 
/* verify that any required query string is present in the URL */
 
400
  /* verify that any required query string is present in the URL */
397
401
 
398
402
  if (queryRequired && num_tags == 0) {
399
403
    printf ("Content-type: text/html\r\n\r\n");
411
415
{
412
416
  Int2  i;
413
417
 
414
 
/* search the tag array for the desired name, returning the associated value */
 
418
  /* search the tag array for the desired name, returning the associated value */
415
419
 
416
420
  if (find == NULL) return NULL;
417
421
  for (i = 0; i < num_tags; i++) {
428
432
{
429
433
  Int2  i;
430
434
 
431
 
/* search a null-terminated array of strings, returning an integer index */
 
435
  /* search a null-terminated array of strings, returning an integer index */
432
436
 
433
437
  if (str == NULL || list == NULL) return -1;
434
438
  for (i = 0; list [i] != NULL; i++) {
456
460
  CharPtr   program;
457
461
  long int  val;
458
462
 
459
 
/* protect against custom requests on public server */
 
463
  /* protect against custom requests on public server */
460
464
 
461
465
  port = getenv ("SERVER_PORT");
462
466
  if (port != NULL) {
465
469
    }
466
470
  }
467
471
 
468
 
/* program argument would be actual path on cgi server machine */
 
472
  /* program argument would be actual path on cgi server machine */
469
473
 
470
474
  program = FindByName ("program");
471
475
  if (program == NULL) {
474
478
    return;
475
479
  }
476
480
 
477
 
/* method defaults to sending data to program via stdin */
 
481
  /* method defaults to sending data to program via stdin */
478
482
 
479
483
  method = FindByName ("method");
480
484
  if (method == NULL || strstr (method, "stdin") != NULL) {
487
491
    meth = SEND_STDIN;
488
492
  }
489
493
 
490
 
/* note that for arguments, %20 in a query string is converted to a space */
 
494
  /* note that for arguments, %20 in a query string is converted to a space */
491
495
 
492
496
  arguments = FindByName ("arguments");
493
497
  if (arguments == NULL) {
494
498
    arguments = "";
495
499
  }
496
500
 
497
 
/* launch program sending arguments and filename or data in appropriate order */
 
501
  /* launch program sending arguments and filename or data in appropriate order */
498
502
 
499
503
  switch (meth) {
500
504
    case SEND_FILENAME_ARGS_BEFORE :
511
515
  fp = popen (cmmd, "r");
512
516
  if (fp == NULL) return;
513
517
 
514
 
/* assumes program sends output to stdout */
 
518
  /* assumes program sends output to stdout */
515
519
 
516
520
  while ((ct = fread (buf, 1, sizeof (buf), fp)) > 0) {
517
521
    EncodeAndWrite (buf, ct, stdout);
529
533
  FILE*   fp;
530
534
  Bool    headerSent = FALSE;
531
535
 
532
 
/* reconstruct and print the query string */
 
536
  /* reconstruct and print the query string */
533
537
 
534
 
/*
 
538
  /*
535
539
  for (i = 0; i < num_tags; i++) {
536
540
    if (i > 0) {
537
541
      sprintf (buf, "%");
545
549
  sprintf (buf, "\n");
546
550
  EncodeAndWrite (buf, strlen (buf), stdout);
547
551
  fflush (stdout);
548
 
*/
 
552
  */
549
553
 
550
 
/* now echo the data file */
 
554
  /* now echo the data file */
551
555
 
552
556
  fp = fopen (tempfile, "r");
553
557
  if (fp == NULL) return;
556
560
 
557
561
    if (! headerSent) {
558
562
 
559
 
/* send required first header information to stdout */
 
563
      /* send required first header information to stdout */
560
564
 
561
565
      printf ("Content-type: text/html\r\n\r\n");
562
566
      fflush (stdout);
566
570
    EncodeAndWrite (buf, ct, stdout);
567
571
    fflush (stdout);
568
572
  }
 
573
 
569
574
  fclose (fp);
570
575
 
571
576
  if (! headerSent) {
589
594
  Char     tmp [16];
590
595
  CharPtr  window;
591
596
 
592
 
/* launch seg with -x parameter, arguments, and name of data file */
 
597
  /* launch seg with -x parameter, arguments, and name of data file */
593
598
 
594
599
  window = FindByName ("window");
595
600
  if (window == NULL) {
614
619
  fp = popen (cmmd, "r");
615
620
  if (fp == NULL) return;
616
621
 
617
 
/* send processed FASTA data from seg directly to stdout and calling program */
 
622
  /* send processed FASTA data from seg directly to stdout and calling program */
618
623
 
619
624
  while ((ct = fread (buf, 1, sizeof (buf), fp)) > 0) {
620
625
 
621
626
    if (! headerSent) {
622
627
 
623
 
/* send required first header information to stdout */
 
628
    /* send required first header information to stdout */
624
629
 
625
630
      printf ("Content-type: text/html\r\n\r\n");
626
631
      fflush (stdout);
639
644
}
640
645
 
641
646
 
 
647
#if 0
642
648
#define MAX_FIELDS  9
643
649
 
644
650
static void RunTrnaScan (CharPtr tempfile)
645
651
 
646
652
{
647
653
  CharPtr   aa;
 
654
  CharPtr   anticodonSeq;
 
655
  CharPtr   arg1 = "";
 
656
  CharPtr   arg2 = "";
648
657
  CharPtr   beg;
649
658
  Char      buf [256];
650
659
  Char      cmmd [256];
 
660
  CharPtr   domain;
651
661
  CharPtr   end;
 
662
  CharPtr   extras;
652
663
  CharPtr   field [MAX_FIELDS];
653
664
  FILE*     fp;
654
665
  Bool      headerSent = FALSE;
666
677
  long int  stop;
667
678
  Char      str [80];
668
679
 
669
 
/* launch tRNAscan-SE with -q parameter and name of data file */
 
680
  /* launch tRNAscan-SE with -q parameter and name of data file */
670
681
 
671
682
  speed = FindByName ("speed");
672
 
  if (speed != NULL && strcmp (speed, "slow") == 0) {
673
 
    sprintf (cmmd, "./tRNAscan-SE -q -C %s", tempfile);
674
 
  } else {
675
 
    sprintf (cmmd, "./tRNAscan-SE -q %s", tempfile);
676
 
  }
 
683
  domain = FindByName ("domain");
 
684
  extras = FindByName ("extras");
 
685
 
 
686
  if (speed != NULL) {
 
687
    if (strcmp (speed, "slow") == 0) {
 
688
      arg1 = "-C ";
 
689
    }
 
690
  }
 
691
 
 
692
  if (domain != NULL) {
 
693
    if (strcmp (domain, "eukaryote") == 0) {
 
694
      arg2 = "";
 
695
    } else if (strcmp (domain, "prokaryote") == 0) {
 
696
      arg2 = "-P ";
 
697
    } else if (strcmp (domain, "archaea") == 0) {
 
698
      arg2 = "-A ";
 
699
    } else if (strcmp (domain, "organelle") == 0) {
 
700
      arg2 = "-O ";
 
701
    } else if (strcmp (domain, "general") == 0) {
 
702
      arg2 = "-G ";
 
703
    }
 
704
  }
 
705
 
 
706
  sprintf (cmmd, "./tRNAscan-SE -q %s%s%s", arg1, arg2, tempfile);
677
707
 
678
708
  fp = popen (cmmd, "r");
679
709
  if (fp == NULL) return;
680
710
 
681
 
/* line by line processing of tRNAscan-SE output table */
 
711
  /* line by line processing of tRNAscan-SE output table */
682
712
 
683
713
  while (fgets (buf, sizeof (buf), fp) != NULL) {
684
714
 
685
715
    if (! headerSent) {
686
716
 
687
 
/* send required first header information to stdout */
 
717
      /* send required first header information to stdout */
688
718
 
689
719
      printf ("Content-type: text/html\r\n\r\n");
690
720
      fflush (stdout);
694
724
    if (inBody) {
695
725
      memset (field, 0, sizeof (field));
696
726
 
697
 
/*
698
 
*  parse tab-delimited output line into array of fields, avoiding use of
699
 
*  strtok so that empty columns (adjacent tabs) are properly assigned to
700
 
*  field array
701
 
*/
 
727
      /*
 
728
      *  parse tab-delimited output line into array of fields, avoiding use of
 
729
      *  strtok so that empty columns (adjacent tabs) are properly assigned to
 
730
      *  field array
 
731
      */
702
732
 
703
733
      ptr = buf;
704
734
      for (numFields = 0; numFields < MAX_FIELDS && ptr != NULL; numFields++) {
710
740
        }
711
741
      }
712
742
 
713
 
/* interested in ID, start, stop, amino acid, and intron start and stop */
 
743
      /* interested in ID, start, stop, amino acid, and intron start and stop */
714
744
 
715
745
      id = field [0];
716
746
      beg = field [2];
717
747
      end = field [3];
718
748
      aa = field [4];
 
749
      anticodonSeq = field [5];
719
750
      intronBeg = field [6];
720
751
      intronEnd = field [7];
721
752
 
725
756
          sscanf (intronBeg, "%ld", &intronStart) == 1 &&
726
757
          sscanf (intronEnd, "%ld", &intronStop) == 1) {
727
758
 
728
 
/* first line of output gives SeqId from FASTA definition line */
 
759
        /* first line of output gives SeqId from FASTA definition line */
729
760
 
730
761
        if (idNotSent) {
731
762
          sprintf (str, ">Features %s tRNAscan-SE\n", id);
734
765
          idNotSent = FALSE;
735
766
        }
736
767
 
737
 
/* first line of feature has start (tab) stop (tab) feature key */
738
 
/* multiple intervals would have lines of start (tab) stop */
 
768
        /* first line of feature has start (tab) stop (tab) feature key */
 
769
        /* multiple intervals would have lines of start (tab) stop */
739
770
 
740
771
        if (intronStart == 0 && intronStop == 0) {
741
772
          sprintf (str, "%ld\t%ld\ttRNA\n", (long) start, (long) stop);
750
781
          fflush (stdout);
751
782
        }
752
783
 
753
 
/* qualifier lines are (tab) (tab) (tab) qualifier key (tab) value */
 
784
        /* qualifier lines are (tab) (tab) (tab) qualifier key (tab) value */
754
785
 
755
786
        if (strstr (aa, "Pseudo") != NULL) {
756
787
          sprintf (str, "\t\t\tnote\ttRNA-Pseudo\n");
762
793
          fflush (stdout);
763
794
        }
764
795
 
765
 
/* dash (formerly empty) gene qualifier to suppress /gene (e.g., if tRNA is in an intron) */
 
796
        /* introducing special qualifier to report anticodon sequence if requested */
 
797
 
 
798
        if (extras != NULL && strcmp (extras, "anticodon") == 0) {
 
799
          sprintf (str, "\t\t\tanti_codon_seq\t%s\n", anticodonSeq);
 
800
          EncodeAndWrite (str, strlen (str), stdout);
 
801
          fflush (stdout);
 
802
        }
 
803
 
 
804
        /* dash (formerly empty) gene qualifier to suppress /gene (e.g., if tRNA is in an intron) */
766
805
 
767
806
        sprintf (str, "\t\t\tgene\t-\n");
768
807
        EncodeAndWrite (str, strlen (str), stdout);
770
809
      }
771
810
    }
772
811
 
773
 
/* detect last line of table header, ignoring everything before data section */
 
812
    /* detect last line of table header, ignoring everything before data section */
774
813
 
775
814
    if (strstr (buf, "-----") != NULL) {
776
815
      inBody = TRUE;
777
816
    }
778
817
  }
 
818
 
779
819
  pclose (fp);
780
820
 
781
821
  if (! headerSent) {
789
829
    fflush (stdout);
790
830
  }
791
831
}
 
832
#endif
 
833
 
 
834
static CharPtr IsolateString (CharPtr str, Char ch)
 
835
 
 
836
{
 
837
  CharPtr  ptr;
 
838
 
 
839
  if (str == NULL || ch == '\0') return NULL;
 
840
  ptr = strchr (str, ch);
 
841
  if (ptr != NULL) {
 
842
    *ptr = '\0';
 
843
    ptr++;
 
844
  }
 
845
  return ptr;
 
846
}
 
847
 
 
848
static Bool ParseRange (CharPtr str, Int4Ptr startP, Int4Ptr stopP)
 
849
 
 
850
{
 
851
  CharPtr   nxt;
 
852
  CharPtr   ptr;
 
853
  long int  start = 0;
 
854
  long int  stop = 0;
 
855
 
 
856
  if (str == NULL || startP == NULL || stopP == NULL) return FALSE;
 
857
  *startP = 0;
 
858
  *stopP = 0;
 
859
 
 
860
  nxt = IsolateString (str, '(');
 
861
  if (nxt == NULL) return FALSE;
 
862
 
 
863
  ptr = nxt;
 
864
  nxt = IsolateString (ptr, '-');
 
865
  if (nxt == NULL) return FALSE;
 
866
 
 
867
  if (sscanf (ptr, "%ld", &start) != 1) return FALSE;
 
868
 
 
869
  ptr = nxt;
 
870
  nxt = IsolateString (ptr, ')');
 
871
  if (nxt == NULL) return FALSE;
 
872
 
 
873
  if (sscanf (ptr, "%ld", &stop) != 1) return FALSE;
 
874
 
 
875
  *startP = start;
 
876
  *stopP = stop;
 
877
 
 
878
  return TRUE;
 
879
}
 
880
 
 
881
static void RunTrnaScan (CharPtr tempfile)
 
882
 
 
883
{
 
884
  Char      aa [32];
 
885
  long int  anticodonStart;
 
886
  long int  anticodonStop;
 
887
  CharPtr   arg1 = "";
 
888
  CharPtr   arg2 = "";
 
889
  CharPtr   arg3 = "";
 
890
  CharPtr   beg;
 
891
  Char      buf [512];
 
892
  Char      cmmd [256];
 
893
  CharPtr   domain;
 
894
  CharPtr   end;
 
895
  FILE*     fp;
 
896
  CharPtr   gencode;
 
897
  Char      id [64];
 
898
  Int2      idNotSent = TRUE;
 
899
  CharPtr   intronBeg;
 
900
  CharPtr   intronEnd;
 
901
  long int  intronStart;
 
902
  long int  intronStop;
 
903
  CharPtr   nxt;
 
904
  Bool      pseudo;
 
905
  CharPtr   ptr;
 
906
  CharPtr   speed;
 
907
  long int  start;
 
908
  long int  stop;
 
909
  Char      str [256];
 
910
 
 
911
  /* launch tRNAscan-SE with -q parameter and name of data file */
 
912
 
 
913
  speed = FindByName ("speed");
 
914
  domain = FindByName ("domain");
 
915
  gencode = FindByName ("gencode");
 
916
 
 
917
  if (speed != NULL) {
 
918
    if (strcmp (speed, "slow") == 0) {
 
919
      arg1 = "-C ";
 
920
    }
 
921
  }
 
922
 
 
923
  if (domain != NULL) {
 
924
    if (strcmp (domain, "eukaryote") == 0) {
 
925
      arg2 = "";
 
926
    } else if (strcmp (domain, "prokaryote") == 0) {
 
927
      arg2 = "-P ";
 
928
    } else if (strcmp (domain, "archaea") == 0) {
 
929
      arg2 = "-A ";
 
930
    } else if (strcmp (domain, "organelle") == 0) {
 
931
      arg2 = "-O ";
 
932
    } else if (strcmp (domain, "general") == 0) {
 
933
      arg2 = "-G ";
 
934
    }
 
935
  }
 
936
 
 
937
  if (gencode != NULL) {
 
938
    if (strcmp (gencode, "standard") == 0) {
 
939
      arg3 = "";
 
940
    } else if (strcmp (gencode, "vertebrate") == 0) {
 
941
      arg3 = "-g gcode.vertmito ";
 
942
    } else if (strcmp (gencode, "yeast") == 0) {
 
943
      arg3 = "-g gcode.ystmito ";
 
944
    } else if (strcmp (gencode, "mold") == 0) {
 
945
      arg3 = "-g gcode.othmito ";
 
946
    } else if (strcmp (gencode, "invertebrate") == 0) {
 
947
      arg3 = "-g gcode.invmito ";
 
948
    } else if (strcmp (gencode, "echinoderm") == 0) {
 
949
      arg3 = "-g gcode.echdmito ";
 
950
    } else if (strcmp (gencode, "ciliate") == 0) {
 
951
      arg3 = "-g gcode.cilnuc ";
 
952
    }
 
953
  }
 
954
 
 
955
  sprintf (cmmd, "./tRNAscan-SE -q -f $ %s%s%s%s", arg1, arg2, arg3, tempfile);
 
956
 
 
957
  fp = popen (cmmd, "r");
 
958
  if (fp == NULL) return;
 
959
 
 
960
  /* send required first header information to stdout */
 
961
 
 
962
  printf ("Content-type: text/html\r\n\r\n");
 
963
  fflush (stdout);
 
964
 
 
965
  /* initialize variables */
 
966
 
 
967
  start = 0;
 
968
  stop = 0;
 
969
  intronStart = 0;
 
970
  intronStop = 0;
 
971
  anticodonStart = 0;
 
972
  anticodonStop = 0;
 
973
  id [0] = '\0';
 
974
  aa [0] = '\0';
 
975
  pseudo = FALSE;
 
976
 
 
977
  /* line by line processing of tRNAscan-SE output table */
 
978
 
 
979
  while (fgets (buf, sizeof (buf), fp) != NULL) {
 
980
 
 
981
    ptr = buf;
 
982
    if (*ptr == '\0') {
 
983
 
 
984
    } else if (strncmp (buf, "Str:", 4) == 0) {
 
985
 
 
986
    } else if (strncmp (buf, "Seq:", 4) == 0) {
 
987
 
 
988
      /* first line of output gives SeqId from FASTA definition line */
 
989
 
 
990
      if (idNotSent) {
 
991
        sprintf (str, ">Features %s tRNAscan-SE\n", id);
 
992
        EncodeAndWrite (str, strlen (str), stdout);
 
993
        fflush (stdout);
 
994
        idNotSent = FALSE;
 
995
      }
 
996
 
 
997
      /* first line of feature has start (tab) stop (tab) feature key */
 
998
      /* multiple intervals would have lines of start (tab) stop */
 
999
 
 
1000
      if (intronStart == 0 && intronStop == 0) {
 
1001
        sprintf (str, "%ld\t%ld\ttRNA\n", (long) start, (long) stop);
 
1002
        EncodeAndWrite (str, strlen (str), stdout);
 
1003
        fflush (stdout);
 
1004
      } else {
 
1005
        sprintf (str, "%ld\t%ld\ttRNA\n", (long) start, (long) (intronStart - 1));
 
1006
        EncodeAndWrite (str, strlen (str), stdout);
 
1007
        fflush (stdout);
 
1008
        sprintf (str, "%ld\t%ld\n", (long) (intronStop + 1), (long) stop);
 
1009
        EncodeAndWrite (str, strlen (str), stdout);
 
1010
        fflush (stdout);
 
1011
      }
 
1012
 
 
1013
      /* qualifier lines are (tab) (tab) (tab) qualifier key (tab) value */
 
1014
 
 
1015
      sprintf (str, "\t\t\tproduct\t%s\n", aa);
 
1016
      EncodeAndWrite (str, strlen (str), stdout);
 
1017
      fflush (stdout);
 
1018
 
 
1019
      if (pseudo) {
 
1020
        sprintf (str, "\t\t\tpseudo\n");
 
1021
        EncodeAndWrite (str, strlen (str), stdout);
 
1022
        fflush (stdout);
 
1023
      } else if (anticodonStart != 0 && anticodonStop != 0) {
 
1024
        if (anticodonStart < anticodonStop) {
 
1025
          sprintf (str, "\t\t\tanticodon\t(pos:%ld..%ld,aa:%s)\n",
 
1026
                   (long) anticodonStart, (long) anticodonStop, aa);
 
1027
          EncodeAndWrite (str, strlen (str), stdout);
 
1028
          fflush (stdout);
 
1029
        } else {
 
1030
          sprintf (str, "\t\t\tanticodon\t(pos:complement(%ld..%ld),aa:%s)\n",
 
1031
                   (long) anticodonStop, (long) anticodonStart, aa);
 
1032
          EncodeAndWrite (str, strlen (str), stdout);
 
1033
          fflush (stdout);
 
1034
        }
 
1035
      }
 
1036
 
 
1037
      /* dash (formerly empty) gene qualifier to suppress /gene (e.g., if tRNA is in an intron) */
 
1038
 
 
1039
      sprintf (str, "\t\t\tgene\t-\n");
 
1040
      EncodeAndWrite (str, strlen (str), stdout);
 
1041
      fflush (stdout);
 
1042
 
 
1043
      /* reset variables */
 
1044
 
 
1045
      start = 0;
 
1046
      stop = 0;
 
1047
      intronStart = 0;
 
1048
      intronStop = 0;
 
1049
      anticodonStart = 0;
 
1050
      anticodonStop = 0;
 
1051
      id [0] = '\0';
 
1052
      aa [0] = '\0';
 
1053
      pseudo = FALSE;
 
1054
 
 
1055
    } else if (strncmp (buf, "Type:", 5) == 0) {
 
1056
 
 
1057
      nxt = IsolateString (buf, ' ');
 
1058
      if (nxt != NULL) {
 
1059
        ptr = nxt;
 
1060
        nxt = IsolateString (ptr, '\t');
 
1061
        if (nxt != NULL) {
 
1062
          strcpy (aa, ptr);
 
1063
          if (strcmp (aa, "Undet") == 0 || strcmp (aa, "Sup") == 0) {
 
1064
            strcpy (aa, "OTHER");
 
1065
          }
 
1066
          ptr = nxt;
 
1067
          ParseRange (ptr, &anticodonStart, &anticodonStop);
 
1068
        }
 
1069
      }
 
1070
 
 
1071
    } else if (strncmp (buf, "Possible intron:", 16) == 0) {
 
1072
 
 
1073
      ParseRange (ptr, &intronStart, &intronStop);
 
1074
 
 
1075
    } else if (strncmp (buf, "Possible pseudogene:", 20) == 0) {
 
1076
 
 
1077
      pseudo = TRUE;
 
1078
 
 
1079
    } else if (strstr (buf, "Length:") != NULL) {
 
1080
 
 
1081
      ptr = strstr (buf, ".trna");
 
1082
      if (ptr != NULL) {
 
1083
        *ptr = '\0';
 
1084
        ptr++;
 
1085
        strcpy (id, buf);
 
1086
 
 
1087
        ParseRange (ptr, &start, &stop);
 
1088
      }
 
1089
    }
 
1090
  }
 
1091
 
 
1092
  pclose (fp);
 
1093
 
 
1094
  if (idNotSent) {
 
1095
    sprintf (str, ">Message\ntRNAscan-SE found no tRNA genes in this sequence\n");
 
1096
    EncodeAndWrite (str, strlen (str), stdout);
 
1097
    fflush (stdout);
 
1098
  }
 
1099
}
792
1100
 
793
1101
 
794
1102
/* this program can provide several services, specified in URL query string */
812
1120
  Int2     service;
813
1121
  Char     tempfile [1024];
814
1122
 
815
 
/* at startup, first verify environment */
 
1123
  /* at startup, first verify environment */
816
1124
 
817
1125
  method = getenv ("REQUEST_METHOD");
818
1126
  if (method == NULL) {
822
1130
    return 1;
823
1131
  }
824
1132
 
825
 
/* ensure that the POST method is being sent from the HTTPD server */
 
1133
  /* ensure that the POST method is being sent from the HTTPD server */
826
1134
 
827
1135
  if (strcmp (method, "POST") != 0) {
828
1136
    printf ("Content-type: text/html\r\n\r\n");
831
1139
    return 1;
832
1140
  }
833
1141
 
834
 
/* backward compatibility for query in URL after ? character */
 
1142
  /* backward compatibility for query in URL after ? character */
835
1143
 
836
1144
  ptr = getenv ("QUERY_STRING");
837
1145
  if (ptr != NULL && strlen (ptr) > 0) {
846
1154
    }
847
1155
  }
848
1156
 
849
 
/*
850
 
*  copy all of stdin to temporary file before sending anything to stdout,
851
 
*  to get around an apparent limitation in the HTTPD implementation that
852
 
*  can cause socket deadlock
853
 
*/
 
1157
  /*
 
1158
  *  copy all of stdin to temporary file before sending anything to stdout,
 
1159
  *  to get around an apparent limitation in the HTTPD implementation that
 
1160
  *  can cause socket deadlock
 
1161
  */
854
1162
 
855
1163
  tmpnam (tempfile);
856
1164
  fp = fopen (tempfile, "w");
865
1173
 
866
1174
    bf = buf;
867
1175
 
868
 
/* write data part of buffer to temporary file */
 
1176
    /* write data part of buffer to temporary file */
869
1177
 
870
1178
    fwrite (bf, 1, ct, fp);
871
1179
  }
872
1180
  fflush (fp);
873
1181
  fclose (fp);
874
1182
 
875
 
/* expect request=custom, request=echo, request=seg, or request=trnascan */
 
1183
  /* expect request=custom, request=echo, request=seg, or request=trnascan */
876
1184
 
877
1185
  request = FindByName ("request");
878
1186
  if (request == NULL) {
882
1190
    return 1;
883
1191
  }
884
1192
 
885
 
/* compare request value against list of available services */
 
1193
  /* compare request value against list of available services */
886
1194
 
887
1195
  service = ListHasString (services, request);
888
1196
  if (service < 1) {
892
1200
    return 1;
893
1201
  }
894
1202
 
895
 
/* call appropriate external analysis program */
 
1203
  /* call appropriate external analysis program */
896
1204
 
897
1205
  switch (service) {
898
1206
 
899
1207
#ifdef ALLOW_CUSTOM_PROGRAM
900
1208
 
901
 
/* for security, custom programs not allowed without symbol at compile time */
 
1209
    /* for security, custom programs not allowed without symbol at compile time */
902
1210
 
903
1211
    case 1 :
904
1212
      RunCustom (tempfile);
917
1225
      break;
918
1226
    default :
919
1227
 
920
 
/* each function must send required first header information to stdout */
 
1228
      /* each function must send required first header information to stdout */
921
1229
 
922
1230
      printf ("Content-type: text/html\r\n\r\n");
923
1231
      fflush (stdout);
924
1232
      break;
925
1233
  }
926
1234
 
927
 
/* flush buffer, cleanup temporary files and allocated memory, and exit */
 
1235
  /* flush buffer, cleanup temporary files and allocated memory, and exit */
928
1236
 
929
1237
  fflush (stdout);
930
1238
  remove (tempfile);