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