Add GNU LGPL headers to all .c .C and .h files
[oweals/cde.git] / cde / programs / dtksh / ksh93 / src / lib / libast / dir / getdents.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these librararies and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /* $XConsortium: getdents.c /main/3 1995/11/01 17:22:56 rswiston $ */
24 /***************************************************************
25 *                                                              *
26 *                      AT&T - PROPRIETARY                      *
27 *                                                              *
28 *         THIS IS PROPRIETARY SOURCE CODE LICENSED BY          *
29 *                          AT&T CORP.                          *
30 *                                                              *
31 *                Copyright (c) 1995 AT&T Corp.                 *
32 *                     All Rights Reserved                      *
33 *                                                              *
34 *           This software is licensed by AT&T Corp.            *
35 *       under the terms and conditions of the license in       *
36 *       http://www.research.att.com/orgs/ssr/book/reuse        *
37 *                                                              *
38 *               This software was created by the               *
39 *           Software Engineering Research Department           *
40 *                    AT&T Bell Laboratories                    *
41 *                                                              *
42 *               For further information contact                *
43 *                     gsf@research.att.com                     *
44 *                                                              *
45 ***************************************************************/
46
47 /* : : generated by proto : : */
48
49 #if !defined(__PROTO__)
50 #if defined(__STDC__) || defined(__cplusplus) || defined(_proto) || defined(c_plusplus)
51 #if defined(__cplusplus)
52 #define __MANGLE__      "C"
53 #else
54 #define __MANGLE__
55 #endif
56 #define __STDARG__
57 #define __PROTO__(x)    x
58 #define __OTORP__(x)
59 #define __PARAM__(n,o)  n
60 #if !defined(__STDC__) && !defined(__cplusplus)
61 #if !defined(c_plusplus)
62 #define const
63 #endif
64 #define signed
65 #define void            int
66 #define volatile
67 #define __V_            char
68 #else
69 #define __V_            void
70 #endif
71 #else
72 #define __PROTO__(x)    ()
73 #define __OTORP__(x)    x
74 #define __PARAM__(n,o)  o
75 #define __MANGLE__
76 #define __V_            char
77 #define const
78 #define signed
79 #define void            int
80 #define volatile
81 #endif
82 #if defined(__cplusplus) || defined(c_plusplus)
83 #define __VARARG__      ...
84 #else
85 #define __VARARG__
86 #endif
87 #if defined(__STDARG__)
88 #define __VA_START__(p,a)       va_start(p,a)
89 #else
90 #define __VA_START__(p,a)       va_start(p)
91 #endif
92 #endif
93 #include "dirlib.h"
94
95 #if _dir_ok || _lib_getdents
96
97 NoN(getdents)
98
99 #else
100
101 /*
102  * getdents
103  *
104  * read directory entries into directory block
105  *
106  * NOTE: directory entries must fit within DIRBLKSIZ boundaries
107  */
108
109 #ifndef MAXNAMLEN
110 #define MAXNAMLEN       255
111 #endif
112
113 #if _lib_dirread
114 extern __MANGLE__ int           dirread __PROTO__((int, char*, int));
115 #endif
116 #if _lib_getdirentries
117 extern __MANGLE__ int           getdirentries __PROTO__((int, char*, int, long*));
118 #endif
119
120 ssize_t
121 getdents __PARAM__((int fd, __V_* buf, size_t siz), (fd, buf, siz)) __OTORP__(int fd; __V_* buf; size_t siz;){
122         struct stat             st;
123
124         if (siz < DIRBLKSIZ)
125         {
126                 errno = EINVAL;
127                 return(-1);
128         }
129         if (fstat(fd, &st)) return(-1);
130         if (!S_ISDIR(st.st_mode))
131         {
132 #ifdef ENOTDIR
133                 errno = ENOTDIR;
134 #else
135                 errno = EBADF;
136 #endif
137                 return(-1);
138         }
139 #if _lib_getdirentries
140         {
141                 long            off;
142                 return(getdirentries(fd, buf, siz, &off));
143         }
144 #else
145 #if _lib_dirread
146         {
147                 register char*          sp;     /* system */
148                 register struct dirent* up;     /* user */
149                 char*                   u;
150                 int                     n;
151                 int                     m;
152                 int                     i;
153
154                 m = (siz * 6) / 10;
155                 m = roundof(m, 8);
156                 sp = (char*)buf + siz - m - 1;
157                 if (!(n = dirread(fd, sp, m))) return(0);
158                 if (n > 0)
159                 {
160                         up = (struct dirent*)buf;
161                         sp[n] = 0;
162                         while (sp < (char*)buf + siz - m + n)
163                         {
164                                 i = 0;
165                                 while (*sp >= '0' && *sp <= '9')
166                                         i = 10 * i + *sp++ - '0';
167                                 while (*sp && *sp != '\t') sp++;
168                                 if (*sp++)
169                                 {
170                                         up->d_fileno = i;
171                                         u = up->d_name;
172                                         while ((*u = *sp++) && u < up->d_name + MAXNAMLEN) u++;
173                                         *u = 0;
174                                         up->d_reclen = sizeof(struct dirent) - sizeof(up->d_name) + (up->d_namlen = u - up->d_name) + 1;
175                                         up->d_reclen = roundof(up->d_reclen, 8);
176                                         up = (struct dirent*)((char*)up + up->d_reclen);
177                                 }
178                         }
179                         return((char*)up - (char*)buf);
180                 }
181         }
182 #else
183 #if _mem_d_reclen_direct
184         return(read(fd, buf, siz));
185 #else
186         {
187
188 #define MAXREC  roundof(sizeof(*up)-sizeof(up->d_name)+sizeof(sp->d_name)+1,8)
189
190                 register struct direct* sp;     /* system */
191                 register struct dirent* up;     /* user */
192                 register char*          s;
193                 register char*          u;
194                 int                     n;
195                 int                     m;
196                 char                    tmp[sizeof(sp->d_name) + 1];
197
198                 /*
199                  * we assume sizeof(struct dirent) > sizeof(struct direct)
200                  */
201
202                 up = (struct dirent*)buf;
203                 n = (siz / MAXREC) * sizeof(struct direct);
204                 if ((!(m = n & ~511) || m < MAXREC) && (!(m = n & ~255) || m < MAXREC)) m = n;
205                 do
206                 {
207                         if ((n = read(fd, (char*)buf + siz - m, m)) <= 0) break;
208                         sp = (struct direct*)((char*)buf + siz - m);
209                         while (sp < (struct direct*)((char*)buf + siz - m + n))
210                         {
211                                 if (sp->d_ino)
212                                 {
213                                         up->d_fileno = sp->d_ino;
214                                         s = sp->d_name;
215                                         u = tmp;
216                                         while (s < sp->d_name + sizeof(sp->d_name) && *s)
217                                                 *u++ = *s++;
218                                         *u = 0;
219                                         strcpy(up->d_name, tmp);
220                                         up->d_reclen = sizeof(struct dirent) - sizeof(up->d_name) + (up->d_namlen = u - tmp) + 1;
221                                         up->d_reclen = roundof(up->d_reclen, 8);
222                                         up = (struct dirent*)((char*)up + up->d_reclen);
223                                 }
224                                 sp++;
225                         }
226                 } while (up == (struct dirent*)buf);
227                 return((char*)up - (char*)buf);
228         }
229 #endif
230 #endif
231 #endif
232 }
233
234 #endif