File: marc.c

package info (click to toggle)
arc 5.21m-1
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k, lenny
  • size: 364 kB
  • ctags: 306
  • sloc: ansic: 4,078; makefile: 123
file content (341 lines) | stat: -rw-r--r-- 9,793 bytes parent folder | download | duplicates (2)
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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
/*
 * $Header: /cvsroot/arc/arc/marc.c,v 1.4 2005/03/13 15:44:00 k_reimer Exp $
 */

/*  MARC - Archive merge utility

    Version 5.21, created on 04/22/87 at 15:05:10

(C) COPYRIGHT 1985-87 by System Enhancement Associates; ALL RIGHTS RESERVED

    By:	 Thom Henderson

    Description:
	 This program is used to "merge" archives.  That is, to move
	 files from one archive to another with no data conversion.
	 Please refer to the ARC source for a description of archives
	 and archive formats.

    Instructions:
	 Run this program with no arguments for complete instructions.

    Language:
	 Computer Innovations Optimizing C86
*/
#include <stdio.h>
#include <string.h>
#include "arc.h"

#if	UNIX
#include <sys/types.h>
#include <sys/stat.h>
#endif

#ifndef	__STDC__
char *calloc(), *malloc(), *realloc(); /* memory managers */
#endif
VOID	arcdie();
static VOID expandlst(), merge();

FILE *src;			       /* source archive */
char srcname[STRLEN];		       /* source archive name */
char *pinbuf;				/* block input buffer */

static char **lst;		       /* files list */
static int lnum;		       /* length of files list */

