]> git.cworth.org Git - gzip/blob - amiga/tailor.c
Avoid creating an undersized buffer for the hufts table.
[gzip] / amiga / tailor.c
1 /* tailor.c -- target dependent functions
2  * Copyright (C) 1993 Carsten Steger (carsten.steger@informatik.tu-muenchen.de)
3  * This is free software; you can redistribute it and/or modify it under the
4  * terms of the GNU General Public License, see the file COPYING.
5  */
6
7 /*
8  * This file contains Amiga specific functions for gzip.
9  */
10
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <error.h>
15 #include <time.h>
16 #include <utime.h>
17 #include <exec/types.h>
18 #include <dos/dos.h>
19 #include <dos/dosextens.h>
20 #include <dos/dosasl.h>
21 #include <proto/dos.h>
22
23 #define MAXPATH 1024
24 #define MAXARGS 512
25
26 extern struct DosLibrary *DOSBase;
27
28 extern void *xmalloc(unsigned int size);
29
30 static char *expand_next_file (char *pattern);
31 static int in_prev_args (char *arg, char **argv, int argc);
32 extern void _expand_args (int *oargc, char ***oargv);
33
34
35 static char *expand_next_file (pattern)
36      char *pattern;
37 {
38   long err;
39   char *pathname;
40   static struct AnchorPath *an = NULL;
41
42   pathname = NULL;
43   if (pattern == NULL)
44     err = -1;
45   else
46     do
47       {
48         if (an == NULL)
49           {
50             an = xmalloc (sizeof (struct AnchorPath) + MAXPATH);
51             memset (an, 0, sizeof (struct AnchorPath) + MAXPATH);
52             an->ap_BreakBits = SIGBREAKF_CTRL_C;
53             an->ap_Strlen = MAXPATH;
54             an->ap_Flags = APF_DOWILD;
55             err = MatchFirst (pattern, an);
56           }
57         else
58           err = MatchNext (an);
59
60         pathname = an->ap_Buf;
61       } while (err == 0 && pathname == NULL);
62
63   if (err)
64     {
65       MatchEnd (an);
66       free (an);
67       an = NULL;
68       return NULL;
69     }
70   else
71     return pathname;
72 }
73
74
75 static int in_prev_args (arg, argv, argc)
76      char *arg, **argv;
77      int argc;
78 {
79   int i, is_in_args;
80
81   is_in_args = 0;
82   for (i = 1; i < argc - 1; i++)
83     if (stricmp (arg, argv[i]) == 0)
84       is_in_args = 1;
85   return is_in_args;
86 }
87
88
89 void _expand_args (oargc, oargv)
90      int *oargc;
91      char ***oargv;
92 {
93   int i;
94   char *str, **argv;
95   static char buf[MAXPATH];
96   int argc, no_match_at_all, num_matches, contains_wildcards;
97
98   /* With Kickstart 1.3 wildcards can't be expanded. */
99   if (DOSBase->dl_lib.lib_Version < 37) return;
100
101   no_match_at_all = 1;
102   contains_wildcards = 0;
103   argc = 0;
104   argv = xmalloc (MAXARGS * sizeof (char *));
105
106   argv[argc++] = (*oargv)[0];
107   for (i = 1; i < *oargc; i++)
108     {
109       if (ParsePattern ((*oargv)[i], buf, MAXPATH))
110         {
111           contains_wildcards = 1;
112           num_matches = 0;
113           while (str = expand_next_file ((*oargv)[i]))
114             if (argc >= MAXARGS)
115               {
116                 expand_next_file (NULL);
117                 fprintf (stderr,"Too many files.\n");
118                 exit (20);
119               }
120             else
121               {
122                 /* Avoid duplicate entries */
123                 if (!in_prev_args (str, argv, argc))
124                   {
125                     argv[argc++] = strdup (str);
126                     num_matches++;
127                   }
128               }
129           if (num_matches != 0)
130             no_match_at_all = 0;
131         }
132       else
133         if (argc >= MAXARGS)
134           {
135             fprintf (stderr,"Too many files.\n");
136             exit (20);
137           }
138         else
139           {
140             if (!in_prev_args ((*oargv)[i], argv, argc))
141               argv[argc++] = (*oargv)[i];
142           }
143     }
144   *oargc = argc;
145   *oargv = argv;
146   if (no_match_at_all && contains_wildcards) {
147     fprintf (stderr,"No match.\n");
148     exit (20);
149   }
150 }
151
152
153 int utime (path, times)
154      char *path;
155      struct utimbuf *times;
156 {
157   struct DateStamp date;
158   LONG error;
159   time_t modtime;
160
161   /* With Kickstart 1.3 setting the filedate could be done, I guess.
162    * Maybe someone else will implement and test the code for this
163    * case (I don't have Kickstart 1.3). */
164   if (DOSBase->dl_lib.lib_Version < 37) return 0;
165
166   /* Amiga dates are counted from 1. Jan 1978 as opposed to 1. Jan 1970
167    * on Unix. Therefore we have to subtract 2922 days (8*365+2). We also
168    * have to subtract the value of __timezone since SAS/C uses "CST+06"
169    * as the default value. */
170   modtime = times->modtime - __timezone;
171   date.ds_Days = (modtime / 86400) - 2922;
172   modtime %= 86400;
173   date.ds_Minute = modtime / 60;
174   modtime %= 60;
175   date.ds_Tick = modtime * TICKS_PER_SECOND;
176   error = SetFileDate (path, &date);
177   if (error == DOSFALSE)
178     {
179       errno = EOSERR;
180       return -1;
181     }
182   return 0;
183 }