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