1 /* buildshar.c:
2  *
3  * utility program to figure out how to pack shar files.  it doesn't try
4  * very hard.
5  *
6  * this program is in the public domain.
7  *
8  * jim frost 09.25.90
9  */
10 
11 #include <stdio.h>
12 #include <sys/types.h>
13 #include <sys/stat.h>
14 
15 /* this defines the size of the shar file not including anything that got
16  * added by shar.  should be considerably smaller than 64000.
17  */
18 
19 #define SHAR_SIZE 40000
20 
21 struct file {
22   char *name;
23   int size;
24   struct file *next;
25 };
26 
27 struct shar {
28   struct file *file;
29   struct shar *next;
30 };
31 
main(argc,argv)32 main(argc, argv)
33      int    argc;
34      char **argv;
35 { int num_files, files_left;
36   struct file *files;
37   struct stat sbuf;
38   struct shar *shar_list;
39   struct shar *cur_shar;
40   struct file *cur_file;
41   int shar_size, shar_num, num_shars;
42   int a;
43 
44   if (argc < 2) {
45     fprintf(stderr, "Usage: %s [files]\n", *argv);
46   }
47 
48   /* build table of filenames
49    */
50 
51   files= (struct file *)malloc(sizeof(struct file) * (argc - 1));
52   for (a= 0, num_files= 0; *(++argv); a++) {
53     if (stat(*argv, &sbuf) < 0) {
54       perror(*argv);
55       files[a].name= NULL;
56       continue;
57     }
58     num_files++;
59     files[a].name= *argv;
60     files[a].size= sbuf.st_size;
61   }
62 
63   /* try to fit files.  this is not a bright algorithm.
64    */
65 
66   shar_list= cur_shar= (struct shar *)malloc(sizeof(struct shar));
67   cur_shar->file= NULL;
68   cur_file= NULL;
69   shar_size= 0;
70 
71   for (files_left= num_files; files_left;) {
72 
73     /* look for a file that'll fit in the current shar
74      */
75 
76     for (a= 0; a < num_files; a++)
77       if (files[a].name &&
78 	  ((shar_size + files[a].size <= SHAR_SIZE) ||
79 	   ((shar_size == 0) && (files[a].size > SHAR_SIZE)))) {
80 	shar_size += files[a].size;
81 	if (cur_file) {
82 	  cur_file->next= (struct file *)malloc(sizeof(struct file));
83 	  cur_file= cur_file->next;
84 	}
85 	else
86 	  cur_shar->file= cur_file= (struct file *)malloc(sizeof(struct file));
87 	cur_file->name= files[a].name;
88 	cur_file->next= NULL;
89 	files[a].name= NULL;
90 	files_left--;
91 	break;
92       }
93 
94     /* if nothing fit, make a new shar file
95      */
96 
97     if (a == num_files) {
98       cur_shar->next= (struct shar *)malloc(sizeof(struct shar));
99       cur_shar= cur_shar->next;
100       cur_shar->file= NULL;
101       cur_shar->next= NULL;
102       cur_file= NULL;
103       shar_size= 0;
104     }
105   }
106 
107   /* find out how many shar files we need for -e flag
108    */
109 
110   for (num_shars= 0, cur_shar= shar_list; cur_shar; num_shars++)
111     cur_shar= cur_shar->next;
112 
113   /* output each shar command line
114    */
115 
116   for (shar_num= 1, cur_shar= shar_list; cur_shar; shar_num++) {
117     printf("shar -n %d -e %d", shar_num, num_shars);
118     for (cur_file= cur_shar->file; cur_file; cur_file= cur_file->next)
119       printf(" %s", cur_file->name);
120     cur_shar= cur_shar->next;
121     printf(" > shar.%d\n", shar_num);
122   }
123   exit(0);
124 }
125