Merge pull request #12 from davel/davel/sqsh
[debian-nspark.git] / misc.c
blob7370d6431da44af2777175a794ed295d1f9f1fae
2 /*
3 * miscellaneous functions
5 * Revision 1.14 99/03/17 MU
6 * Also capitilised the hexadecimal output strings.
8 * $Header: misc.c 1.12 95/08/01 $
9 * $Log: misc.c,v $
10 * Revision 1.13 95/08/01 xx:xx:xx BB
11 * Fixed for Borland C/C++
12 * Made inlist() case insensitive (DOS only) because DOS filenames are case
13 * insensitive.
14 * Made basename safe for null-strings.
16 * Revision 1.12 92/12/22 09:54:29 duplain
17 * Changed #include <malloc.h> to #include <stdlib.h> .
19 * Revision 1.11 92/12/09 09:42:36 duplain
20 * Simplified append_type(). Changed append_type() to append lowercase types.
22 * Revision 1.10 92/12/08 10:20:07 duplain
23 * Added append_type().
25 * Revision 1.9 92/12/07 17:18:58 duplain
26 * reformatted source.
28 * Revision 1.8 92/11/12 09:03:30 duplain
29 * Fixed bug with realloc() size in uplevel().
31 * Revision 1.7 92/11/06 12:42:28 duplain
32 * Changed print_details() so it supports PC archive headers correctly.
34 * Revision 1.6 92/11/04 16:56:14 duplain
35 * Added check for PC archive header in print_header().
37 * Revision 1.5 92/10/09 18:06:58 duplain
38 * Added "+1" to malloc() call in riscos_path()... SCO UNIX was quiet right
39 * to core dump :-)
41 * Revision 1.4 92/10/07 10:56:39 duplain
42 * Added check for SYSV2 when including <malloc.h>. Made riscos_path() compile
43 * for non-RISCOS systems only.
45 * Revision 1.3 92/10/06 12:12:29 duplain
46 * Removed reference to date->csecond in print_details().
48 * Revision 1.2 92/09/30 10:26:58 duplain
49 * Fixed basename(). Added riscos_path().
51 * Revision 1.1 92/09/29 18:02:21 duplain
52 * Initial revision
56 #include <stdlib.h>
57 #include <string.h>
59 #include <stdio.h>
60 #include "spark.h"
61 #include "main.h"
63 #include "date.h"
64 #include "misc.h"
65 #include "error.h"
68 * return last element in pathname
70 char *
71 basename(char *s)
73 /* BB changed next line to cope with null-pointers.
74 (IRIX's strlen() produces a coredump when s == NULL). */
75 /* char *cptr = s + strlen(s); */
76 char *cptr;
77 if (!s)
78 return NULL;
79 cptr = s + strlen(s);
80 while (cptr > s)
82 if (*cptr == PATHSEP)
83 return (++cptr);
84 cptr--;
86 return (s);
89 #if defined(RISCOS)
90 #define DOTARC "_arc"
91 #define DOT '_'
92 #else /* not RISCOS */
93 #define DOTARC ".arc"
94 #define DOT '.'
95 #endif /* RISCOS */
98 * append ".arc" ("_arc" in RISCOS) to a string, if an extension doesn't
99 * already exist, and return the new string.
101 char *
102 name_dot_arc(char *s)
104 static char *newname = NULL;
107 * check that there's room for the extension
109 if (strlen(basename(s)) + sizeof(DOTARC) - 1 > FILENAMELEN)
110 return (s);
113 * free previous allocation (hope it's finished with :-/)
115 if (newname)
116 free(newname);
117 newname = malloc(strlen(s) + sizeof(DOTARC));
118 if (!newname)
119 return (s); /* don't complain */
120 strcpy(newname, s);
121 strcat(newname, DOTARC);
122 return (newname);
126 * turn a local-host pathname into a RISC OS path
129 #ifndef RISCOS
130 char *
131 riscos_path(register char *s)
133 static char *riscosname = NULL;
134 register char *cptr;
136 if (riscosname)
137 free(riscosname);
139 riscosname = malloc(strlen(s) + 1);
140 if (!riscosname)
141 return (NULL);
142 for (cptr = riscosname; *s; s++, cptr++)
143 if (*s == PATHSEP)
144 *cptr = '.';
145 else
146 *cptr = *s;
147 *cptr = '\0';
148 return (riscosname);
150 #endif /* RISC OS */
152 static char *pathname = NULL;
155 * uplevel() and downlevel() maintain the pathname as directories are found
156 * within the archive
158 char *
159 uplevel()
161 register char *cptr;
162 register int olen, nlen;
164 if (!pathname)
165 return (NULL);
167 olen = strlen(pathname);
168 cptr = pathname + olen - 1;
169 while (cptr > pathname)
170 if (*cptr == PATHSEP)
172 *cptr = '\0';
173 break;
175 else
176 cptr--;
178 if (cptr == pathname)
180 free(pathname);
181 pathname = NULL;
183 else
185 nlen = strlen(pathname);
186 if (nlen < olen)
187 pathname = realloc(pathname, nlen + 1);
189 return (pathname);
192 char *
193 downlevel(char *filename)
195 register int len, flen;
197 if (!pathname)
198 len = 0;
199 else
200 len = strlen(pathname);
202 flen = strlen(filename);
203 if (!len)
205 pathname = malloc(flen + 1);
206 if (pathname)
207 strcpy(pathname, filename);
209 else
211 pathname = realloc(pathname, len + flen + 2);
212 if (pathname)
214 strcat(pathname, PATHSEPSTR);
215 strcat(pathname, filename);
218 return (pathname);
221 char *
222 get_comp_desc(Byte comptype)
224 switch (comptype & ~ARCHPACK)
226 case CT_NOTCOMP:
227 case CT_NOTCOMP2:
228 return "Stored";
229 case CT_PACK:
230 return "Packed";
231 case CT_CRUNCH:
232 return "Crunched";
233 case CT_SQUASH:
234 return "Squashed";
235 case CT_COMP:
236 return "Compressed";
237 default:
238 return "Unknown";
241 return "Unknown";
245 * print archive file details (size, data and time)
247 void
248 print_details(Header *header)
250 Date *date;
252 if (!header)
253 return;
255 if (header->comptype & ARCHPACK)
257 /* Archimedes archive header */
259 /* BB changed constants in next line to long */
260 if ((header->load & (Word) 0xfff00000l) == (Word) 0xfff00000l)
262 /* time stamp valid */
263 date = makedate(header);
264 msg("%8ld %02d-%s-%04d %02d:%02d:%02d &%03X %s",
265 (long)header->origlen, date->day,
266 monthname(date->month), date->year + 1900,
267 date->hour, date->minute, date->second,
268 (header->load >> 8) & 0xfff,
269 get_comp_desc(header->comptype));
272 else
274 /* load/exec only */
275 /* BB added long to first format in next line.
276 Header.origlen is a Word (i.e. a long) */
277 #ifdef __MSDOS__
278 msg("%8ld &%08lX &%08lX ---- %s", header->origlen,
279 #else
280 msg("%8d &%08lX &%08lX ---- %s", header->origlen,
281 #endif /* __MSDOS__ */
282 (long)header->load, (long)header->exec,
283 get_comp_desc(header->comptype));
286 else
288 /* PC archive header */
289 date = makedate(header);
290 msg("%8ld %02d-%s-%02d %02d:%02d:%02d ---- %s",
291 (long)header->origlen, date->day, monthname(date->month),
292 date->year + 1900, date->hour, date->minute, date->second,
293 get_comp_desc(header->comptype));
298 * Test if the given filename matches any of the names specified in the
299 * command line "files list". This function is also used to test if a given
300 * pathname is contained in the any of the names given in the "files list".
302 * Returns non-zero if filename matches, or no "files list" exists.
305 inlist(char *filename)
307 register int len = strlen(filename);
308 register char **filelist = files;
310 if (!*filelist)
311 return (1); /* no "files list" */
313 while (*filelist)
314 #ifdef __MSDOS__
315 if (strnicmp(filename, *filelist++, len) == 0)
316 #else
317 if (strncmp(filename, *filelist++, len) == 0)
318 #endif /* __MSDOS__ */
319 return (1);
320 return (0);
324 * append the file's type to the end if it's name
325 * (this function assumes that enough storage is available in the argument
326 * "filename" to store the additional characters ",XXX")
329 /* BB: For DOS, a comma is of no use. So changed that into a dot. */
331 append_type(Header *header, char *filename)
333 char append[sizeof(",xxx")];
335 /* BB changed constants in next line to long. */
336 if ((header->load & (Word) 0xfff00000l) == (Word) 0xfff00000l)
338 /* valid time-stamp */
339 #ifdef __MSDOS__
340 sprintf(append, ".%03X", (header->load >> 8) & 0xfff);
341 #else
342 sprintf(append, ",%03X", (header->load >> 8) & 0xfff);
343 #endif /* __MSDOS__ */
344 strcat(filename, append);
345 return (0);
347 return (-1);
350 #ifdef DEBUGGING
353 * print archive file header info
355 void
356 print_header(Header *header)
358 if (!header)
359 return;
361 debug("comptype=0X%X name=%s complen=%lu date=0X%X time=0X%X\n",
362 header->comptype, header->name, header->complen, header->date,
363 header->time);
364 debug("crc=0X%X origlen=%lu load=0X%lX exec=0X%lX attr=0x%lX\n",
365 header->crc, header->origlen, header->load, header->exec,
366 header->attr);
369 #endif /* DEBUGGING */