~ubuntu-branches/ubuntu/wily/zoo/wily

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
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
#ifndef LINT
/* derived from: misc.c 2.6 88/08/15 16:17:23 */
static char sccsid[]="$Source: /usr/home/dhesi/zoo/RCS/misc.c,v $\n\
$Id: misc.c,v 1.8 91/07/09 01:54:08 dhesi Exp $";
#endif /* LINT */

/*
Copyright (C) 1986, 1987 Rahul Dhesi -- All rights reserved
(C) Copyright 1988 Rahul Dhesi -- All rights reserved
*/
#include "options.h"
/* Miscellaneous functions needed by Zoo but not by Ooz */

#include "zoo.h"
#include "zooio.h"
#include "various.h"

#include "errors.i"
#include "zoofns.h"
#ifndef NOSIGNAL
#include <signal.h>
#endif

#ifdef NEEDCTYP
#include <ctype.h>
#else
#include "portable.h"
#endif

int ver_too_high PARMS((struct zoo_header *));

/*
calc_ofs() is given a string that (supposedly) begins with a string
of digits.  It returns a corresponding numeric value.  If no such
string, it aborts the program with a fatal error message.
*/
long calc_ofs(str)
char *str;
{
   long retval;
   char *p;
   retval = 0L;
   p = str; /* save for error message */
   while (isdigit(*str)) {
      retval = retval * 10L + (*str-'0');
      str++;
   }
   if (*str != '\0')
      prterror ('f', "Invalid number %s\n", p);
   return (retval);
}

/*
choosefname() decides which filename to use.  If a long filename is present,
and if the syntax is that of UNIX, MS-DOS or the portable form, we use it;
else we use the short filename. 
*/

char *choosefname(direntry)
struct direntry *direntry;
{
   char *retptr;                 /* pointer to name that we will return */
   switch (direntry->system_id) {
      case SYSID_NIX:
      case SYSID_PORTABLE:
      case SYSID_MS:
         retptr = (direntry->namlen != 0) ? direntry->lfname : direntry->fname;
         break;
      default:
         retptr = direntry->fname;
         break;
   }
   return (retptr);
} /* choosefname() */

/* 
combine() combines a directory name and a filename, making sure the
two are separated by a path separator 
*/
char *combine(result, dirname, fname)
char result[], *dirname, *fname;
{
   *result = '\0';
   if (*dirname != '\0') {
#ifdef DIR_LBRACK /* hack for VMS */
      strcat (result, DIR_LBRACK);

      /*  "/" => "[",  "./" => "[."  others => "[." */

      if (dirname[0] == '/') {        /* absolute path => "[" */
         strcat (result, dirname + 1);
      } else if (dirname[0] == '.' && dirname[1] == '/') {
         strcat (result, CUR_DIR);
         strcat (result, dirname + 2);
      } else {
         strcat (result, CUR_DIR);
         strcat (result, dirname);
      }

/* folowing #ifdef block ought to be outside #ifdef DIR_LBRACK, and
   for loop should then start with p=result.  This is currently
   just a hack for VMS.
*/
#ifdef DIR_SEP
   if (DIR_SEP != '/') {   /* if char separating dirs is not "/",  */
      char *p;
      for (p = result+2;  *p != '\0';  p++) /* change it to underscore */
        if (*p == DIR_SEP)
           *p = '_';
   }
#endif

      {
         char *p;
         for (p = result; *p != '\0';  p++)
         if (*p == '/')
            *p = '.';
      }
#else
      strcat (result, dirname);
#endif
      if (*lastptr(result) != *PATH_CH)
         strcat(result, PATH_CH);
   }

   strcat(result, fname);
   return (result);
}

/*
fullpath() accepts a pointer to a directory entry and returns the
combined directory name + filename.  The long filename is used
if available, else the short filename is used.
*/
char *fullpath (direntry)
struct direntry *direntry;
{
	static char result[PATHSIZE];
	combine (result,
				direntry->dirlen != 0 ? direntry->dirname : "", 
				(direntry->namlen != 0) ? direntry->lfname : direntry->fname
			  );
	return (result);
}

/* 
ver_too_high returns true if version of provided archive header is
too high for us to manipulate archive
*/

int ver_too_high (header)
struct zoo_header *header;
{
   return (header->major_ver > MAJOR_VER ||
            (header->major_ver == MAJOR_VER &&
             header->minor_ver > MINOR_VER));
}

/* 
rwheader() reads archive header, checks consistency, makes sure its
version number is not too high, updates it if too low, and seeks to
beginning of first directory entr.  If `preserve' is 1, it preserves
the header type;  if `preserve' is 0, it gives a fatal error message
if type is 0.
*/

void rwheader (header, zoo_file, preserve)
register struct zoo_header *header;
ZOOFILE zoo_file;
int preserve;
{

   frd_zooh (header, zoo_file);

   if ((header->zoo_start + header->zoo_minus) != 0L)
      prterror ('f', failed_consistency);
   if (ver_too_high (header))
      prterror ('f', wrong_version, header->major_ver, header->minor_ver);

	if (preserve == 0 && header->type == 0)
		prterror ('f', packfirst);

   /* We reach here if the archive version is not too high.  Now, if it
   isn't the same as ours, we bring it up to ours so the modified archive
   will be safe from previous versions of Zoo */

   if (header->major_ver != MAJOR_VER || header->minor_ver != MINOR_VER) {
      header->major_ver = MAJOR_VER;
      header->minor_ver = MINOR_VER;
      zooseek (zoo_file, 0L, 0);            /* seek to beginning */
      fwr_zooh (header, zoo_file);
   }
   zooseek (zoo_file, header->zoo_start, 0); /* seek to where data begins */
} /* rwheader */

