Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
6725 siemargl 1
/*
2
  Copyright (c) 1990-2008 Info-ZIP.  All rights reserved.
3
 
4
  See the accompanying file LICENSE, version 2000-Apr-09 or later
5
  (the contents of which are also included in unzip.h) for terms of use.
6
  If, for some reason, all these files are missing, the Info-ZIP license
7
  also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
8
*/
9
/*---------------------------------------------------------------------------
10
 
11
  tanunz.c
12
 
13
  Tandem/NSK routines for use with Info-ZIP's UnZip 5.3 and later.
14
 
15
  Contains:  do_wild()           <-- generic enough to put in fileio.c?
16
             ef_scan_for_tandem()
17
             open_outfile()
18
             mapattr()
19
             mapname()
20
             checkdir()
21
             mkdir()
22
             close_outfile()
23
             version()
24
 
25
  ---------------------------------------------------------------------------*/
26
 
27
 
28
#define UNZIP_INTERNAL
29
#include "unzip.h"
30
 
31
#include 
32
#include "$system.zsysdefs.zsysc" nolist
33
#include  nolist
34
#include "tannsk.h"
35
 
36
 
37
char *in2ex OF((__GPRO__ char *));
38
 
39
static nsk_file_attrs *ef_scan_for_tandem (
40
    uch *ef_buf,
41
    unsigned ef_len
42
  );
43
 
44
 
45
static int created_dir;        /* used in mapname(), checkdir() */
46
static int renamed_fullpath;   /* ditto */
47
 
48
 
49
/****************************/
50
/* Strings used in tanunz.c */
51
/****************************/
52
 
53
static ZCONST char Far CannotDeleteOldFile[] =
54
  "error:  cannot delete old %s\n";
55
static ZCONST char Far CannotCreateFile[] = "error:  cannot create %s\n";
56
 
57
 
58
#ifndef SFX
59
/**********************/
60
/* Function do_wild() */  /* for porting: dir separator; match(ignore_case) */
61
/**********************/
62
 
63
char *do_wild(__G__ wildspec)
64
    __GDEF
65
    ZCONST char *wildspec;  /* only used first time on a given dir */
66
{
67
    static DIR *wild_dir = (DIR *)NULL;
68
    static ZCONST char *wildname;
69
    static char *dirname, matchname[FILNAMSIZ];
70
    static int notfirstcall=FALSE, have_dirname, dirnamelen;
71
    struct dirent *file;
72
    static char *intname;
73
    int isdir = 0;
74
    int pdosflag = 0;
75
 
76
    /* Even when we're just returning wildspec, we *always* do so in
77
     * matchname[]--calling routine is allowed to append four characters
78
     * to the returned string, and wildspec may be a pointer to argv[].
79
     */
80
    if (!notfirstcall) {    /* first call:  must initialize everything */
81
        notfirstcall = TRUE;
82
 
83
        if (!iswild(wildspec)) {
84
            strncpy(matchname, wildspec, FILNAMSIZ);
85
            matchname[FILNAMSIZ-1] = '\0';
86
            have_dirname = FALSE;
87
            wild_dir = NULL;
88
            return matchname;
89
        }
90
 
91
        dirnamelen = strlen(wildspec);
92
 
93
        if ((dirname = (char *)malloc(dirnamelen+1)) == (char *)NULL) {
94
            Info(slide, 0x201, ((char *)slide,
95
              "warning:  cannot allocate wildcard buffers\n"));
96
             strncpy(matchname, wildspec, FILNAMSIZ);
97
             matchname[FILNAMSIZ-1] = '\0';
98
             return matchname;   /* but maybe filespec was not a wildcard */
99
        }
100
        strcpy(dirname, wildspec);
101
        wildname = wildspec;
102
        have_dirname = FALSE;
103
 
104
        if ((wild_dir = opendir(dirname)) != (DIR *)NULL) {
105
            while ((file = readdir(wild_dir)) != (struct dirent *)NULL) {
106
                Trace((stderr, "do_wild: readdir returns %s\n",
107
                  FnFilter1(file->d_name)));
108
                if (file->d_name[0] == '.' && wildname[0] != '.')
109
                    continue;  /* Unix: '*' and '?' do not match leading dot */
110
                if (match(file->d_name, wildname, 0 WISEP) && /* 0=case sens.*/
111
                    /* skip "." and ".." directory entries */
112
                    strcmp(file->d_name, ".") && strcmp(file->d_name, "..")) {
113
                    Trace((stderr, "do_wild: match() succeeds\n"));
114
                    if (have_dirname) {
115
                        strcpy(matchname, dirname);
116
                        strcpy(matchname+dirnamelen, file->d_name);
117
                    } else
118
                        strcpy(matchname, file->d_name);
119
                    return matchname;
120
                }
121
            }
122
            /* if we get to here directory is exhausted, so close it */
123
            closedir(wild_dir);
124
            wild_dir = (DIR *)NULL;
125
        }
126
 
127
        /* return the raw wildspec in case that works (e.g., directory not
128
         * searchable, but filespec was not wild and file is readable) */
129
        strncpy(matchname, wildspec, FILNAMSIZ);
130
        matchname[FILNAMSIZ-1] = '\0';
131
        return matchname;
132
    }
133
 
134
    /* last time through, might have failed opendir but returned raw wildspec */
135
    if (wild_dir == (DIR *)NULL) {
136
        notfirstcall = FALSE; /* nothing left to try--reset for new wildspec */
137
        if (have_dirname)
138
            free(dirname);
139
        return (char *)NULL;
140
    }
141
 
142
    /* If we've gotten this far, we've read and matched at least one entry
143
     * successfully (in a previous call), so dirname has been copied into
144
     * matchname already.
145
     */
146
    while ((file = readdir(wild_dir)) != (struct dirent *)NULL) {
147
        Trace((stderr, "do_wild:  readdir returns %s\n",
148
          FnFilter1(file->d_name)));
149
        if (file->d_name[0] == '.' && wildname[0] != '.')
150
            continue;   /* Unix:  '*' and '?' do not match leading dot */
151
        if (match(file->d_name, wildname, 0 WISEP)) {   /* 0 == case sens. */
152
            if (have_dirname) {
153
                /* strcpy(matchname, dirname); */
154
                strcpy(matchname+dirnamelen, file->d_name);
155
            } else
156
                strcpy(matchname, file->d_name);
157
            return matchname;
158
        }
159
    }
160
 
161
    closedir(wild_dir);     /* have read at least one entry; nothing left */
162
    wild_dir = (DIR *)NULL;
163
    notfirstcall = FALSE;   /* reset for new wildspec */
164
    if (have_dirname)
165
        free(dirname);
166
    return (char *)NULL;
167
 
168
} /* end function do_wild() */
169
 
