perl 4.0 patch 14: patch #11, continued
[p5sagit/p5-mst-13.2.git] / msdos / directory.c
CommitLineData
6e21c824 1/* $RCSfile: directory.c,v $$Revision: 4.0.1.1 $$Date: 91/06/07 11:22:24 $
b1248f16 2 *
3 * (C) Copyright 1987, 1988, 1990 Diomidis Spinellis.
4 *
6e21c824 5 * You may distribute under the terms of either the GNU General Public
6 * License or the Artistic License, as specified in the README file.
b1248f16 7 *
8 * $Log: directory.c,v $
6e21c824 9 * Revision 4.0.1.1 91/06/07 11:22:24 lwall
10 * patch4: new copyright notice
11 *
fe14fcc3 12 * Revision 4.0 91/03/20 01:34:24 lwall
13 * 4.0 baseline.
14 *
b1248f16 15 * Revision 3.0.1.1 90/03/27 16:07:37 lwall
16 * patch16: MSDOS support
17 *
18 * Revision 1.3 90/03/16 22:39:40 dds
19 * Fixed malloc problem.
20 *
21 * Revision 1.2 88/07/23 00:08:39 dds
22 * Added inode non-zero filling.
23 *
24 * Revision 1.1 88/07/23 00:03:50 dds
25 * Initial revision
26 *
27 */
28
29/*
30 * UNIX compatible directory access functions
31 */
32
33#include <sys/types.h>
34#include <sys/dir.h>
35#include <stddef.h>
36#include <stdlib.h>
37#include <string.h>
38#include <dos.h>
39#include <ctype.h>
40
41/*
42 * File names are converted to lowercase if the
43 * CONVERT_TO_LOWER_CASE variable is defined.
44 */
45#define CONVERT_TO_LOWER_CASE
46
47#define PATHLEN 65
48
49#ifndef lint
6e21c824 50static char rcsid[] = "$RCSfile: directory.c,v $$Revision: 4.0.1.1 $$Date: 91/06/07 11:22:24 $";
b1248f16 51#endif
52
53DIR *
54opendir(char *filename)
55{
56 DIR *p;
57 char *oldresult, *result;
58 union REGS srv;
59 struct SREGS segregs;
60 register reslen = 0;
61 char scannamespc[PATHLEN];
62 char *scanname = scannamespc; /* To take address we need a pointer */
63
64 /*
65 * Structure used by the MS-DOS directory system calls.
66 */
67 struct dir_buff {
68 char reserved[21]; /* Reserved for MS-DOS */
69 unsigned char attribute; /* Attribute */
70 unsigned int time; /* Time */
71 unsigned int date; /* Date */
72 long size; /* Size of file */
73 char fn[13]; /* Filename */
74 } buffspc, *buff = &buffspc;
75
76
77 if (!(p = (DIR *) malloc(sizeof(DIR))))
78 return NULL;
79
80 /* Initialize result to use realloc on it */
81 if (!(result = malloc(1))) {
82 free(p);
83 return NULL;
84 }
85
86 /* Create the search pattern */
87 strcpy(scanname, filename);
88 if (strchr("/\\", *(scanname + strlen(scanname) - 1)) == NULL)
89 strcat(scanname, "/*.*");
90 else
91 strcat(scanname, "*.*");
92
93 segread(&segregs);
94#if ( defined(M_I86LM) || defined(M_I86CM) || defined(M_I86HM) )
95 segregs.ds = FP_SEG(buff);
96 srv.x.dx = FP_OFF(buff);
97#else
98 srv.x.dx = (unsigned int) buff;
99#endif
100 srv.h.ah = 0x1a; /* Set DTA to DS:DX */
101 intdosx(&srv, &srv, &segregs);
102
103#if ( defined(M_I86LM) || defined(M_I86CM) || defined(M_I86HM) )
104 segregs.ds = FP_SEG(scanname);
105 srv.x.dx = FP_OFF(scanname);
106#else
107 srv.x.dx = (unsigned int) scanname;
108#endif
109 srv.x.cx = 0xff; /* Search mode */
110
111 for (srv.h.ah = 0x4e; !intdosx(&srv, &srv, &segregs); srv.h.ah = 0x4f) {
112 if ((result = (char *) realloc(result, reslen + strlen(buff->fn) + 1)) ==
113 NULL) {
114 free(p);
115 free(oldresult);
116 return NULL;
117 }
118 oldresult = result;
119#ifdef CONVERT_TO_LOWER_CASE
120 strcpy(result + reslen, strlwr(buff->fn));
121#else
122 strcpy(result + reslen, buff->fn);
123#endif
124 reslen += strlen(buff->fn) + 1;
125 }
126
127 if (!(result = realloc(result, reslen + 1))) {
128 free(p);
129 free(oldresult);
130 return NULL;
131 } else {
132 p->start = result;
133 p->curr = result;
134 *(result + reslen) = '\0';
135 return p;
136 }
137}
138
139
140struct direct *
141readdir(DIR *dirp)
142{
143 char *p;
144 register len;
145 static dummy;
146
147 p = dirp->curr;
148 len = strlen(p);
149 if (*p) {
150 dirp->curr += len + 1;
151 strcpy(dirp->dirstr.d_name, p);
152 dirp->dirstr.d_namlen = len;
153 /* To fool programs */
154 dirp->dirstr.d_ino = ++dummy;
155 return &(dirp->dirstr);
156 } else
157 return NULL;
158}
159
160long
161telldir(DIR *dirp)
162{
163 return (long) dirp->curr; /* ouch! pointer to long cast */
164}
165
166void
167seekdir(DIR *dirp, long loc)
168{
169 dirp->curr = (char *) loc; /* ouch! long to pointer cast */
170}
171
172void
173rewinddir(DIR *dirp)
174{
175 dirp->curr = dirp->start;
176}
177
178void
179closedir(DIR *dirp)
180{
181 free(dirp->start);
182 free(dirp);
183}