int
main(nargs,arg)			       /* system entry point */
int nargs;			       /* number of arguments */
char *arg[];			       /* pointers to arguments */
{
    char *makefnam();
    char *envfind();
#if	!_MTS
    char *arctemp2, *mktemp();		/* temp file stuff */
#endif
#if	GEMDOS
    VOID exitpause();
#endif
    int n;			       /* index */
#if	UNIX
    struct	stat	sbuf;
#endif


    if(nargs<3)
    {	 printf("MARC - Archive merger, Version 5.21i, created on 11/25/92 at 14:40:55\n");
/*	 printf("(C) COPYRIGHT 1985,86,87 by System Enhancement Associates;");
	 printf(" ALL RIGHTS RESERVED\n\n");
	 printf("Please refer all inquiries to:\n\n");
	 printf("	System Enhancement Associates\n");
	 printf("	21 New Street, Wayne NJ 07470\n\n");
	 printf("You may copy and distribute this program freely,");
	 printf(" provided that:\n");
	 printf("    1)	  No fee is charged for such copying and");
	 printf(" distribution, and\n");
	 printf("    2)	  It is distributed ONLY in its original,");
	 printf(" unmodified state.\n\n");
	 printf("If you like this program, and find it of use, then your");
	 printf(" contribution will\n");
	 printf("be appreciated.  You may not use this product in a");
	 printf(" commercial environment\n");
	 printf("or a governmental organization without paying a license");
	 printf(" fee of $35.  Site\n");
	 printf("licenses and commercial distribution licenses are");
	 printf(" available.  A program\n");
	 printf("disk and printed documentation are available for $50.\n");
	 printf("\nIf you fail to abide by the terms of this license, ");
	 printf(" then your conscience\n");
	 printf("will haunt you for the rest of your life.\n\n");
*/
	 printf("Usage: MARC <tgtarc> <srcarc> [<filename> . . .]\n");
	 printf("Where: <tgtarc> is the archive to add files to,\n");
	 printf("	<srcarc> is the archive to get files from, and\n");
	 printf("	<filename> is zero or more file names to get.\n");
	 printf("\nAdapted from MSDOS by Howard Chu\n");
#if	GEMDOS
	 exitpause();
#endif
	 return 1;
    }

	/* see where temp files go */
#if	!_MTS
	arctemp = calloc(1, STRLEN);
	if (!(arctemp2 = envfind("ARCTEMP")))
		arctemp2 = envfind("TMPDIR");
	if (arctemp2) {
		strncpy(arctemp, arctemp2, STRLEN - 16);
		arctemp[STRLEN - 17] = '\0';
		n = strlen(arctemp);
		if (arctemp[n - 1] != CUTOFF)
			arctemp[n] = CUTOFF;
	}
#if	UNIX
	else	strcpy(arctemp, "/tmp/");
#endif
#if	!MSDOS
	{
		static char tempname[] = "AXXXXXX";
		strcat(arctemp, mktemp(tempname));
	}
#else
	strcat(arctemp, "$ARCTEMP");
#endif
#else
	guinfo("SHFSEP	", gotinf);
	sepchr[0] = gotinf[0];
	guinfo("SCRFCHAR", gotinf);
	tmpchr[0] = gotinf[0];
	arctemp = "-$$$";
	arctemp[0] = tmpchr[0];
#endif

	for (n = 1; n < nargs; n++)
	  if (strlen(arg[n]) > (STRLEN - 16))
	  {
	    fprintf(stderr, "Too long argument: %s\n", arg[n]);
	    exit(235);
	  }

#if	UNIX
	if (!stat(arg[1],&sbuf))
		strcpy(arcname,arg[1]);
	else
		makefnam(arg[1],".arc",arcname);
	if (!stat(arg[2],&sbuf))
		strcpy(srcname,arg[2]);
	else
		makefnam(arg[2],".arc",srcname);
#else
    makefnam(arg[1],".ARC",arcname);   /* fix up archive names */
    makefnam(arg[2],".ARC",srcname);
/*	makefnam(".$$$",arcname,newname);*/
#endif
	sprintf(newname,"%s.arc",arctemp);

    arc = fopen(arcname,OPEN_R);	       /* open the archives */
    if(!(src=fopen(srcname,OPEN_R)))
	 arcdie("Cannot read source archive %s",srcname);
    if(!(new=fopen(newname,OPEN_W)))
	 arcdie("Cannot create new archive %s",newname);

    if(!arc)
	 printf("Creating new archive %s\n",arcname);

    /* get the files list set up */

    lnum = nargs-3;		       /* initial length of list */
    if(lnum<1)			       /* phoney for default case */
    {	 lnum = 1;
	 lst = (char **) calloc(1,sizeof(char *));
	 lst[0] = "*.*";
    }
    else			       /* else use filenames given */
    {	 lst = (char **) calloc(lnum,sizeof(char *));
	 for(n=3; n<nargs; n++)
	      lst[n-3] = arg[n];

	 for(n=0; n<lnum; )	       /* expand indirect references */
	 {    if(*lst[n] == '@')
		   expandlst(n);
	      else n++;
	 }
    }
    if (!(pinbuf = malloc(MYBUF)))
	arcdie("Not enough memory for input buffer.");

    merge(lnum,lst);		       /* merge desired files */

    if(arc) fclose(arc);	       /* close the archives */
    fclose(src);
    fclose(new);

    if(arc)			       /* make the switch */
	 if(unlink(arcname))
	      arcdie("Unable to delete old copy of %s",arcname);
    if(move(newname,arcname))
	 arcdie("Unable to rename %s to %s",newname,arcname);

    setstamp(arcname,arcdate,arctime);     /* new arc matches newest file */

#if	GEMDOS
    exitpause();
#endif
    return nerrs;
}