170
#endif /* !SFX */
171
 
172
 
173
 
174
/*********************************/
175
/* Function ef_scan_for_tandem() */
176
/*********************************/
177
 
178
static nsk_file_attrs *ef_scan_for_tandem(ef_buf, ef_len)
179
    uch *ef_buf;                /* buffer containing extra field */
180
    unsigned ef_len;            /* total length of extra field */
181
{
182
    unsigned eb_id;
183
    unsigned eb_len;
184
 
185
  /*---------------------------------------------------------------------------
186
    This function scans the extra field for EF_TANDEM
187
    -------------------------------------------------------------------------*/
188
 
189
    if (ef_buf == NULL)
190
      return NULL;
191
 
192
    while (ef_len >= EB_HEADSIZE) {
193
      eb_id = makeword(EB_ID + ef_buf);
194
      eb_len = makeword(EB_LEN + ef_buf);
195
 
196
      if (eb_len > (ef_len - EB_HEADSIZE)) {
197
          /* discovered some extra field inconsistency! */
198
          TTrace((stderr,
199
            "ef_scan_for_tandem: block length %u > rest ef_size %u\n", eb_len,
200
            ef_len - EB_HEADSIZE));
201
          break;
202
      }
203
 
204
      switch (eb_id) {
205
        case EF_TANDEM:
206
          return (nsk_file_attrs *)(char *)(ef_buf + EB_HEADSIZE);
207
          break;
208
 
209
        default:
210
          break;
211
      }
212
 
213
      /* Skip this extra field block */
214
      ef_buf += (eb_len + EB_HEADSIZE);
215
      ef_len -= (eb_len + EB_HEADSIZE);
216
  }
217
 
218
  return NULL;
219
}
220
 
221
 
222
/***************************/
223
/* Function open_outfile() */
224
/***************************/
225
 
226
int open_outfile(__G)           /* return 1 if fail */
227
    __GDEF
228
{
229
    int fdesc;
230
    short fnum, err, len;
231
    int priext, secext;
232
    short maxext, filecode, blocksize;
233
 
234
    #define alist_items 1
235
    #define vlist_bytes 2
236
    short alist[alist_items]={42};
237
    unsigned short vlist[alist_items];
238
    short extra, *err_item=&extra;
239
    nsk_file_attrs *znsk_attr;
240
    ulg eof, pages;
241
    char nsk_work[FILENAME_MAX + 1], *nsk_fname=&nsk_work[0];
242
 
243
#ifdef DLL
244
    if (G.redirect_data)
245
        return (redirect_outfile(__G) == FALSE);
246
#endif
247
    if (SSTAT(G.filename, &G.statbuf) == 0) {
248
        Trace((stderr, "open_outfile:  stat(%s) returns 0:  file exists\n",
249
          FnFilter1(G.filename)));
250
        if (unlink(G.filename) != 0) {
251
            Trace((stderr, "open_outfile:  existing file %s is read-only\n",
252
              FnFilter1(G.filename)));
253
            chmod(G.filename, S_IRUSR | S_IWUSR);
254
            Trace((stderr, "open_outfile:  %s now writable\n",
255
              FnFilter1(G.filename)));
256
            if (unlink(G.filename) != 0) {
257
                Info(slide, 0x401, ((char *)slide,
258
                  LoadFarString(CannotDeleteOldFile), FnFilter1(G.filename)));
259
                return 1;
260
            }
261
        }
262
        Trace((stderr, "open_outfile:  %s now deleted\n",
263
          FnFilter1(G.filename)));
264
    }
265
 
266
    /* Set up Tandem specific file information if present */
267
    znsk_attr = ef_scan_for_tandem(G.extra_field, G.lrec.extra_field_length);