2 * Unix SMB/CIFS implementation.
3 * SMB parameters and setup
4 * Copyright (C) Andrew Tridgell 1992-1998 Modified by Jeremy Allison 1995.
6 * Added afdgets() Jelmer Vernooij 2005
8 * This program is free software; you can redistribute it and/or modify it under
9 * the terms of the GNU General Public License as published by the Free
10 * Software Foundation; either version 3 of the License, or (at your option)
13 * This program is distributed in the hope that it will be useful, but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
18 * You should have received a copy of the GNU General Public License along with
19 * this program; if not, see <http://www.gnu.org/licenses/>.
23 #include "system/shmem.h"
24 #include "system/filesys.h"
26 #include "lib/util/samba_util.h"
27 #include "lib/util/util_file.h"
28 #include "lib/util/sys_popen.h"
29 #include "lib/util/sys_rw.h"
30 #include "lib/util/debug.h"
33 * Read one line (data until next newline or eof) and allocate it
35 _PUBLIC_
char *afdgets(int fd
, TALLOC_CTX
*mem_ctx
, size_t hint
)
38 ssize_t alloc_size
= 0, offset
= 0, ret
;
41 if (hint
<= 0) hint
= 0x100;
46 data
= talloc_realloc(mem_ctx
, data
, char, alloc_size
);
51 ret
= read(fd
, data
+ offset
, hint
);
63 for (p
= 0; p
< ret
; p
++) {
64 if (data
[offset
+ p
] == '\n')
69 data
[offset
+ p
] = '\0';
71 /* Go back to position of newline */
72 lseek(fd
, p
- ret
+ 1, SEEK_CUR
);
78 } while ((size_t)ret
== hint
);
85 char *fgets_slash(TALLOC_CTX
*mem_ctx
, char *s2
, size_t maxlen
, FILE *f
)
90 bool start_of_line
= true;
101 maxlen
= MIN(maxlen
,8);
102 s
= talloc_array(mem_ctx
, char, maxlen
);
111 while (len
< maxlen
-1) {
118 while (len
> 0 && s
[len
-1] == ' ') {
121 if (len
> 0 && s
[len
-1] == '\\') {
123 start_of_line
= true;
128 if (len
<= 0 && (s2
== NULL
)) {
131 return (len
>0) ? s
: NULL
;
139 start_of_line
= false;
143 if ((s2
== NULL
) && (len
> maxlen
-3)) {
149 DBG_ERR("length overflow\n");
155 t
= talloc_realloc(mem_ctx
, s
, char, maxlen
);
157 DBG_ERR("failed to expand buffer!\n");
170 load a file into memory from a fd.
172 _PUBLIC_
char *fd_load(int fd
, size_t *psize
, size_t maxsize
, TALLOC_CTX
*mem_ctx
)
184 file
= fdopen_keepfd(fd
, "r");
189 while (size
< maxsize
) {
193 chunk
= MIN(chunk
, (maxsize
- size
));
195 newbufsize
= size
+ (chunk
+1); /* chunk+1 can't overflow */
196 if (newbufsize
< size
) {
197 goto fail
; /* overflow */
200 p
= talloc_realloc(mem_ctx
, p
, char, newbufsize
);
205 nread
= fread(p
+size
, 1, chunk
, file
);
208 if (nread
!= chunk
) {
234 load a file into memory
236 _PUBLIC_
char *file_load(const char *fname
, size_t *size
, size_t maxsize
, TALLOC_CTX
*mem_ctx
)
241 if (!fname
|| !*fname
) return NULL
;
243 fd
= open(fname
,O_RDONLY
);
244 if (fd
== -1) return NULL
;
246 p
= fd_load(fd
, size
, maxsize
, mem_ctx
);
254 parse a buffer into lines
255 'p' will be freed on error, and otherwise will be made a child of the returned array
257 static char **file_lines_parse_internal(char *p
, size_t size
, int *numlines
, TALLOC_CTX
*mem_ctx
)
264 for (s
= p
, i
=0; s
< p
+size
; s
++) {
265 if (s
[0] == '\n') i
++;
268 ret
= talloc_zero_array(mem_ctx
, char *, i
+2);
274 talloc_steal(ret
, p
);
277 for (s
= p
, i
=1; s
< p
+size
; s
++) {
283 if (s
[0] == '\r') s
[0] = 0;
286 /* remove any blank lines at the end */
287 while (i
> 0 && ret
[i
-1][0] == 0) {
291 if (numlines
) *numlines
= i
;
298 load a file into memory and return an array of pointers to lines in the file
299 must be freed with talloc_free().
301 _PUBLIC_
char **file_lines_load(const char *fname
, int *numlines
, size_t maxsize
, TALLOC_CTX
*mem_ctx
)
306 p
= file_load(fname
, &size
, maxsize
, mem_ctx
);
309 return file_lines_parse_internal(p
, size
, numlines
, mem_ctx
);
313 load a fd into memory and return an array of pointers to lines in the file
314 must be freed with talloc_free(). If convert is true calls unix_to_dos on
317 _PUBLIC_
char **fd_lines_load(int fd
, int *numlines
, size_t maxsize
, TALLOC_CTX
*mem_ctx
)
322 p
= fd_load(fd
, &size
, maxsize
, mem_ctx
);
325 return file_lines_parse_internal(p
, size
, numlines
, mem_ctx
);
328 _PUBLIC_
char **file_lines_parse(const char *p_in
,
334 * Copy the incoming string so it can end up
335 * being owned by the returned pointer and
336 * freed when that is.
338 char *p
= talloc_strdup(mem_ctx
, p_in
);
342 return file_lines_parse_internal(p
, size
, numlines
, mem_ctx
);
345 _PUBLIC_
bool file_save_mode(const char *fname
, const void *packet
,
346 size_t length
, mode_t mode
)
350 fd
= open(fname
, O_WRONLY
|O_CREAT
|O_EXCL
, mode
);
354 num_written
= write(fd
, packet
, length
);
355 if (num_written
== -1 || (size_t)num_written
!= length
) {
364 save a lump of data into a file. Mostly used for debugging
366 _PUBLIC_
bool file_save(const char *fname
, const void *packet
, size_t length
)
368 return file_save_mode(fname
, packet
, length
, 0644);
371 _PUBLIC_
int vfdprintf(int fd
, const char *format
, va_list ap
)
378 len
= vasprintf(&p
, format
, ap2
);
380 if (len
<= 0) return len
;
381 ret
= write(fd
, p
, len
);
386 _PUBLIC_
int fdprintf(int fd
, const char *format
, ...)
391 va_start(ap
, format
);
392 ret
= vfdprintf(fd
, format
, ap
);
399 compare two files, return true if the two files have the same content
401 bool file_compare(const char *path1
, const char *path2
)
403 FILE *f1
= NULL
, *f2
= NULL
;
404 uint8_t buf1
[1024], buf2
[1024];
407 f1
= fopen(path1
, "r");
411 f2
= fopen(path2
, "r");
417 size_t n1
= fread(buf1
, 1, sizeof(buf1
), f1
);
418 size_t n2
= fread(buf2
, 1, sizeof(buf2
), f2
);
424 ret
= (feof(f1
) && feof(f2
));
427 if (memcmp(buf1
, buf2
, n1
) != 0) {
430 if (n1
< sizeof(buf1
)) {
431 bool has_error
= (ferror(f1
) || ferror(f2
));
449 Load from a pipe into memory.
451 char *file_ploadv(char * const argl
[], size_t *size
)
458 fd
= sys_popenv(argl
);
465 while ((n
= sys_read(fd
, buf
, sizeof(buf
))) > 0) {
466 p
= talloc_realloc(NULL
, p
, char, total
+ n
+ 1);
468 DBG_ERR("failed to expand buffer!\n");
472 memcpy(p
+total
, buf
, n
);
481 * FIXME: Perhaps ought to check that the command completed
482 * successfully (returned 0); if not the data may be
495 * fopen a dup'ed fd. Prevent fclose to close the fd passed in.
497 * Don't use on fd's that have fcntl locks, on error it will close the
498 * dup'ed fd, thus killing your fcntl locks.
500 FILE *fdopen_keepfd(int fd
, const char *mode
)
510 f
= fdopen(dup_fd
, mode
);