static	VOID
merge(nargs,arg)		       /* merge two archives */
int nargs;			       /* number of filename templates */
char *arg[];			       /* pointers to names */
{
    struct heads srch;		       /* source archive header */
    struct heads arch;		       /* target archive header */
    int gotsrc, gotarc;		       /* archive entry versions (0=end) */
    int copy;			       /* true to copy file from source */
    int n;			       /* index */

    gotsrc = gethdr(src,&srch);	       /* get first source file */
    gotarc = gethdr(arc,&arch);	       /* get first target file */

    while(gotsrc || gotarc)	       /* while more to merge */
    {	 if(strcmp(srch.name,arch.name)>0)
	 {    copyfile(arc,&arch,gotarc);
	      gotarc = gethdr(arc,&arch);
	 }

	 else if(strcmp(srch.name,arch.name)<0)
	 {    copy = 0;
	      for(n=0; n<nargs; n++)
	      {	   if(match(srch.name,arg[n]))
		   {	copy = 1;
			break;
		   }
	      }
	      if(copy)		       /* select source or target */
	      {	   printf("Adding file:	  %s\n",srch.name);
		   copyfile(src,&srch,gotsrc);
	      }
	      else fseek(src,srch.size,1);
	      gotsrc = gethdr(src,&srch);
	 }

	 else			       /* duplicate names */
	 {    copy = 0;
	      {	   if((srch.date>arch.date)
		   || (srch.date==arch.date && srch.time>arch.time))
		   {	for(n=0; n<nargs; n++)
			{    if(match(srch.name,arg[n]))
			     {	  copy = 1;
				  break;
			     }
			}
		   }
	      }
	      if(copy)		       /* select source or target */
	      {	   printf("Updating file: %s\n",srch.name);
		   copyfile(src,&srch,gotsrc);
		   gotsrc = gethdr(src,&srch);
		   if(gotarc)
		   {	fseek(arc,arch.size,1);
			gotarc = gethdr(arc,&arch);
		   }
	      }
	      else
	      {	   copyfile(arc,&arch,gotarc);
		   gotarc = gethdr(arc,&arch);
		   if(gotsrc)
		   {	fseek(src,srch.size,1);
			gotsrc = gethdr(src,&srch);
		   }
	      }
	 }
    }

    hdrver = 0;			       /* end of archive marker */
    writehdr(&arch,new);	       /* mark the end of the archive */
}

int gethdr(f,hdr)		       /* special read header for merge */
FILE *f;			       /* file to read from */
struct heads *hdr;		       /* storage for header */
{
    char *i = hdr->name;	       /* string index */
    int n;			       /* index */

    for(n=0; n<FNLEN; n++)	       /* fill name field */
	 *i++ = 0176;		       /* impossible high value */
    *--i = '\0';		       /* properly end the name */

    hdrver = 0;			       /* reset header version */
    if(readhdr(hdr,f))		       /* use normal reading logic */
	 return hdrver;		       /* return the version */
    else return 0;		       /* or fake end of archive */
}

copyfile(f,hdr,ver)		       /* copy a file from an archive */
FILE *f;			       /* archive to copy from */
struct heads *hdr;		       /* header data for file */
int ver;			       /* header version */
{
    hdrver = ver;		       /* set header version */
    writehdr(hdr,new);		       /* write out the header */
    filecopy(f,new,hdr->size);	       /* copy over the data */
}

static VOID
expandlst(n)			       /* expand an indirect reference */
int n;				       /* number of entry to expand */
{
    FILE *lf, *fopen();		       /* list file, opener */
    char buf[100];		       /* input buffer */
    int x;			       /* index */
    char *p = lst[n]+1;		       /* filename pointer */
    char *makefnam();

    if(*p)			       /* use name if one was given */
    {	 makefnam(p,".CMD",buf);
	 upper(buf);
	 if(!(lf=fopen(buf,"r")))
	      arcdie("Cannot read list of files in %s",buf);
    }
    else lf = stdin;		       /* else use standard input */

    for(x=n+1; x<lnum; x++)	       /* drop reference from the list */
	 lst[x-1] = lst[x];
    lnum--;

    while(fscanf(lf,"%99s",buf)>0)     /* read in the list */
    {	 if(!(lst=(char **) realloc(lst,(lnum+1)*sizeof(char *))))
	      arcdie("too many file references");

	 lst[lnum] = malloc(strlen(buf)+1);
	 strcpy(lst[lnum],buf);	       /* save the name */
	 lnum++;
    }

    if(lf!=stdin)		       /* avoid closing standard input */
	 fclose(lf);
}