1/*
2  Copyright (c) 1990-2000 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  macdir.c
12
13 *  This file provides dirent-style directory-reading procedures
14 *  for V7 Unix systems that don't have such procedures.
15 *
16 *
17  ---------------------------------------------------------------------------*/
18
19
20/*****************************************************************************/
21/*  Includes                                                                 */
22/*****************************************************************************/
23
24
25#include    <Errors.h>
26#include    <Files.h>
27#include    <Strings.h>
28#include    <sound.h>
29
30#include <errno.h>
31#include <stdio.h>
32#include <stdlib.h>
33#include <string.h>
34
35#include "macdir.h"
36#include "helpers.h"
37#include "pathname.h"
38
39
40/*****************************************************************************/
41/*  Functions                                                                */
42/*****************************************************************************/
43
44int closedir(DIR *dPtr)
45{
46    free(dPtr);
47
48    return 0;
49}
50
51
52DIR *opendir(char *dirName)
53{
54    int fullPath;
55    unsigned pathLen;
56    char *s;
57    HParamBlockRec hPB;
58    CInfoPBRec cPB;
59    DIR *dPtr;
60    OSErr err;
61    FSSpec spec;
62    char CompletePath[NAME_MAX];
63
64    GetCompletePath(CompletePath, dirName, &spec, &err);
65    printerr("GetCompletePath", err, err, __LINE__, __FILE__, dirName);
66
67    if (dirName == NULL || *dirName == '\0' ||
68        (pathLen = strlen(dirName)) >= 256) {
69        errno = EINVAL;
70        return NULL;
71    }
72
73
74    /* Get information about volume. */
75    memset(&hPB, '\0', sizeof(hPB));
76
77    if (((s = strchr(dirName, ':')) == NULL) || (*dirName == ':')) {
78        fullPath = false;
79    } else {
80        *(s + 1) = '\0';
81        hPB.volumeParam.ioVolIndex = -1;
82        fullPath = true;
83    }
84
85    hPB.volumeParam.ioNamePtr = spec.name;
86
87    err = PBHGetVInfoSync(&hPB);
88
89    if ((err != noErr) || (hPB.volumeParam.ioVFSID != 0)) {
90        errno = ENOENT;
91        return NULL;
92    }
93
94    /* Get information about file. */
95
96    memset(&cPB, '\0', sizeof(cPB));
97
98    if (fullPath)
99        cPB.hFileInfo.ioVRefNum = hPB.volumeParam.ioVRefNum;
100
101    cPB.hFileInfo.ioNamePtr = spec.name;
102
103    err = PBGetCatInfoSync(&cPB);
104
105    if (err != noErr) {
106        errno = (err == fnfErr) ? ENOENT : EIO;
107        return NULL;
108    }
109
110    if (!(cPB.hFileInfo.ioFlAttrib & ioDirMask)) {
111        errno = ENOTDIR;
112        return NULL;
113    }
114
115    /* Get space for, and fill in, DIR structure. */
116
117    if ((dPtr = (DIR *)malloc(sizeof(DIR))) == NULL) {
118        return NULL;
119    }
120
121    dPtr->ioVRefNum = cPB.dirInfo.ioVRefNum;
122    dPtr->ioDrDirID = cPB.dirInfo.ioDrDirID;
123    dPtr->ioFDirIndex = 1;
124    dPtr->flags = 0;
125
126    return dPtr;
127}
128
129
130struct dirent *readdir(DIR *dPtr)
131{
132    struct dirent *dirPtr;
133    CInfoPBRec cPB;
134    char name[256];
135    OSErr err;
136
137    if (dPtr->flags) {
138        return NULL;
139    }
140
141    /* Get information about file. */
142
143    memset(&cPB, '\0', sizeof(cPB));
144
145    cPB.hFileInfo.ioNamePtr = (StringPtr)name;
146    cPB.hFileInfo.ioFDirIndex = dPtr->ioFDirIndex;
147    cPB.hFileInfo.ioVRefNum = dPtr->ioVRefNum;
148    cPB.hFileInfo.ioDirID = dPtr->ioDrDirID;
149
150    err = PBGetCatInfoSync(&cPB);
151
152    if (err != noErr) {
153        dPtr->flags = 0xff;
154        errno = (err == fnfErr) ? ENOENT : EIO;
155        return NULL;
156    }
157
158    p2cstr((StringPtr)name);
159
160    dirPtr = &dPtr->currEntry;
161
162    dirPtr->d_fileno = dPtr->ioFDirIndex++;
163    dirPtr->d_namlen = strlen(name);
164    strcpy(dirPtr->d_name, name);
165    dirPtr->d_reclen = sizeof(struct dirent) - sizeof(dirPtr->d_name) +
166                       dirPtr->d_namlen;
167
168    return dirPtr;
169}
170