]> andersk Git - splint.git/blame - test/nullterminatedtest/buggy1.c
noexpand always false.
[splint.git] / test / nullterminatedtest / buggy1.c
CommitLineData
4e4880b7 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 */
92typedef struct {
93 char *name;
94 char *val;
95} entry;
96
97/*Function prototypes, local.
98 */
99void html_file( char *a, char *b, int nf );
100void html_directory( char *a, int nf );
101void dir_dot_parse( char *s, char *d );
102void tar_zed( entry *e, int m );
103
104/*
105 *Function prototypes, external.
106 */
107char *makeword( char *line, char stop );
108char *fmakeword( FILE *f, char stop, int *len );
109void unescape_url( char *url );
110void plustospace (char *str );
111
112/*
113 *Function prototyping for lclint checking
114 */
115/*@nullterminated@*/char *getenv(/*@nullterminated@*/char *);
116
117int atoi(/*@nullterminated@*/char *);
118
119/*@nullterminated@*/char *strcpy(char *, /*@nullterminated@*/char *);
120
121int strcmp(/*@nullterminated@*/ const char *s1, /*@nullterminated@*/ const char *s2);
122
123/*@nullterminated@*/char *strcat(/*@nullterminated@*/char *dst, /*@nullterminated@*/const char *src);
124
125int stat(/*@nullterminated@*/const char *path, struct stat *buf);
126
127int strncmp(const char *s1, const char *s2, size_t n);
128
129DIR *opendir(/*@nullterminated@*/const char *dirname);
130
131char *strncpy(char *dst, const char *src, size_t n);
132
133void qsort(void *base, size_t nel, size_t width,
134 int (*compar) (const void *, const void *));
135
136struct tm *localtime(const time_t *clock);
137
138void *memcpy(void *s1, const void *s2, size_t n);
139
140int sprintf(char *s, /*@nullterminated@*/const char *format, /* args */ ...);
141
142int system(const char *string);
143
144
145
146/*****************************************************************************/
147main()
148{
149
150/*
151 * Local Variables:
152 */
153entry entries[MAX_ENTRIES];
154int x;
155int m; /*number of lines in request*/
156int cl;
157char wdir[TEXT_BUFSIZE];
158/*@nullterminated@*/ char adir[TEXT_BUFSIZE];
159struct 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/*****************************************************************************/
253void 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 */
297char *dirname, /* Name of directory to be displayed. */
298
299int nf /* Number of files in request. */
300
301)
302{
303
304/*
305 * Local Variables:
306 */
307DIR *the_directory;
308
309struct dirent *the_file;
310struct stat statbuf;
311struct tm ttime;
312
313char tbuf[128];
314char full_path[TEXT_BUFSIZE];
315char adir[TEXT_BUFSIZE];
316char ent_tab[LIST_ENTRIES][ENT_WID];
317
318int entries;
319int notvalid = 0;
320int 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 */
542return;
543}
544
545
546/*****************************************************************************/
547void 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 */
584char *indir,
585char *outdir
586
587)
588{
589
590/*
591 * Local Variables:
592 */
593char *cptr;
594char *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 */
666return;
667}
668
669
670/*****************************************************************************/
671void 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 */
711char *fname, /* Full path of file. */
712char *sname, /* Name only of file. */
713
714int nf /* Total number of files in request. */
715
716)
717{
718
719/*
720 * Local Variables:
721 */
722char thecommand[4 * TEXT_BUFSIZE];
723char 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 */
833return;
834}
835
836
837/*****************************************************************************/
838int 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 */
878char *fname, /* The file specification. */
879char *fext /* A file extension, without ".". */
880
881)
882{
883
884/*
885 * Local Variables:
886 */
887char *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/*****************************************************************************/
918void 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 */
954entry *ent, /* Pointer to start of list. */
955
956int n /* Number of items in list. */
957
958)
959{
960
961/*
962 * Local Variables:
963 */
964char request_text[65536]; /* Buffer for command line. */
965
966int 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 */
1022return;
1023}
1024
1025/*End-of-file.
1026 */
1027
This page took 0.194803 seconds and 5 git commands to generate.