maint: include <config.h> first in many files
[gzip.git] / amiga / tailor.c
blob50847749e53aadb72ebb5d0110ad0c1ba6e89ce4
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 */
7 /*
8 * This file contains Amiga specific functions for gzip.
9 */
11 #include <config.h>
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <string.h>
15 #include <error.h>
16 #include <time.h>
17 #include <utime.h>
18 #include <exec/types.h>
19 #include <dos/dos.h>
20 #include <dos/dosextens.h>
21 #include <dos/dosasl.h>
22 #include <proto/dos.h>
24 #define MAXPATH 1024
25 #define MAXARGS 512
27 extern struct DosLibrary *DOSBase;
29 extern void *xmalloc(unsigned int size);
31 static char *expand_next_file (char *pattern);
32 static int in_prev_args (char *arg, char **argv, int argc);
33 extern void _expand_args (int *oargc, char ***oargv);
36 static char *expand_next_file (pattern)
37 char *pattern;
39 long err;
40 char *pathname;
41 static struct AnchorPath *an = NULL;
43 pathname = NULL;
44 if (pattern == NULL)
45 err = -1;
46 else
49 if (an == NULL)
51 an = xmalloc (sizeof (struct AnchorPath) + MAXPATH);
52 memset (an, 0, sizeof (struct AnchorPath) + MAXPATH);
53 an->ap_BreakBits = SIGBREAKF_CTRL_C;
54 an->ap_Strlen = MAXPATH;
55 an->ap_Flags = APF_DOWILD;
56 err = MatchFirst (pattern, an);
58 else
59 err = MatchNext (an);
61 pathname = an->ap_Buf;
62 } while (err == 0 && pathname == NULL);
64 if (err)
66 MatchEnd (an);
67 free (an);
68 an = NULL;
69 return NULL;
71 else
72 return pathname;
76 static int in_prev_args (arg, argv, argc)
77 char *arg, **argv;
78 int argc;
80 int i, is_in_args;
82 is_in_args = 0;
83 for (i = 1; i < argc - 1; i++)
84 if (stricmp (arg, argv[i]) == 0)
85 is_in_args = 1;
86 return is_in_args;
90 void _expand_args (oargc, oargv)
91 int *oargc;
92 char ***oargv;
94 int i;
95 char *str, **argv;
96 static char buf[MAXPATH];
97 int argc, no_match_at_all, num_matches, contains_wildcards;
99 /* With Kickstart 1.3 wildcards can't be expanded. */
100 if (DOSBase->dl_lib.lib_Version < 37) return;
102 no_match_at_all = 1;
103 contains_wildcards = 0;
104 argc = 0;
105 argv = xmalloc (MAXARGS * sizeof (char *));
107 argv[argc++] = (*oargv)[0];
108 for (i = 1; i < *oargc; i++)
110 if (ParsePattern ((*oargv)[i], buf, MAXPATH))
112 contains_wildcards = 1;
113 num_matches = 0;
114 while (str = expand_next_file ((*oargv)[i]))
115 if (argc >= MAXARGS)
117 expand_next_file (NULL);
118 fprintf (stderr,"Too many files.\n");
119 exit (20);
121 else
123 /* Avoid duplicate entries */
124 if (!in_prev_args (str, argv, argc))
126 argv[argc++] = strdup (str);
127 num_matches++;
130 if (num_matches != 0)
131 no_match_at_all = 0;
133 else
134 if (argc >= MAXARGS)
136 fprintf (stderr,"Too many files.\n");
137 exit (20);
139 else
141 if (!in_prev_args ((*oargv)[i], argv, argc))
142 argv[argc++] = (*oargv)[i];
145 *oargc = argc;
146 *oargv = argv;
147 if (no_match_at_all && contains_wildcards) {
148 fprintf (stderr,"No match.\n");
149 exit (20);
154 int utime (path, times)
155 char *path;
156 struct utimbuf *times;
158 struct DateStamp date;
159 LONG error;
160 time_t modtime;
162 /* With Kickstart 1.3 setting the filedate could be done, I guess.
163 * Maybe someone else will implement and test the code for this
164 * case (I don't have Kickstart 1.3). */
165 if (DOSBase->dl_lib.lib_Version < 37) return 0;
167 /* Amiga dates are counted from 1. Jan 1978 as opposed to 1. Jan 1970
168 * on Unix. Therefore we have to subtract 2922 days (8*365+2). We also
169 * have to subtract the value of __timezone since SAS/C uses "CST+06"
170 * as the default value. */
171 modtime = times->modtime - __timezone;
172 date.ds_Days = (modtime / 86400) - 2922;
173 modtime %= 86400;
174 date.ds_Minute = modtime / 60;
175 modtime %= 60;
176 date.ds_Tick = modtime * TICKS_PER_SECOND;
177 error = SetFileDate (path, &date);
178 if (error == DOSFALSE)
180 errno = EOSERR;
181 return -1;
183 return 0;