Remove autogenerated files
[debian/tar] / src / msd_dir.c
1 /*
2  * @(#)msd_dir.c 1.4 87/11/06   Public Domain.
3  *
4  *  A public domain implementation of BSD directory routines for
5  *  MS-DOS.  Written by Michael Rendell ({uunet,utai}michael@garfield),
6  *  August 1897
7  */
8
9 #include        <sys/types.h>
10 #include        <sys/stat.h>
11 #include        "msd_dir.h"
12 #ifndef __TURBOC__
13 #include        <malloc.h>
14 #endif
15 #include        <string.h>
16 #include        <dos.h>
17
18 #ifndef NULL
19 # define        NULL    0
20 #endif  /* NULL */
21
22 #ifndef MAXPATHLEN
23 # define        MAXPATHLEN      255
24 #endif  /* MAXPATHLEN */
25
26 /* attribute stuff */
27 #define A_RONLY         0x01
28 #define A_HIDDEN        0x02
29 #define A_SYSTEM        0x04
30 #define A_LABEL         0x08
31 #define A_DIR           0x10
32 #define A_ARCHIVE       0x20
33
34 /* dos call values */
35 #define DOSI_FINDF      0x4e
36 #define DOSI_FINDN      0x4f
37 #define DOSI_SDTA       0x1a
38
39 #define Newisnull(a, t)         ((a = (t *) malloc(sizeof(t))) == (t *) NULL)
40 /* #define      ATTRIBUTES              (A_DIR | A_HIDDEN | A_SYSTEM) */
41 #define ATTRIBUTES      (A_RONLY | A_SYSTEM | A_DIR)
42
43 /* what find first/next calls look use */
44 typedef struct {
45         char            d_buf[21];
46         char            d_attribute;
47         unsigned short  d_time;
48         unsigned short  d_date;
49         long            d_size;
50         char            d_name[13];
51 } Dta_buf;
52
53 static  char    *getdirent();
54 static  void    mysetdta();
55 static  void    free_dircontents();
56
57 static  Dta_buf         dtabuf;
58 static  Dta_buf         *dtapnt = &dtabuf;
59 static  union REGS      reg, nreg;
60
61 #if     defined(M_I86LM)
62 static  struct SREGS    sreg;
63 #endif
64
65 DIR     *
66 opendir(name)
67         char    *name;
68 {
69         struct  stat            statb;
70         DIR                     *dirp;
71         char                    c;
72         char                    *s;
73         struct _dircontents     *dp;
74         char                    nbuf[MAXPATHLEN + 1];
75         
76         if (stat(name, &statb) < 0 || (statb.st_mode & S_IFMT) != S_IFDIR)
77                 return (DIR *) NULL;
78         if (Newisnull(dirp, DIR))
79                 return (DIR *) NULL;
80         if (*name && (c = name[strlen(name) - 1]) != '\\' && c != '/')
81                 (void) strcat(strcpy(nbuf, name), "\\*.*");
82         else
83                 (void) strcat(strcpy(nbuf, name), "*.*");
84         dirp->dd_loc = 0;
85         mysetdta();
86         dirp->dd_contents = dirp->dd_cp = (struct _dircontents *) NULL;
87         if ((s = getdirent(nbuf)) == (char *) NULL)
88                 return dirp;
89         do {
90                 if (Newisnull(dp, struct _dircontents) || (dp->_d_entry =
91                         malloc((unsigned) (strlen(s) + 1))) == (char *) NULL)
92                 {
93                         if (dp)
94                                 free((char *) dp);
95                         free_dircontents(dirp->dd_contents);
96                         return (DIR *) NULL;
97                 }
98                 if (dirp->dd_contents)
99                         dirp->dd_cp = dirp->dd_cp->_d_next = dp;
100                 else
101                         dirp->dd_contents = dirp->dd_cp = dp;
102                 (void) strcpy(dp->_d_entry, s);
103                 dp->_d_next = (struct _dircontents *) NULL;
104         } while ((s = getdirent((char *) NULL)) != (char *) NULL);
105         dirp->dd_cp = dirp->dd_contents;
106
107         return dirp;
108 }
109
110 void
111 closedir(dirp)
112         DIR     *dirp;
113 {
114         free_dircontents(dirp->dd_contents);
115         free((char *) dirp);
116 }
117
118 struct dirent   *
119 readdir(dirp)
120         DIR     *dirp;
121 {
122         static  struct dirent   dp;
123         
124         if (dirp->dd_cp == (struct _dircontents *) NULL)
125                 return (struct dirent *) NULL;
126         dp.d_namlen = dp.d_reclen =
127                 strlen(strcpy(dp.d_name, dirp->dd_cp->_d_entry));
128         strlwr(dp.d_name);              /* JF */
129         dp.d_ino = 0;
130         dirp->dd_cp = dirp->dd_cp->_d_next;
131         dirp->dd_loc++;
132
133         return &dp;
134 }
135
136 void
137 seekdir(dirp, off)
138         DIR     *dirp;
139         long    off;
140 {
141         long                    i = off;
142         struct _dircontents     *dp;
143
144         if (off < 0)
145                 return;
146         for (dp = dirp->dd_contents ; --i >= 0 && dp ; dp = dp->_d_next)
147                 ;
148         dirp->dd_loc = off - (i + 1);
149         dirp->dd_cp = dp;
150 }
151
152 long
153 telldir(dirp)
154         DIR     *dirp;
155 {
156         return dirp->dd_loc;
157 }
158
159 static  void
160 free_dircontents(dp)
161         struct  _dircontents    *dp;
162 {
163         struct _dircontents     *odp;
164
165         while (dp) {
166                 if (dp->_d_entry)
167                         free(dp->_d_entry);
168                 dp = (odp = dp)->_d_next;
169                 free((char *) odp);
170         }
171 }
172
173 static  char    *
174 getdirent(dir)
175         char    *dir;
176 {
177         if (dir != (char *) NULL) {             /* get first entry */
178                 reg.h.ah = DOSI_FINDF;
179                 reg.h.cl = ATTRIBUTES;
180 #if     defined(M_I86LM)
181                 reg.x.dx = FP_OFF(dir);
182                 sreg.ds = FP_SEG(dir);
183 #else
184                 reg.x.dx = (unsigned) dir;
185 #endif
186         } else {                                /* get next entry */
187                 reg.h.ah = DOSI_FINDN;
188 #if     defined(M_I86LM)
189                 reg.x.dx = FP_OFF(dtapnt);
190                 sreg.ds = FP_SEG(dtapnt);
191 #else
192                 reg.x.dx = (unsigned) dtapnt;
193 #endif
194         }
195 #if     defined(M_I86LM)
196         intdosx(&reg, &nreg, &sreg);
197 #else
198         intdos(&reg, &nreg);
199 #endif
200         if (nreg.x.cflag)
201                 return (char *) NULL;
202
203         return dtabuf.d_name;
204 }
205
206 static  void
207 mysetdta()
208 {
209         reg.h.ah = DOSI_SDTA;
210 #if     defined(M_I86LM)
211         reg.x.dx = FP_OFF(dtapnt);
212         sreg.ds = FP_SEG(dtapnt);
213         intdosx(&reg, &nreg, &sreg);
214 #else
215         reg.x.dx = (int) dtapnt;
216         intdos(&reg, &nreg);
217 #endif
218 }