8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / cmd / sendmail / libsm / smstdio.c
blobb99c5efb68dfd758b49d7dd8570d90bfb4e8b685
1 /*
2 * Copyright (c) 2000-2002, 2004 Sendmail, Inc. and its suppliers.
3 * All rights reserved.
5 * By using this file, you agree to the terms and conditions set
6 * forth in the LICENSE file which can be found at the top level of
7 * the sendmail distribution.
8 */
10 #pragma ident "%Z%%M% %I% %E% SMI"
12 #include <sm/gen.h>
13 SM_IDSTR(id, "@(#)$Id: smstdio.c,v 1.34 2004/08/03 20:46:34 ca Exp $")
14 #include <unistd.h>
15 #include <stdio.h>
16 #include <fcntl.h>
17 #include <errno.h>
18 #include <sys/stat.h>
19 #include <sm/assert.h>
20 #include <sm/io.h>
21 #include <sm/string.h>
22 #include "local.h"
24 static void setup __P((SM_FILE_T *));
27 ** Overall:
28 ** This is a file type which implements a layer on top of the system
29 ** stdio. fp->f_cookie is the FILE* of stdio. The cookie may be
30 ** "bound late" because of the manner which Linux implements stdio.
31 ** When binding late (when fp->f_cookie==NULL) then the value of
32 ** fp->f_ival is used (0, 1 or 2) to map to stdio's stdin, stdout or
33 ** stderr.
37 ** SM_STDIOOPEN -- open a file to system stdio implementation
39 ** Parameters:
40 ** fp -- file pointer assign for this open
41 ** info -- info about file to open
42 ** flags -- indicating method of opening
43 ** rpool -- ignored
45 ** Returns:
46 ** Failure: -1
47 ** Success: 0 (zero)
50 /* ARGSUSED3 */
51 int
52 sm_stdioopen(fp, info, flags, rpool)
53 SM_FILE_T *fp;
54 const void *info;
55 int flags;
56 const void *rpool;
58 register FILE *s;
59 char *stdiomode;
61 switch (flags)
63 case SM_IO_RDONLY:
64 stdiomode = "r";
65 break;
66 case SM_IO_WRONLY:
67 stdiomode = "w";
68 break;
69 case SM_IO_APPEND:
70 stdiomode = "a";
71 break;
72 case SM_IO_APPENDRW:
73 stdiomode = "a+";
74 break;
75 #if SM_IO_BINARY != 0
76 case SM_IO_RDONLY_B:
77 stdiomode = "rb";
78 break;
79 case SM_IO_WRONLY_B:
80 stdiomode = "wb";
81 break;
82 case SM_IO_APPEND_B:
83 stdiomode = "ab";
84 break;
85 case SM_IO_APPENDRW_B:
86 stdiomode = "a+b";
87 break;
88 case SM_IO_RDWR_B:
89 stdiomode = "r+b";
90 break;
91 #endif /* SM_IO_BINARY != 0 */
92 case SM_IO_RDWR:
93 default:
94 stdiomode = "r+";
95 break;
98 if ((s = fopen((char *)info, stdiomode)) == NULL)
99 return -1;
100 fp->f_cookie = s;
101 return 0;
105 ** SETUP -- assign file type cookie when not already assigned
107 ** Parameters:
108 ** fp - the file pointer to get the cookie assigned
110 ** Return:
111 ** none.
114 static void
115 setup(fp)
116 SM_FILE_T *fp;
118 if (fp->f_cookie == NULL)
120 switch (fp->f_ival)
122 case 0:
123 fp->f_cookie = stdin;
124 break;
125 case 1:
126 fp->f_cookie = stdout;
127 break;
128 case 2:
129 fp->f_cookie = stderr;
130 break;
131 default:
132 sm_abort("fp->f_ival=%d: out of range (0...2)", fp->f_ival);
133 break;
139 ** SM_STDIOREAD -- read from the file
141 ** Parameters:
142 ** fp -- the file pointer
143 ** buf -- location to place the read data
144 ** n - number of bytes to read
146 ** Returns:
147 ** result from fread().
150 ssize_t
151 sm_stdioread(fp, buf, n)
152 SM_FILE_T *fp;
153 char *buf;
154 size_t n;
156 register FILE *s;
158 if (fp->f_cookie == NULL)
159 setup(fp);
160 s = fp->f_cookie;
161 return fread(buf, 1, n, s);
165 ** SM_STDIOWRITE -- write to the file
167 ** Parameters:
168 ** fp -- the file pointer
169 ** buf -- location of data to write
170 ** n - number of bytes to write
172 ** Returns:
173 ** result from fwrite().
176 ssize_t
177 sm_stdiowrite(fp, buf, n)
178 SM_FILE_T *fp;
179 char const *buf;
180 size_t n;
182 register FILE *s;
184 if (fp->f_cookie == NULL)
185 setup(fp);
186 s = fp->f_cookie;
187 return fwrite(buf, 1, n, s);
191 ** SM_STDIOSEEK -- set position within file
193 ** Parameters:
194 ** fp -- the file pointer
195 ** offset -- new location based on 'whence'
196 ** whence -- indicates "base" for 'offset'
198 ** Returns:
199 ** result from fseek().
202 off_t
203 sm_stdioseek(fp, offset, whence)
204 SM_FILE_T *fp;
205 off_t offset;
206 int whence;
208 register FILE *s;
210 if (fp->f_cookie == NULL)
211 setup(fp);
212 s = fp->f_cookie;
213 return fseek(s, offset, whence);
217 ** SM_STDIOCLOSE -- close the file
219 ** Parameters:
220 ** fp -- close file pointer
222 ** Return:
223 ** status from fclose()
227 sm_stdioclose(fp)
228 SM_FILE_T *fp;
230 register FILE *s;
232 if (fp->f_cookie == NULL)
233 setup(fp);
234 s = fp->f_cookie;
235 return fclose(s);
239 ** SM_STDIOSETINFO -- set info for this open file
241 ** Parameters:
242 ** fp -- the file pointer
243 ** what -- type of information setting
244 ** valp -- memory location of info to set
246 ** Return:
247 ** Failure: -1 and sets errno
248 ** Success: none (currently).
251 /* ARGSUSED2 */
253 sm_stdiosetinfo(fp, what, valp)
254 SM_FILE_T *fp;
255 int what;
256 void *valp;
258 switch (what)
260 case SM_IO_WHAT_MODE:
261 default:
262 errno = EINVAL;
263 return -1;
268 ** SM_STDIOGETINFO -- get info for this open file
270 ** Parameters:
271 ** fp -- the file pointer
272 ** what -- type of information request
273 ** valp -- memory location to place info
275 ** Return:
276 ** Failure: -1 and sets errno
277 ** Success: none (currently).
280 /* ARGSUSED2 */
282 sm_stdiogetinfo(fp, what, valp)
283 SM_FILE_T *fp;
284 int what;
285 void *valp;
287 switch (what)
289 case SM_IO_WHAT_SIZE:
291 int fd;
292 struct stat st;
294 if (fp->f_cookie == NULL)
295 setup(fp);
296 fd = fileno((FILE *) fp->f_cookie);
297 if (fd < 0)
298 return -1;
299 if (fstat(fd, &st) == 0)
300 return st.st_size;
301 else
302 return -1;
305 case SM_IO_WHAT_MODE:
306 default:
307 errno = EINVAL;
308 return -1;
313 ** SM_IO_STDIOOPEN -- create an SM_FILE which interfaces to a stdio FILE
315 ** Parameters:
316 ** stream -- an open stdio stream, as returned by fopen()
317 ** mode -- the mode argument to fopen() which describes stream
319 ** Return:
320 ** On success, return a pointer to an SM_FILE object which
321 ** can be used for reading and writing 'stream'.
322 ** Abort if mode is gibberish or stream is bad.
323 ** Raise an exception if we can't allocate memory.
326 SM_FILE_T *
327 sm_io_stdioopen(stream, mode)
328 FILE *stream;
329 char *mode;
331 int fd;
332 bool r, w;
333 int ioflags;
334 SM_FILE_T *fp;
336 fd = fileno(stream);
337 SM_REQUIRE(fd >= 0);
339 r = w = false;
340 switch (mode[0])
342 case 'r':
343 r = true;
344 break;
345 case 'w':
346 case 'a':
347 w = true;
348 break;
349 default:
350 sm_abort("sm_io_stdioopen: mode '%s' is bad", mode);
352 if (strchr(&mode[1], '+') != NULL)
353 r = w = true;
354 if (r && w)
355 ioflags = SMRW;
356 else if (r)
357 ioflags = SMRD;
358 else
359 ioflags = SMWR;
361 fp = sm_fp(SmFtRealStdio, ioflags, NULL);
362 fp->f_file = fd;
363 fp->f_cookie = stream;
364 return fp;