]> andersk Git - splint.git/blob - test/nullterminatedtest/buggy1.c
- library fixes:
[splint.git] / test / nullterminatedtest / buggy1.c
1 /*
2  *  Name:
3  *     StarZ
4
5  *  Purpose:
6  *     File Browser/Getter for World Wide Web Browsers.
7
8  *  Language:
9  *     C
10
11  *  Description:
12  *     This is a Common Gateway Interface program which when accessed
13  *     with an HTTP GET as SCRIPT_URL (see #defines below) will return
14  *     a directory listing of files available on the host machine.
15  *
16  *     The directory listing is in the shape of an HTML form with a
17  *     "checkbox" button for each directory entry.  The size of each file
18  *     or an indication that it is a directory are given.
19  *
20  *     A button for "mode select" is also given.
21  *
22  *     The default mode is File Browse.
23  *     A selected file is displayed, or a selected directory generates a
24  *     new HTML form for that directory.
25  *
26  *     The other mode is File Get.
27  *     Selected files and/or directories are put in a tar archive and
28  *     compressed back to the Web browser program.
29
30  *  Authors:
31  *     MJC: Martin Clayton (Starlink)
32  *     {enter_new_authors_here}
33
34  *  History:
35  *     14-DEC-1994 (MJC):
36  *       Original Version.
37  *     30-DEC-1994 (MJC):
38  *       Added a direct "change directory to" text entry field.
39  *       Changed note relating to Netscape to reflect change in Company name.
40  *     12-APR-1995 (MJC):
41  *       Limited access to directories under /star tree.
42  *     {enter_further_changes_here}
43
44  *  Problems:
45  *     Nothing checks that a file for browse is a text file.
46  *     Default file protections are used, so a remote user can access
47  *     any unprotected files on the system hosting this program.
48  *     Some large HTML forms are slowly processed by the common
49  *     Web browser Mosaic, this is best overcome by using a more advanced
50  *     browser such as Netscape Communications' Netscape but remains a general
51  *     problem.
52  *     The code may well be OSF/1 specific.
53  *     {note_further_problems_here}
54
55  *  Bugs:
56  *     {note_any_bugs_here}
57
58  *-
59  */
60
61 /*Standard Include files:
62  */
63 #include <stdio.h>
64 #include <stdlib.h>
65 #include <dirent.h>
66 #include <sys/types.h>
67 #include <sys/stat.h>
68 #include <strings.h>
69 #include <time.h>
70
71 /*Local Macros.
72  */
73 #define MAX_ENTRIES     (10240)  /* Maximum number of lines in cgi request.   */
74 #define LIST_ENTRIES    (10240)  /* Maximum number of files in a Get request. */
75 #define TEXT_BUFSIZE    (1024)   /* Internal buffer size.                     */
76 #define ENT_WID         (64)     /* Maximum length of a file name.            */
77 #define MODE_FLAG       "spoingmode" /*Internal flag for Browse/Get mode.     */
78
79 #define DEFAULT_DIR     "/star"   /* First directory to be listed.            */
80
81 /*Where the program will be placed.
82  */
83 #define SCRIPT_URL      "http://www.star.ucl.ac.uk/mjc-cgi/S.tar.Z"
84
85 /*Maintenance details.
86  */
87 #define AUTHOR_NAME "Martin Clayton"
88 #define AUTHOR_URL  "<A HREF=\"mailto:mjc@starlink.ucl.ac.uk\">mjc@starlink.ucl.ac.uk</A>"
89
90 /*Structure to hold a cgi request list entry.
91  */
92 typedef struct {
93     char *name;
94     char *val;
95 } entry;
96
97 /*Function prototypes, local.
98  */
99 void html_file( char *a, char *b, int nf );
100 void html_directory( char *a, int nf );
101 void dir_dot_parse( char *s, char *d );
102 void tar_zed( entry *e, int m );
103
104 /*
105  *Function prototypes, external.
106  */
107 char *makeword( char *line, char stop );
108 char *fmakeword( FILE *f, char stop, int *len );
109 void unescape_url( char *url );
110 void plustospace (char *str );
111
112 /*
113  *Function prototyping for lclint checking
114  */
115 /*@nullterminated@*/char *getenv(/*@nullterminated@*/char *);
116
117 int atoi(/*@nullterminated@*/char *);
118
119 /*@nullterminated@*/char *strcpy(char *, /*@nullterminated@*/char *);
120
121 int strcmp(/*@nullterminated@*/ const char *s1, /*@nullterminated@*/ const char *s2);
122
123 /*@nullterminated@*/char *strcat(/*@nullterminated@*/char *dst, /*@nullterminated@*/const char *src);
124
125 int stat(/*@nullterminated@*/const char *path, struct stat *buf);
126
127 int strncmp(const char *s1, const char *s2, size_t n);
128
129 DIR *opendir(/*@nullterminated@*/const char *dirname);
130
131 char *strncpy(char *dst, const char *src, size_t n);
132
133 void qsort(void *base, size_t nel, size_t width,
134           int (*compar) (const void *, const void *));
135
136 struct tm *localtime(const time_t *clock);
137
138 void *memcpy(void *s1, const void *s2, size_t n);
139
140 int sprintf(char *s, /*@nullterminated@*/const char *format, /* args */ ...);
141
142 int system(const char *string);
143
144
145
146 /*****************************************************************************/
147 main()
148 {
149
150 /*
151  *  Local Variables:
152  */
153 entry entries[MAX_ENTRIES];
154 int x;
155 int m;           /*number of lines in request*/
156 int cl;
157 char wdir[TEXT_BUFSIZE];
158 /*@nullterminated@*/ char adir[TEXT_BUFSIZE];
159 struct stat statbuf;
160 /*.
161  */
162
163 /*No request given.
164  */
165     if ( !getenv( "CONTENT_LENGTH" ) ) {
166         m = -1;
167
168 /*Move request lines into "entry" array.
169  */
170     } else {
171         cl = atoi( getenv( "CONTENT_LENGTH" ) );
172         m = 0;
173         for ( x = 0; cl && ( !feof( stdin ) ); x++ ) {
174             m = x;
175             entries[x].val = fmakeword( stdin, '&', &cl );
176             plustospace( entries[x].val );
177             unescape_url( entries[x].val );
178             entries[x].name = makeword( entries[x].val, '=' );
179         }
180     }
181
182 /*No request made.  Initial inquiry from remote machine.
183  */
184     if ( ( m == -1 ) || ( !entries[0].name ) ) {
185         html_directory( "", 0 );
186
187 /*Decode the request.
188  */
189     } else {
190
191 /*    Request for compressed archive data.
192  */
193         if ( !strcmp( entries[0].name, MODE_FLAG ) ) {
194             tar_zed( &entries[1], m - 1 );
195
196 /*    Browse request.
197  */
198         } else if ( !strcmp( entries[0].name, "Explicit" ) ) {
199
200 /*        Check for explicit directory or file name.
201  */
202             if ( strcmp( entries[0].val, "" ) ) {
203                 strcpy( adir, entries[0].val );
204
205             } else if ( m > 0 ) {
206
207 /*            Build required file name, first directory part.
208  */
209                 strcpy( adir, entries[1].val );
210
211 /*            Add in a / if not root directory.
212  */
213                 if ( strcmp( adir, "/" ) ) {
214                     strcat( adir, "/" );
215                 }
216
217 /*            Append the actual file name.
218  */
219                 strcat( adir, entries[1].name );
220
221             } else {
222                 strcpy( adir, DEFAULT_DIR );
223             }
224
225 /*        Modify the file name if it is . or ..
226  */
227             dir_dot_parse( adir, wdir );
228
229 /*        Get file information.
230  */
231             stat( wdir, &statbuf );
232
233 /*        Build a directory listing.
234  */
235             if ( statbuf.st_mode & S_IFDIR) {
236                 html_directory( wdir, m - 1 );
237
238 /*        Display a file's contents.
239  */
240             } else {
241                 html_file( wdir, entries[1].name, m - 1 );
242             }
243         }
244     }
245
246 /*Done.
247  */
248     exit ( EXIT_SUCCESS );
249 }
250
251
252 /*****************************************************************************/
253 void html_directory(
254 /*+
255  *  Name:
256  *     html_directory
257
258  *  Purpose:
259  *     Build directory listing in HTML.
260
261  *  Language:
262  *     C
263
264  *  Invocation:
265  *     html_directory( dirname, nf )
266
267  *  Arguments:
268  *     dirname = char * (Given)
269  *        Pointer to name of the directory to be listed.
270  *     nf = int (Given)
271  *        Total number of files in request.
272
273  *  Authors:
274  *     MJC: Martin Clayton (Starlink)
275  *     {enter_new_authors_here}
276
277  *  History:
278  *     14-DEC-1994 (MJC):
279  *       Original Version.
280  *     20-DEC-1994 (MJC):
281  *       Added support for file last modification time to be displayed.
282  *     21-DEC-1994 (MJC):
283  *       Removed spurious <P> from second control button pair.
284  *     21-JAN-1995 (MJC):
285  *       Added gopher images to directory listings.
286  *     12-APR-1995 (MJC):
287  *       Limited access to directories under /star tree.
288  *     {enter_further_changes_here}
289
290  *  Bugs:
291  *     {note_any_bugs_here}
292
293  *-
294
295  *  Arguments Given:
296  */
297 char *dirname,                   /* Name of directory to be displayed.        */
298
299 int nf                           /* Number of files in request.               */
300
301 )
302 {
303
304 /*
305  *  Local Variables:
306  */
307 DIR *the_directory;
308
309 struct dirent *the_file;
310 struct stat statbuf;
311 struct tm ttime;
312
313 char tbuf[128];
314 char full_path[TEXT_BUFSIZE];
315 char adir[TEXT_BUFSIZE];
316 char ent_tab[LIST_ENTRIES][ENT_WID];
317
318 int entries;
319 int notvalid = 0;
320 int i;
321
322 /*.
323  */
324
325 /*When not an empty string, use supplied file name.
326  */
327     if ( *dirname != '\0' ) {
328         strcpy( full_path, dirname );
329
330 /*Otherwise set to default directory.
331  */
332     } else {
333         strcpy( full_path, DEFAULT_DIR );
334     }
335
336 /*Make sure request is in /star tree, if not go to default directory.
337  */
338     if ( strncmp( full_path, DEFAULT_DIR, 5 ) ) {
339         notvalid = 1;
340         strcpy( full_path, DEFAULT_DIR );
341     }
342
343 /*Try to open the directory.
344  */
345     the_directory = opendir( full_path );
346
347 /*Start response output.
348  */
349     www_begin( T_HTML );
350
351 /*HTML title.
352  */
353     www_head( "StarZ: File browser-getter." );
354
355     hline( "<BODY>" );
356
357 /*Heading.
358  */
359     hrule( );
360     hheading( "StarZ: File browser-getter", 1 );
361     hrule( );
362
363 /*Print error message if unable to open directory.
364  */
365     if ( !the_directory ) {
366         printf( "Could not open %s directory.%c", full_path, NEW_LINE );
367
368
369 /*Otherwise start to build listing.
370  */
371     } else {
372
373 /*    Currently, only one directory can be selected for listing.
374  *    The first chosen is displayed, others are ignored except that
375  *    the following message is displayed.
376  */
377         if ( nf > 0 ) {
378             printf( "<B>Only first entry in list will be displayed.</B>%c",
379                     NEW_LINE );
380         }
381
382 /*    Print warning that request is not in /star tree.
383  */
384         if ( notvalid ) {
385             printf( "<B>Your request has been denied, default %s directory selected instead.</B>%c",
386                     DEFAULT_DIR, NEW_LINE );
387         }
388
389 /*    Start HTML FORM.
390  *    URL of where script will reside.
391  */
392         printf( "<FORM action=\"%s\" method=\"POST\">%c",
393                 SCRIPT_URL, NEW_LINE );
394
395 /*    Submit and reset buttons.  These are duplicated later.
396  */
397         printf( "<INPUT type=submit value=\" Submit Request \">%c", NEW_LINE );
398         printf( "<INPUT type=reset value=\" Reset \"><P>%c", NEW_LINE );
399
400 /*    Browse or Get mode-select button.
401  */
402         printf( "<INPUT TYPE=\"checkbox\" NAME=\"%s\" ", MODE_FLAG );
403         printf( "VALUE=\"%s\"> <B>Get or Browse (default) mode</B><BR>%c",
404                 full_path, NEW_LINE);
405
406 /*    Text input field for entry of explicit file or directory name.
407  */
408         printf( "<INPUT SIZE=32 TYPE=TEXT NAME=\"Explicit\"> <B>Change Directory</B><BR>%c", NEW_LINE );
409
410 /*    List heading.
411  */
412         printf( "<H2>Directory of %s</H2>%c", full_path, NEW_LINE );
413
414 /*    Build directory listing.
415  */
416         entries = 0;
417         while ( ( the_file = readdir( the_directory ) ) &&
418                ( entries < LIST_ENTRIES ) ) {
419
420 /*        Don't include . and .. in list for sort.
421  */
422             if ( !strcmp( the_file->d_name, "." ) ) {
423                 continue;
424
425             } else if ( !strcmp( the_file->d_name, ".." ) ) {
426                 continue;
427
428 /*        Other file names added to list.
429  */
430             } else {
431                 strncpy( ent_tab[entries], the_file->d_name, ENT_WID );
432                 ent_tab[entries][ENT_WID - 1] = '\0';
433                 entries++;
434             }
435         }
436
437 /*    Close the directory.
438  */
439         closedir( the_directory );
440
441 /*    Sort the directory list.
442  */
443         qsort( (void *)(ent_tab), entries + 1, ENT_WID, strcmp );
444
445 /*    Start output of the listing.
446  */
447         printf( "<PRE WIDTH=64>%c", NEW_LINE );
448
449 /*    Current directory button.
450  */
451         printf( "<INPUT TYPE=\"checkbox\" NAME=\".\" VALUE=\"%s\">",
452                 full_path);
453         printf( " &lt;-current directory-&gt;%c", NEW_LINE );
454
455 /*    Parent directory button.
456  */
457         if ( strcmp( full_path, "/" ) ) {
458             printf( "<INPUT TYPE=\"checkbox\" NAME=\"..\" VALUE=\"%s\">",
459                     full_path);
460             printf( " &lt;-parent directory%c", NEW_LINE );
461         }
462
463 /*    Files themselves.
464  */
465         for ( i = 1; i <= entries; i++ ) {
466
467 /*       Start with button.
468  */
469            printf( "<INPUT TYPE=\"checkbox\" NAME=\"%s\" VALUE=\"%s\">",
470                    ent_tab[i], full_path );
471
472 /*       Get file information.
473  */
474            strcpy( adir, full_path );
475            if ( strcmp( adir, "/" ) ) {
476                strcat( adir, "/" );
477            }
478            strcat( adir, ent_tab[i] );
479            stat( adir, &statbuf );
480
481 /*       Mark as a directory if that is the case.
482  */
483            if ( statbuf.st_mode & S_IFDIR) {
484                printf( " <IMG ALIGN=absbottom BORDER=0 SRC=\"internal-gopher-menu\">" );
485                printf( " %-32s", ent_tab[i] );
486                printf( "%9s", "directory" );
487
488 /*       Otherwise print the size of the file.
489  */
490            } else {
491                if ( extension( ent_tab[i], "html" ) ) {
492                    printf( " <IMG ALIGN=absbottom BORDER=0 SRC=\"internal-gopher-text\">" );
493
494                } else {
495                    printf( " <IMG ALIGN=absbottom BORDER=0 SRC=\"internal-gopher-unknown\">" );
496                }
497                printf( " %-32s", ent_tab[i] );
498                printf( "%9d", (int)( statbuf.st_size ) );
499            }
500
501 /*       Last modification date/time information.
502  */
503            (void)(memcpy( &ttime, localtime(&statbuf.st_mtime),
504                           sizeof(struct tm)) );
505            (void)(strncpy( tbuf, asctime( &ttime ), 26 ) );
506            *( tbuf + 24 ) = '\0';
507            printf( "  %s%c", tbuf, NEW_LINE );
508
509         }
510
511 /*    End of the directory listing.
512  */
513         printf( "</PRE>%c", NEW_LINE );
514
515 /*    Output a second set of control buttons.
516  */
517         printf( "<INPUT type=submit value=\" Submit Request \">%c",
518                 NEW_LINE );
519         printf( "<INPUT type=reset value=\" Reset \">%c", NEW_LINE );
520
521 /*    End of form.
522  */
523         printf( "</FORM>%c", NEW_LINE );
524     }
525
526 /*End main part of response
527  */
528     hrule( );
529
530
531 /*HTML Address field.
532  */
533     www_address( AUTHOR_NAME, AUTHOR_URL, NULL );
534
535 /*End response.
536  */
537     hline( "</BODY>" );
538     www_end( );
539
540 /*Done.
541  */
542 return;
543 }
544
545
546 /*****************************************************************************/
547 void dir_dot_parse(
548 /*+
549  *  Name:
550  *     dir_dot_parse
551
552  *  Purpose:
553  *     Finds simplest version of a file specifier with . or .. at end.
554
555  *  Language:
556  *     C
557
558  *  Invocation:
559  *     dir_dot_parse( indir, outdir )
560
561  *  Arguments:
562  *     indir = char * (Given)
563  *        Pointer to the file specification to be checked.
564  *     outdir = char * (Given and Returned)
565  *        Pointer to space for parsed specification, must be big enough
566  *        to hold converted file name.
567
568  *  Authors:
569  *     MJC: Martin Clayton (Starlink)
570  *     {enter_new_authors_here}
571
572  *  History:
573  *     14-DEC-1994 (MJC):
574  *       Original Version.
575  *     {enter_further_changes_here}
576
577  *  Bugs:
578  *     {note_any_bugs_here}
579
580  *-
581
582  *  Arguments Given:
583  */
584 char *indir,
585 char *outdir
586
587 )
588 {
589
590 /*
591  *  Local Variables:
592  */
593 char *cptr;
594 char *eptr;
595
596 /*.
597  */
598
599 /*Mark default return value as a blank string.
600  */
601     strcpy( outdir, "" );
602     if ( !strcmp( indir, "" ) ) {
603         return;
604     }
605
606 /*Find the end of the supplied string.
607  */
608     cptr = indir;
609     while ( *cptr ) {
610         cptr++;
611     }
612     eptr = cptr;
613
614 /*Point to last non-null character in string.
615  */
616     if ( cptr > indir ) {
617         cptr--;
618
619     } else {
620         return;
621     }
622
623 /*Does string end in a '.'?
624  */
625     if ( *cptr == '.' ) {
626         cptr--;
627
628 /*    Current directory, remove /. part of file name.
629  */
630         if ( *cptr == '/' ) {
631             *cptr++ = '\0';
632             *cptr = '\0';
633
634         } else if ( *cptr == '.' ) {
635             cptr--;
636
637 /*        Parent directory, remove /.. part of file name and
638  *        name of the current directory, unless the current
639  *        directory is root, in which case just remove the ..
640  */
641             if ( *cptr == '/' ) {
642                 while ( cptr > indir ) {
643                     cptr--;
644                     if ( *cptr == '/' ) {
645                         break;
646                     }
647                 }
648                 if ( cptr > indir) {
649                     while ( cptr < eptr ) {
650                         *cptr++ = '\0';
651                     }
652
653                 } else {
654                     *(indir + 1) = '\0';
655                 }
656             }
657         }
658     }
659
660 /*Copy the parsed file specifier to output buffer.
661  */
662     strcpy ( outdir, indir );
663
664 /*Done.
665  */
666 return;
667 }
668
669
670 /*****************************************************************************/
671 void html_file(
672 /*+
673  *  Name:
674  *     html_file
675
676  *  Purpose:
677  *     Display a text file in an HTML 'wrapper'.
678
679  *  Language:
680  *     C
681
682  *  Invocation:
683  *     html_file( fname, sname, nf )
684
685  *  Arguments:
686  *     fname = char * (Given)
687  *        Pointer to full path of the file to be displayed.
688  *     sname = char * (Given)
689  *        Pointer to name of the file only.
690  *     nf = int (Given)
691  *        Total number of files in request.
692
693  *  Authors:
694  *     MJC: Martin Clayton (Starlink)
695  *     {enter_new_authors_here}
696
697  *  History:
698  *     14-DEC-1994 (MJC):
699  *       Original Version.
700  *     21-DEC-1994 (MJC):
701  *       Added missing <BODY>.
702  *     {enter_further_changes_here}
703
704  *  Bugs:
705  *     {note_any_bugs_here}
706
707  *-
708
709  *  Arguments Given:
710  */
711 char *fname,                     /* Full path of file.                        */
712 char *sname,                     /* Name only of file.                        */
713
714 int nf                           /* Total number of files in request.         */
715
716 )
717 {
718
719 /*
720  *  Local Variables:
721  */
722 char thecommand[4 * TEXT_BUFSIZE];
723 char title[1024];                 /* Workspace for page title.                */
724 /*.
725  */
726
727 /*It's a gif wrap in simple HTML page.
728  */
729     if ( extension( fname, "gif" ) ) {
730
731 /*    Start response.
732  */
733         www_begin( T_HTML );
734         sprintf( title, "StarZ: %s", sname );
735         www_head( title );
736
737         hline( "<BODY>" );
738
739 /*Pointer to image.
740  */
741         printf( "<IMG SRC=\"%s\"><P>%c", fname, NEW_LINE );
742
743 /*    Attach an address field.
744  */
745         www_address( AUTHOR_NAME, AUTHOR_URL, NULL );
746
747 /*    End response.
748  */
749         hline( "</BODY>" );
750         www_end( );
751
752
753 /*If the file appears NOT to be an HTML file, then wrap it in
754  *some appropriate HTML.
755  */
756     } else if ( !extension( fname, "html" ) ) {
757
758 /*    Start response.
759  */
760         www_begin( T_HTML );
761         sprintf( title, "StarZ: %s", sname );
762         www_head( title );
763
764         hline( "<BODY>" );
765
766 /*    Only the first file of a multiple-file display request is piped back.
767  */
768         if ( nf > 0 ) {
769             hline( "<B>Only first entry in list will be displayed.</B>" );
770         }
771
772 /*    Wrap the file in preformatted HTML style.
773  */
774         hline( "<PRE>" );
775
776 /*    Flush stdout prior to calling cat to display file.
777  */
778         fflush( stdout );
779
780 /*    Build command line to display the file.
781  */
782         sprintf( thecommand, "cat %s\0x00", fname );
783
784 /*    Pipe out file.
785  */
786         if ( system ( thecommand ) ) {
787             printf( "Could not access file %s%c", fname, NEW_LINE );
788         }
789
790 /*    End of wrap.
791  */
792         hline( "</PRE>" );
793
794 /*    Attach an address field.
795  */
796         www_address( AUTHOR_NAME, AUTHOR_URL, NULL );
797
798 /*    End response.
799  */
800         hline( "</BODY>" );
801         www_end( );
802
803
804 /*Other case is a file we expect to be in HTML format.
805  */
806     } else if ( extension( fname, "html" ) ) {
807
808 /*    Start response.
809  */
810         printf( "Content-type: text/html%c%c", NEW_LINE, NEW_LINE );
811
812 /*    Only the first file of a multiple-file display request is piped back.
813  */
814         if ( nf > 0 ) {
815             printf( "<B>Only first entry in list will be displayed.</B>%c",
816                     NEW_LINE );
817         }
818
819 /*    Flush stdout prior to calling cat
820  */
821         fflush( stdout );
822
823 /*    Pipe out HTML file.
824  */
825         sprintf( thecommand, "cat %s\0x00", fname );
826         if ( system ( thecommand ) ) {
827             printf( "Could not access file %s%c", fname, NEW_LINE );
828         }
829     }
830
831 /*Done.
832  */
833 return;
834 }
835
836
837 /*****************************************************************************/
838 int extension(
839 /*+
840  *  Name:
841  *     extension
842
843  *  Purpose:
844  *     Compare the last part of a file specifier with a supplied extension.
845
846  *  Language:
847  *     C
848
849  *  Invocation:
850  *     extension( fname, fext )
851
852  *  Arguments:
853  *     fname = char * (Given)
854  *        Pointer to name of the file to be checked.
855  *     fext = char * (Given)
856  *        Pointer to the extension to be tested for.
857
858  *  Returned:
859  *     Returns the result of a strcmp( ) call comparing the relevant
860  *     part of the supplied text with the supplied extension.
861
862  *  Authors:
863  *     MJC: Martin Clayton (Starlink)
864  *     {enter_new_authors_here}
865
866  *  History:
867  *     14-DEC-1994 (MJC):
868  *       Original Version.
869  *     {enter_further_changes_here}
870
871  *  Bugs:
872  *     {note_any_bugs_here}
873
874  *-
875
876  *  Arguments Given:
877  */
878 char *fname,                     /* The file specification.                   */
879 char *fext                       /* A file extension, without ".".            */
880
881 )
882 {
883
884 /*
885  *  Local Variables:
886  */
887 char *cptr;
888
889 /*.
890  */
891
892 /*Find end of file name.
893  */
894     cptr = fname;
895     while ( *cptr ) {
896         cptr++;
897     }
898     if ( cptr > fname ) {
899         cptr--;
900     }
901
902 /*Find last . in  file name and point to character after it.
903  */
904     while ( ( *cptr != '.' ) && ( cptr > fname ) ) {
905         cptr--;
906     }
907     if ( cptr > fname ) {
908         cptr++;
909     }
910
911 /*Compare supplied extension with part of file name.
912  */
913     return ( !strcmp( cptr, fext) );
914 }
915
916
917 /*****************************************************************************/
918 void tar_zed(
919 /*+
920  *  Name:
921  *     tar_zed
922
923  *  Purpose:
924  *     Pipe a compressed tar archive of the requested files to stdout.
925
926  *  Language:
927  *     C
928
929  *  Invocation:
930  *     tar_zed( ent, n )
931
932  *  Arguments:
933  *     ent = entry * (Given)
934  *        Pointer to first item in a list of "entry" structures.
935  *     n = int (Given)
936  *        Total number of items in list.
937
938  *  Authors:
939  *     MJC: Martin Clayton (Starlink)
940  *     {enter_new_authors_here}
941
942  *  History:
943  *     14-DEC-1994 (MJC):
944  *       Original Version.
945  *     {enter_further_changes_here}
946
947  *  Bugs:
948  *     {note_any_bugs_here}
949
950  *-
951
952  *  Arguments Given:
953  */
954 entry *ent,                      /* Pointer to start of list.                 */
955
956 int n                            /* Number of items in list.                  */
957
958 )
959 {
960
961 /*
962  *  Local Variables:
963  */
964 char request_text[65536];        /* Buffer for command line.                  */
965
966 int i;                           /* Loop index.                               */
967
968 /*.
969  */
970
971 /*A null request was received, return message.
972  */
973     if ( n < 1 ) {
974         printf( "Content-type: text/html%c%c", NEW_LINE, NEW_LINE );
975         printf( "<B>Compressed tar file down-load request detected.</B><P>%c",
976                 NEW_LINE );
977         printf( "<B>Your request was empty!</B>%c", NEW_LINE );
978
979 /*Otherwise build command line to compress tar file to stdout.
980  */
981     } else {
982
983 /*    ent[].val is the same foe all entries, the base directory for
984  *    the archive build.  Mark a "change directory" command for this.
985  */
986         strcpy( request_text, "cd " );
987         strcat( request_text, ent[1].val );
988
989 /*    Add tar command with flags for pipe to stdout and follow soft links.
990  */
991         strcat( request_text, " ; tar -cfh - " );
992
993 /*    Now add all the list entries.
994  */
995         for ( i = 1; i <= n; i++ ) {
996             strcat( request_text, ent[i].name );
997             strcat( request_text, " " );
998         }
999
1000 /*    Finally, the pipe to compress with flag to send output to stdout.
1001  */
1002         strcat( request_text, " | compress -c" );
1003
1004 /*    Start transfer.
1005  */
1006         printf( "Content-Encoding: x-compress%c%c", NEW_LINE, NEW_LINE );
1007
1008 /*    Flush output.
1009  */
1010         fflush ( stdout );
1011
1012 /*    Execute compress archive command line.
1013  */
1014         if ( system( request_text ) ) {
1015             printf( "Content-type: text/html%c%c", NEW_LINE, NEW_LINE );
1016             printf( "<B>Transfer failed.</B><P>%c", NEW_LINE );
1017         }
1018     }
1019
1020 /*Done.
1021  */
1022 return;
1023 }
1024
1025 /*End-of-file.
1026  */
1027
This page took 0.128704 seconds and 5 git commands to generate.