File: buildshar.c

package info (click to toggle)
xli 1.17.0+20061110-5
  • links: PTS, VCS
  • area: main
  • in suites: bullseye, buster, sid
  • size: 1,540 kB
  • sloc: ansic: 25,840; makefile: 11
file content (123 lines) | stat: -rw-r--r-- 2,840 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
/* #ident	"@(#)x11:contrib/clients/xloadimage/buildshar.c 1.5 93/07/23 Labtam" */
/* buildshar.c:
 *
 * utility program to figure out how to pack shar files.  it doesn't try
 * very hard.
 *
 * this program is in the public domain.
 *
 * jim frost 09.25.90
 */

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>

/* this defines the size of the shar file not including anything that got
 * added by shar.  should be considerably smaller than 64000.
 */

#define SHAR_SIZE 40000

struct file {
  char *name;
  int size;
  struct file *next;
};

struct shar {
  struct file *file;
  struct shar *next;
};

main(int argc, char **argv)
{ int num_files, files_left;
  struct file *files;
  struct stat sbuf;
  struct shar *shar_list;
  struct shar *cur_shar;
  struct file *cur_file;
  int shar_size, shar_num, num_shars;
  int a;

  if (argc < 2) {
    fprintf(stderr, "Usage: %s [files]\n", *argv);
  }

  /* build table of filenames
   */

  files= (struct file *)malloc(sizeof(struct file) * (argc - 1));
  for (a= 0, num_files= 0; *(++argv); a++) {
    if (stat(*argv, &sbuf) < 0) {
      perror(*argv);
      files[a].name= NULL;
      continue;
    }
    num_files++;
    files[a].name= *argv;
    files[a].size= sbuf.st_size;
  }

  /* try to fit files.  this is not a bright algorithm.
   */

  shar_list= cur_shar= (struct shar *)malloc(sizeof(struct shar));
  cur_shar->file= NULL;
  cur_file= NULL;
  shar_size= 0;

  for (files_left= num_files; files_left;) {

    /* look for a file that'll fit in the current shar
     */

    for (a= 0; a < num_files; a++)
      if (files[a].name &&
	  ((shar_size + files[a].size <= SHAR_SIZE) ||
	   ((shar_size == 0) && (files[a].size > SHAR_SIZE)))) {
	shar_size += files[a].size;
	if (cur_file) {
	  cur_file->next= (struct file *)malloc(sizeof(struct file));
	  cur_file= cur_file->next;
	}
	else
	  cur_shar->file= cur_file= (struct file *)malloc(sizeof(struct file));
	cur_file->name= files[a].name;
	cur_file->next= NULL;
	files[a].name= NULL;
	files_left--;
	break;
      }

    /* if nothing fit, make a new shar file
     */

    if (a == num_files) {
      cur_shar->next= (struct shar *)malloc(sizeof(struct shar));
      cur_shar= cur_shar->next;
      cur_shar->file= NULL;
      cur_shar->next= NULL;
      cur_file= NULL;
      shar_size= 0;
    }
  }

  /* find out how many shar files we need for -e flag
   */

  for (num_shars= 0, cur_shar= shar_list; cur_shar; num_shars++)
    cur_shar= cur_shar->next;

  /* output each shar command line
   */

  for (shar_num= 1, cur_shar= shar_list; cur_shar; shar_num++) {
    printf("shar -n %d -e %d", shar_num, num_shars);
    for (cur_file= cur_shar->file; cur_file; cur_file= cur_file->next)
      printf(" %s", cur_file->name);
    cur_shar= cur_shar->next;
    printf(" > shar.%d\n", shar_num);
  }
  exit(0);
}