summaryrefslogtreecommitdiff
path: root/Build/source/utils/gzip/amiga/tailor.c
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/utils/gzip/amiga/tailor.c')
-rw-r--r--Build/source/utils/gzip/amiga/tailor.c183
1 files changed, 183 insertions, 0 deletions
diff --git a/Build/source/utils/gzip/amiga/tailor.c b/Build/source/utils/gzip/amiga/tailor.c
new file mode 100644
index 00000000000..9f14cc45b6c
--- /dev/null
+++ b/Build/source/utils/gzip/amiga/tailor.c
@@ -0,0 +1,183 @@
+/* tailor.c -- target dependent functions
+ * Copyright (C) 1993 Carsten Steger (carsten.steger@informatik.tu-muenchen.de)
+ * This is free software; you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License, see the file COPYING.
+ */
+
+/*
+ * This file contains Amiga specific functions for gzip.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <error.h>
+#include <time.h>
+#include <utime.h>
+#include <exec/types.h>
+#include <dos/dos.h>
+#include <dos/dosextens.h>
+#include <dos/dosasl.h>
+#include <proto/dos.h>
+
+#define MAXPATH 1024
+#define MAXARGS 512
+
+extern struct DosLibrary *DOSBase;
+
+extern void *xmalloc(unsigned int size);
+
+static char *expand_next_file (char *pattern);
+static int in_prev_args (char *arg, char **argv, int argc);
+extern void _expand_args (int *oargc, char ***oargv);
+
+
+static char *expand_next_file (pattern)
+ char *pattern;
+{
+ long err;
+ char *pathname;
+ static struct AnchorPath *an = NULL;
+
+ pathname = NULL;
+ if (pattern == NULL)
+ err = -1;
+ else
+ do
+ {
+ if (an == NULL)
+ {
+ an = xmalloc (sizeof (struct AnchorPath) + MAXPATH);
+ memset (an, 0, sizeof (struct AnchorPath) + MAXPATH);
+ an->ap_BreakBits = SIGBREAKF_CTRL_C;
+ an->ap_Strlen = MAXPATH;
+ an->ap_Flags = APF_DOWILD;
+ err = MatchFirst (pattern, an);
+ }
+ else
+ err = MatchNext (an);
+
+ pathname = an->ap_Buf;
+ } while (err == 0 && pathname == NULL);
+
+ if (err)
+ {
+ MatchEnd (an);
+ free (an);
+ an = NULL;
+ return NULL;
+ }
+ else
+ return pathname;
+}
+
+
+static int in_prev_args (arg, argv, argc)
+ char *arg, **argv;
+ int argc;
+{
+ int i, is_in_args;
+
+ is_in_args = 0;
+ for (i = 1; i < argc - 1; i++)
+ if (stricmp (arg, argv[i]) == 0)
+ is_in_args = 1;
+ return is_in_args;
+}
+
+
+void _expand_args (oargc, oargv)
+ int *oargc;
+ char ***oargv;
+{
+ int i;
+ char *str, **argv;
+ static char buf[MAXPATH];
+ int argc, no_match_at_all, num_matches, contains_wildcards;
+
+ /* With Kickstart 1.3 wildcards can't be expanded. */
+ if (DOSBase->dl_lib.lib_Version < 37) return;
+
+ no_match_at_all = 1;
+ contains_wildcards = 0;
+ argc = 0;
+ argv = xmalloc (MAXARGS * sizeof (char *));
+
+ argv[argc++] = (*oargv)[0];
+ for (i = 1; i < *oargc; i++)
+ {
+ if (ParsePattern ((*oargv)[i], buf, MAXPATH))
+ {
+ contains_wildcards = 1;
+ num_matches = 0;
+ while (str = expand_next_file ((*oargv)[i]))
+ if (argc >= MAXARGS)
+ {
+ expand_next_file (NULL);
+ fprintf (stderr,"Too many files.\n");
+ exit (20);
+ }
+ else
+ {
+ /* Avoid duplicate entries */
+ if (!in_prev_args (str, argv, argc))
+ {
+ argv[argc++] = strdup (str);
+ num_matches++;
+ }
+ }
+ if (num_matches != 0)
+ no_match_at_all = 0;
+ }
+ else
+ if (argc >= MAXARGS)
+ {
+ fprintf (stderr,"Too many files.\n");
+ exit (20);
+ }
+ else
+ {
+ if (!in_prev_args ((*oargv)[i], argv, argc))
+ argv[argc++] = (*oargv)[i];
+ }
+ }
+ *oargc = argc;
+ *oargv = argv;
+ if (no_match_at_all && contains_wildcards) {
+ fprintf (stderr,"No match.\n");
+ exit (20);
+ }
+}
+
+
+int utime (path, times)
+ char *path;
+ struct utimbuf *times;
+{
+ struct DateStamp date;
+ LONG error;
+ time_t modtime;
+
+ /* With Kickstart 1.3 setting the filedate could be done, I guess.
+ * Maybe someone else will implement and test the code for this
+ * case (I don't have Kickstart 1.3). */
+ if (DOSBase->dl_lib.lib_Version < 37) return 0;
+
+ /* Amiga dates are counted from 1. Jan 1978 as opposed to 1. Jan 1970
+ * on Unix. Therefore we have to subtract 2922 days (8*365+2). We also
+ * have to subtract the value of __timezone since SAS/C uses "CST+06"
+ * as the default value. */
+ modtime = times->modtime - __timezone;
+ date.ds_Days = (modtime / 86400) - 2922;
+ modtime %= 86400;
+ date.ds_Minute = modtime / 60;
+ modtime %= 60;
+ date.ds_Tick = modtime * TICKS_PER_SECOND;
+ error = SetFileDate (path, &date);
+ if (error == DOSFALSE)
+ {
+ errno = EOSERR;
+ return -1;
+ }
+ return 0;
+}