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/sys_popen.h"
28 #include "lib/util/sys_rw.h"
29 #include "lib/util/debug.h"
32 * Read one line (data until next newline or eof) and allocate it
34 _PUBLIC_
char *afdgets(int fd
, TALLOC_CTX
*mem_ctx
, size_t hint
)
37 ssize_t alloc_size
= 0, offset
= 0, ret
;
40 if (hint
<= 0) hint
= 0x100;
45 data
= talloc_realloc(mem_ctx
, data
, char, alloc_size
);
50 ret
= read(fd
, data
+ offset
, hint
);
62 for (p
= 0; p
< ret
; p
++) {
63 if (data
[offset
+ p
] == '\n')
68 data
[offset
+ p
] = '\0';
70 /* Go back to position of newline */
71 lseek(fd
, p
- ret
+ 1, SEEK_CUR
);
77 } while (ret
== hint
);
84 char *fgets_slash(TALLOC_CTX
*mem_ctx
, char *s2
, size_t maxlen
, FILE *f
)
89 bool start_of_line
= true;
100 maxlen
= MIN(maxlen
,8);
101 s
= talloc_array(mem_ctx
, char, maxlen
);
110 while (len
< maxlen
-1) {
117 while (len
> 0 && s
[len
-1] == ' ') {
120 if (len
> 0 && s
[len
-1] == '\\') {
122 start_of_line
= true;
127 if (len
<= 0 && (s2
== NULL
)) {
130 return (len
>0) ? s
: NULL
;
138 start_of_line
= false;
142 if ((s2
== NULL
) && (len
> maxlen
-3)) {
148 DBG_ERR("length overflow");
154 t
= talloc_realloc(mem_ctx
, s
, char, maxlen
);
156 DBG_ERR("failed to expand buffer!\n");
169 load a file into memory from a fd.
171 _PUBLIC_
char *fd_load(int fd
, size_t *psize
, size_t maxsize
, TALLOC_CTX
*mem_ctx
)
177 if (fstat(fd
, &sbuf
) != 0) return NULL
;
182 size
= MIN(size
, maxsize
);
185 p
= (char *)talloc_size(mem_ctx
, size
+1);
188 if (read(fd
, p
, size
) != size
) {
194 if (psize
) *psize
= size
;
200 load a file into memory
202 _PUBLIC_
char *file_load(const char *fname
, size_t *size
, size_t maxsize
, TALLOC_CTX
*mem_ctx
)
207 if (!fname
|| !*fname
) return NULL
;
209 fd
= open(fname
,O_RDONLY
);
210 if (fd
== -1) return NULL
;
212 p
= fd_load(fd
, size
, maxsize
, mem_ctx
);
220 parse a buffer into lines
221 'p' will be freed on error, and otherwise will be made a child of the returned array
223 char **file_lines_parse(char *p
, size_t size
, int *numlines
, TALLOC_CTX
*mem_ctx
)
230 for (s
= p
, i
=0; s
< p
+size
; s
++) {
231 if (s
[0] == '\n') i
++;
234 ret
= talloc_zero_array(mem_ctx
, char *, i
+2);
240 talloc_steal(ret
, p
);
243 for (s
= p
, i
=1; s
< p
+size
; s
++) {
249 if (s
[0] == '\r') s
[0] = 0;
252 /* remove any blank lines at the end */
253 while (i
> 0 && ret
[i
-1][0] == 0) {
257 if (numlines
) *numlines
= i
;
264 load a file into memory and return an array of pointers to lines in the file
265 must be freed with talloc_free().
267 _PUBLIC_
char **file_lines_load(const char *fname
, int *numlines
, size_t maxsize
, TALLOC_CTX
*mem_ctx
)
272 p
= file_load(fname
, &size
, maxsize
, mem_ctx
);
275 return file_lines_parse(p
, size
, numlines
, mem_ctx
);
279 load a fd into memory and return an array of pointers to lines in the file
280 must be freed with talloc_free(). If convert is true calls unix_to_dos on
283 _PUBLIC_
char **fd_lines_load(int fd
, int *numlines
, size_t maxsize
, TALLOC_CTX
*mem_ctx
)
288 p
= fd_load(fd
, &size
, maxsize
, mem_ctx
);
291 return file_lines_parse(p
, size
, numlines
, mem_ctx
);
294 _PUBLIC_
bool file_save_mode(const char *fname
, const void *packet
,
295 size_t length
, mode_t mode
)
298 fd
= open(fname
, O_WRONLY
|O_CREAT
|O_TRUNC
, mode
);
302 if (write(fd
, packet
, length
) != (size_t)length
) {
311 save a lump of data into a file. Mostly used for debugging
313 _PUBLIC_
bool file_save(const char *fname
, const void *packet
, size_t length
)
315 return file_save_mode(fname
, packet
, length
, 0644);
318 _PUBLIC_
int vfdprintf(int fd
, const char *format
, va_list ap
)
325 len
= vasprintf(&p
, format
, ap2
);
327 if (len
<= 0) return len
;
328 ret
= write(fd
, p
, len
);
333 _PUBLIC_
int fdprintf(int fd
, const char *format
, ...)
338 va_start(ap
, format
);
339 ret
= vfdprintf(fd
, format
, ap
);
346 compare two files, return true if the two files have the same content
348 bool file_compare(const char *path1
, const char *path2
)
352 TALLOC_CTX
*mem_ctx
= talloc_new(NULL
);
354 p1
= file_load(path1
, &size1
, 0, mem_ctx
);
355 p2
= file_load(path2
, &size2
, 0, mem_ctx
);
356 if (!p1
|| !p2
|| size1
!= size2
) {
357 talloc_free(mem_ctx
);
360 if (memcmp(p1
, p2
, size1
) != 0) {
361 talloc_free(mem_ctx
);
364 talloc_free(mem_ctx
);
370 Load from a pipe into memory.
372 char *file_pload(const char *syscmd
, size_t *size
)
379 fd
= sys_popen(syscmd
);
387 while ((n
= sys_read(fd
, buf
, sizeof(buf
))) > 0) {
388 p
= talloc_realloc(NULL
, p
, char, total
+ n
+ 1);
390 DEBUG(0,("file_pload: failed to expand buffer!\n"));
394 memcpy(p
+total
, buf
, n
);
402 /* FIXME: Perhaps ought to check that the command completed
403 * successfully (returned 0); if not the data may be