1 /*
2 Unix SMB/Netbios implementation.
3 Version 1.9.
4 Samba system utilities
5
6 Copyright (C) Andrew Tridgell 1992-1998
7
8 Copyright (C) 2011-2021
9 Free Software Foundation, Inc.
10
11 This file is part of the Midnight Commander.
12
13 The Midnight Commander is free software: you can redistribute it
14 and/or modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation, either version 3 of the License,
16 or (at your option) any later version.
17
18 The Midnight Commander is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program. If not, see <http://www.gnu.org/licenses/>.
25 */
26
27 #include "includes.h"
28
29 extern int DEBUGLEVEL;
30
31 /*
32 The idea is that this file will eventually have wrappers around all
33 important system calls in samba. The aims are:
34
35 - to enable easier porting by putting OS dependent stuff in here
36
37 - to allow for hooks into other "pseudo-filesystems"
38
39 - to allow easier integration of things like the japanese extensions
40
41 - to support the philosophy of Samba to expose the features of
42 the OS within the SMB model. In general whatever file/printer/variable
43 expansions/etc make sense to the OS should be acceptable to Samba.
44 */
45
46
47 /*******************************************************************
48 this replaces the normal select() system call
49 return if some data has arrived on one of the file descriptors
50 return -1 means error
51 ********************************************************************/
52 #ifndef HAVE_SELECT
53 static int
pollfd(int fd)54 pollfd (int fd)
55 {
56 int r = 0;
57
58 #ifdef HAS_RDCHK
59 r = rdchk (fd);
60 #elif defined(TCRDCHK)
61 (void) ioctl (fd, TCRDCHK, &r);
62 #else
63 (void) ioctl (fd, FIONREAD, &r);
64 #endif
65
66 return (r);
67 }
68
69 int
sys_select(int maxfd,fd_set * fds,struct timeval * tval)70 sys_select (int maxfd, fd_set * fds, struct timeval *tval)
71 {
72 fd_set fds2;
73 int counter = 0;
74 int found = 0;
75
76 FD_ZERO (&fds2);
77
78 while (1)
79 {
80 int i;
81 for (i = 0; i < maxfd; i++)
82 {
83 if (FD_ISSET (i, fds) && pollfd (i) > 0)
84 {
85 found++;
86 FD_SET (i, &fds2);
87 }
88 }
89
90 if (found)
91 {
92 memcpy ((void *) fds, (void *) &fds2, sizeof (fds2));
93 return (found);
94 }
95
96 if (tval && tval->tv_sec < counter)
97 return (0);
98 sleep (1);
99 counter++;
100 }
101 }
102
103 #else /* !NO_SELECT */
104 int
sys_select(int maxfd,fd_set * fds,struct timeval * tval)105 sys_select (int maxfd, fd_set * fds, struct timeval *tval)
106 {
107 #ifdef USE_POLL
108 struct pollfd pfd[256];
109 int i;
110 int maxpoll;
111 int timeout;
112 int pollrtn;
113
114 maxpoll = 0;
115 for (i = 0; i < maxfd; i++)
116 {
117 if (FD_ISSET (i, fds))
118 {
119 struct pollfd *pfdp = &pfd[maxpoll++];
120 pfdp->fd = i;
121 pfdp->events = POLLIN;
122 pfdp->revents = 0;
123 }
124 }
125
126 timeout = (tval != NULL) ? (tval->tv_sec * 1000) + (tval->tv_usec / 1000) : -1;
127 errno = 0;
128 do
129 {
130 pollrtn = poll (&pfd[0], maxpoll, timeout);
131 }
132 while (pollrtn < 0 && errno == EINTR);
133
134 FD_ZERO (fds);
135
136 for (i = 0; i < maxpoll; i++)
137 if (pfd[i].revents & POLLIN)
138 FD_SET (pfd[i].fd, fds);
139
140 return pollrtn;
141 #else /* USE_POLL */
142
143 struct timeval t2;
144 int selrtn;
145
146 do
147 {
148 if (tval)
149 memcpy ((void *) &t2, (void *) tval, sizeof (t2));
150 errno = 0;
151 selrtn = select (maxfd, SELECT_CAST fds, NULL, NULL, tval ? &t2 : NULL);
152 }
153 while (selrtn < 0 && errno == EINTR);
154
155 return (selrtn);
156 #endif /* USE_POLL */
157 }
158 #endif /* NO_SELECT */
159
160 /*******************************************************************
161 A stat() wrapper that will deal with 64 bit filesizes.
162 ********************************************************************/
163
164 int
sys_stat(const char * fname,SMB_STRUCT_STAT * sbuf)165 sys_stat (const char *fname, SMB_STRUCT_STAT * sbuf)
166 {
167 return stat (fname, sbuf);
168 }
169
170 /*******************************************************************
171 An lstat() wrapper that will deal with 64 bit filesizes.
172 ********************************************************************/
173 #if 0
174 int
175 sys_lstat (const char *fname, SMB_STRUCT_STAT * sbuf)
176 {
177 return lstat (fname, sbuf);
178 }
179
180 /*******************************************************************
181 An fseek() wrapper that will deal with 64 bit filesizes.
182 ********************************************************************/
183
184 int
185 sys_fseek (FILE * fp, SMB_OFF_T offset, int whence)
186 {
187 return fseek (fp, offset, whence);
188 }
189
190 /*******************************************************************
191 An ftell() wrapper that will deal with 64 bit filesizes.
192 ********************************************************************/
193
194 SMB_OFF_T
195 sys_ftell (FILE * fp)
196 {
197 return (SMB_OFF_T) ftell (fp);
198 }
199
200 /*******************************************************************
201 An open() wrapper that will deal with 64 bit filesizes.
202 ********************************************************************/
203
204 int
205 sys_open (const char *path, int oflag, mode_t mode)
206 {
207 return open (path, oflag, mode);
208 }
209
210 /*******************************************************************
211 An fopen() wrapper that will deal with 64 bit filesizes.
212 ********************************************************************/
213 #endif /* 0 */
214
215 FILE *
sys_fopen(const char * path,const char * type)216 sys_fopen (const char *path, const char *type)
217 {
218 return fopen (path, type);
219 }
220
221 #if 0
222 /*******************************************************************
223 A readdir wrapper that will deal with 64 bit filesizes.
224 ********************************************************************/
225
226 SMB_STRUCT_DIRENT *
227 sys_readdir (DIR * dirp)
228 {
229 return readdir (dirp);
230 }
231
232 /*******************************************************************
233 system wrapper for getwd
234 ********************************************************************/
235 char *
236 sys_getwd (char *s)
237 {
238 char *wd;
239 #ifdef HAVE_GETCWD
240 wd = (char *) getcwd (s, sizeof (pstring));
241 #else
242 wd = (char *) getwd (s);
243 #endif
244 return wd;
245 }
246
247 /*******************************************************************
248 chown isn't used much but OS/2 doesn't have it
249 ********************************************************************/
250
251 int
252 sys_chown (const char *fname, uid_t uid, gid_t gid)
253 {
254 #ifndef HAVE_CHOWN
255 static int done;
256 if (!done)
257 {
258 DEBUG (1, ("WARNING: no chown!\n"));
259 done = 1;
260 }
261 #else
262 return (chown (fname, uid, gid));
263 #endif
264 }
265 #endif /* 0 */
266 /**************************************************************************
267 A wrapper for gethostbyname() that tries avoids looking up hostnames
268 in the root domain, which can cause dial-on-demand links to come up for no
269 apparent reason.
270 ****************************************************************************/
271 struct hostent *
sys_gethostbyname(const char * name)272 sys_gethostbyname (const char *name)
273 {
274 #ifdef REDUCE_ROOT_DNS_LOOKUPS
275 char query[256], hostname[256];
276 char *domain;
277
278 /* Does this name have any dots in it? If so, make no change */
279
280 if (strchr (name, '.'))
281 return (gethostbyname (name));
282
283 /* Get my hostname, which should have domain name
284 attached. If not, just do the gethostname on the
285 original string.
286 */
287
288 gethostname (hostname, sizeof (hostname) - 1);
289 hostname[sizeof (hostname) - 1] = 0;
290 if ((domain = strchr (hostname, '.')) == NULL)
291 return (gethostbyname (name));
292
293 /* Attach domain name to query and do modified query.
294 If names too large, just do gethostname on the
295 original string.
296 */
297
298 if ((strlen (name) + strlen (domain)) >= sizeof (query))
299 return (gethostbyname (name));
300
301 slprintf (query, sizeof (query) - 1, "%s%s", name, domain);
302 return (gethostbyname (query));
303 #else /* REDUCE_ROOT_DNS_LOOKUPS */
304 return (gethostbyname (name));
305 #endif /* REDUCE_ROOT_DNS_LOOKUPS */
306 }
307