/*
writedir() write a directory entry with keyboard interrupt disabled
*/
void writedir (direntry, zoo_file)
struct direntry *direntry;
ZOOFILE zoo_file;
{
#ifndef NOSIGNAL  
   T_SIGNAL (*oldsignal)();
   oldsignal = signal (SIGINT, SIG_IGN);
#endif
   if (fwr_dir (direntry, zoo_file) == -1)
      prterror ('f', disk_full);
#ifndef NOSIGNAL
   signal (SIGINT, oldsignal);
#endif
}

/* 
readdir() reads a directory entry from an archive.  If the directory
entry is invalid and if fail is 1, it causes a fatal error;
else it returns.  Return value is 0 if no error else -1;
*/

int readdir (direntry, zoo_file, fail)    /* read directory entry */
register struct direntry *direntry;
ZOOFILE zoo_file;
int fail;                              /* 0 -> return, 1 -> abort on error */
{
   if (frd_dir (direntry, zoo_file) < 0) {
      if (fail) {
         prterror ('f', bad_directory);
      } else
         return (-1);
   }
   if (direntry->zoo_tag != ZOO_TAG) {
      if (fail)
         prterror ('f', bad_directory);
      else
         return (-1);
   }
   return (0);
}

/* use pointer version below */
#ifdef COMMENT
/* instr() searches a string for a substring */
instr (s, t)      /* return index of string t in string s, -1 if none */
char s[], t[];    /*  .. from K&R page 67 */
{
   int i;
   register int j, k;
   for (i = 0; s[i] != '\0'; i++) {
      for (j = i, k = 0; t[k] != '\0' && s[j]==t[k]; j++, k++)
         ;
      if (t[k] == '\0')
         return (i);
   }
   return (-1);
}
#endif /* COMMENT */

/* instr() searches a string for a substring */
/* from J. Brian Waters */
int instr (s, t)   		/* return the position of t in s, -1 if none */
char *s, *t;				/*  a pointer version of K&R index function p.67 */
{               /* renamed to instr() to avoid conflicts with C RTL - JBW */

   register char *i, *j, *k;

   for (i = s; *i; i++) {
      for (j = i, k = t; (*k) && (*j++ == *k); k++)
         ;
       if (!*k)
         return ((int) (i - s));
   }
   return(-1);
}

/* cfactor() calculates the compression factor given a directory entry */
int cfactor (org_size, size_now)
long org_size, size_now;
{
   register int size_factor;
   while ((unsigned long) org_size > 32000) { /* avoid later overflow */
      org_size = (unsigned long) org_size / 1024;
      size_now = (unsigned long) size_now / 1024;
   }
   if (org_size == 0)         /* avoid division by zero */
      size_factor = 0;
   else {
      size_factor = (int)
         (
            (1000 * 
               ((unsigned long) org_size - (unsigned long) size_now)
            ) / org_size + 5
         ) / 10;
   }
   return (size_factor);
}

/***********
str_dup() duplicates a string using dynamic memory.
*/

char *str_dup (str)
register char *str;
{
   return (strcpy (emalloc (strlen(str)+1), str));
}

/**************
cmpnum() compares two pairs of unsigned integers and returns a negative,
zero, or positive value as the comparison yields less than, equal, or
greater than result.  Each pair of unsigned integers is considered to be the
more significant and the less significant half of a longer unsigned number.

Note:  cmpnum is used to compare dates and times.
*/

int cmpnum (hi1, lo1, hi2, lo2)
register unsigned int hi1, hi2;
unsigned int lo1, lo2;
{
   if (hi1 != hi2)
      return (hi1 > hi2 ? 1 : -1);
   else {
		if (lo1 == lo2)
			return (0);
		else
			return (lo1 > lo2 ? 1 : -1);
	}
}

/*******************/
/* writenull() */
/* writes a null directory entry to an open archive */
void writenull (file, length)
ZOOFILE file;
int length;
{
#ifndef NOSIGNAL
   T_SIGNAL (*oldsignal)();
#endif
   struct direntry newentry;
   memset ((char *) &newentry, 0, sizeof (newentry));
   newentry.zoo_tag = ZOO_TAG;
   newentry.type = 2;
   /* Force entry to be the required length plus possibly 2 stray bytes
   by dividing up the needed padding into dirlen and namlen. */
   if (length > SIZ_DIRL)
      newentry.dirlen = newentry.namlen = (length-SIZ_DIRL)/2 + 2;
   else
      newentry.dirlen = newentry.namlen = 0;
#ifndef NOSIGNAL
   oldsignal = signal (SIGINT, SIG_IGN);
#endif
   if (fwr_dir (&newentry, file) == -1)
      prterror ('f', disk_full);
#ifndef NOSIGNAL
   signal (SIGINT, oldsignal);
#endif
}

#ifdef FORCESLASH
/*******************/
/*
fixslash() changes all "\" characters in the supplied string to "/".
*/

void fixslash (str)
char *str;
{
   register char *p;
   for (p = str; *p != '\0'; p++)
      if (*p == '\\')
         *p = '/';
}
#endif /* FORCESLASH */