2 * Unix SMB/CIFS implementation.
3 * SMB parameters and setup
4 * Copyright (C) Andrew Tridgell 1992-1998 Modified by Jeremy Allison 1995.
6 * This program is free software; you can redistribute it and/or modify it under
7 * the terms of the GNU General Public License as published by the Free
8 * Software Foundation; either version 3 of the License, or (at your option)
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * You should have received a copy of the GNU General Public License along with
17 * this program; if not, see <http://www.gnu.org/licenses/>.
23 #define MAP_FAILED ((void *)-1)
26 /****************************************************************************
27 Read a line from a file with possible \ continuation chars.
28 Blanks at the start or end of a line are stripped.
29 The string will be allocated if s2 is NULL.
30 ****************************************************************************/
32 char *fgets_slash(char *s2
,int maxlen
,XFILE
*f
)
37 bool start_of_line
= True
;
48 maxlen
= MIN(maxlen
,8);
49 s
= (char *)SMB_MALLOC(maxlen
);
58 while (len
< maxlen
-1) {
64 while (len
> 0 && s
[len
-1] == ' ') {
67 if (len
> 0 && s
[len
-1] == '\\') {
74 if (len
<= 0 && !s2
) {
83 start_of_line
= False
;
88 if (!s2
&& len
> maxlen
-3) {
90 s
= (char *)SMB_REALLOC(s
,maxlen
);
92 DEBUG(0,("fgets_slash: failed to expand buffer!\n"));
100 /****************************************************************************
101 Load from a pipe into memory.
102 ****************************************************************************/
104 static char *file_pload(char *syscmd
, size_t *size
)
111 fd
= sys_popen(syscmd
);
119 while ((n
= read(fd
, buf
, sizeof(buf
))) > 0) {
120 p
= (char *)SMB_REALLOC(p
, total
+ n
+ 1);
122 DEBUG(0,("file_pload: failed to expand buffer!\n"));
126 memcpy(p
+total
, buf
, n
);
134 /* FIXME: Perhaps ought to check that the command completed
135 * successfully (returned 0); if not the data may be
146 /****************************************************************************
147 Load a file into memory from a fd.
148 Truncate at maxsize. If maxsize == 0 - no limit.
149 ****************************************************************************/
151 char *fd_load(int fd
, size_t *psize
, size_t maxsize
)
153 SMB_STRUCT_STAT sbuf
;
157 if (sys_fstat(fd
, &sbuf
) != 0) {
163 size
= MIN(size
, maxsize
);
166 p
= (char *)SMB_MALLOC(size
+1);
171 if (read(fd
, p
, size
) != size
) {
184 /****************************************************************************
185 Load a file into memory.
186 ****************************************************************************/
188 char *file_load(const char *fname
, size_t *size
, size_t maxsize
)
193 if (!fname
|| !*fname
) {
197 fd
= open(fname
,O_RDONLY
);
202 p
= fd_load(fd
, size
, maxsize
);
207 /*******************************************************************
209 *******************************************************************/
211 bool unmap_file(void* start
, size_t size
)
214 if ( munmap( start
, size
) != 0 ) {
215 DEBUG( 1, ("map_file: Failed to unmap address %p "
217 start
, (unsigned int)size
, strerror(errno
) ));
227 /*******************************************************************
228 mmap (if possible) or read a file.
229 ********************************************************************/
231 void *map_file(char *fname
, size_t size
)
237 fd
= open(fname
, O_RDONLY
, 0);
239 DEBUG(2,("map_file: Failed to load %s - %s\n", fname
, strerror(errno
)));
242 p
= mmap(NULL
, size
, PROT_READ
, MAP_SHARED
|MAP_FILE
, fd
, 0);
244 if (p
== MAP_FAILED
) {
245 DEBUG(1,("map_file: Failed to mmap %s - %s\n", fname
, strerror(errno
)));
250 p
= file_load(fname
, &s2
, 0);
255 DEBUG(1,("map_file: incorrect size for %s - got %lu expected %lu\n",
256 fname
, (unsigned long)s2
, (unsigned long)size
));
264 /****************************************************************************
265 Parse a buffer into lines.
266 ****************************************************************************/
268 static char **file_lines_parse(char *p
, size_t size
, int *numlines
)
277 for (s
= p
, i
=0; s
< p
+size
; s
++) {
278 if (s
[0] == '\n') i
++;
281 ret
= SMB_MALLOC_ARRAY(char *, i
+2);
286 memset(ret
, 0, sizeof(ret
[0])*(i
+2));
289 for (s
= p
, i
=0; s
< p
+size
; s
++) {
300 /* remove any blank lines at the end */
301 while (i
> 0 && ret
[i
-1][0] == 0) {
312 /****************************************************************************
313 Load a file into memory and return an array of pointers to lines in the file
314 must be freed with file_lines_free().
315 ****************************************************************************/
317 char **file_lines_load(const char *fname
, int *numlines
, size_t maxsize
)
322 p
= file_load(fname
, &size
, maxsize
);
327 return file_lines_parse(p
, size
, numlines
);
330 /****************************************************************************
331 Load a fd into memory and return an array of pointers to lines in the file
332 must be freed with file_lines_free(). If convert is true calls unix_to_dos on
334 ****************************************************************************/
336 char **fd_lines_load(int fd
, int *numlines
, size_t maxsize
)
341 p
= fd_load(fd
, &size
, maxsize
);
346 return file_lines_parse(p
, size
, numlines
);
349 /****************************************************************************
350 Load a pipe into memory and return an array of pointers to lines in the data
351 must be freed with file_lines_free().
352 ****************************************************************************/
354 char **file_lines_pload(char *syscmd
, int *numlines
)
359 p
= file_pload(syscmd
, &size
);
364 return file_lines_parse(p
, size
, numlines
);
367 /****************************************************************************
368 Free lines loaded with file_lines_load.
369 ****************************************************************************/
371 void file_lines_free(char **lines
)
380 /****************************************************************************
381 Take a list of lines and modify them to produce a list where \ continues
383 ****************************************************************************/
385 void file_lines_slashcont(char **lines
)
389 for (i
=0; lines
[i
];) {
390 int len
= strlen(lines
[i
]);
391 if (lines
[i
][len
-1] == '\\') {
392 lines
[i
][len
-1] = ' ';
394 char *p
= &lines
[i
][len
];
395 while (p
< lines
[i
+1]) {
398 for (j
= i
+1; lines
[j
]; j
++) {
399 lines
[j
] = lines
[j
+1];
408 /****************************************************************************
409 Save a lump of data into a file. Mostly used for debugging.
410 ****************************************************************************/
412 bool file_save(const char *fname
, void *packet
, size_t length
)
415 fd
= open(fname
, O_WRONLY
|O_CREAT
|O_TRUNC
, 0644);
419 if (write(fd
, packet
, length
) != (size_t)length
) {