• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/router/samba-3.0.25b/source/lib/
1/*
2 * Unix SMB/CIFS implementation.
3 * SMB parameters and setup
4 * Copyright (C) Andrew Tridgell 1992-1998 Modified by Jeremy Allison 1995.
5 *
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 2 of the License, or (at your option)
9 * any later version.
10 *
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
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * this program; if not, write to the Free Software Foundation, Inc., 675
18 * Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21#include "includes.h"
22
23#ifndef MAP_FAILED
24#define MAP_FAILED ((void *)-1)
25#endif
26
27/****************************************************************************
28 Read a line from a file with possible \ continuation chars.
29 Blanks at the start or end of a line are stripped.
30 The string will be allocated if s2 is NULL.
31****************************************************************************/
32
33char *fgets_slash(char *s2,int maxlen,XFILE *f)
34{
35	char *s=s2;
36	int len = 0;
37	int c;
38	BOOL start_of_line = True;
39
40	if (x_feof(f)) {
41		return(NULL);
42	}
43
44	if (maxlen <2) {
45		return(NULL);
46	}
47
48	if (!s2) {
49		maxlen = MIN(maxlen,8);
50		s = (char *)SMB_MALLOC(maxlen);
51	}
52
53	if (!s) {
54		return(NULL);
55	}
56
57	*s = 0;
58
59	while (len < maxlen-1) {
60		c = x_getc(f);
61		switch (c) {
62			case '\r':
63				break;
64			case '\n':
65				while (len > 0 && s[len-1] == ' ') {
66					s[--len] = 0;
67				}
68				if (len > 0 && s[len-1] == '\\') {
69					s[--len] = 0;
70					start_of_line = True;
71					break;
72				}
73				return(s);
74			case EOF:
75				if (len <= 0 && !s2)  {
76					SAFE_FREE(s);
77				}
78				return(len>0?s:NULL);
79			case ' ':
80				if (start_of_line) {
81					break;
82				}
83			default:
84				start_of_line = False;
85				s[len++] = c;
86				s[len] = 0;
87		}
88
89		if (!s2 && len > maxlen-3) {
90			maxlen *= 2;
91			s = (char *)SMB_REALLOC(s,maxlen);
92			if (!s) {
93				DEBUG(0,("fgets_slash: failed to expand buffer!\n"));
94				return(NULL);
95			}
96		}
97	}
98	return(s);
99}
100
101/****************************************************************************
102 Load from a pipe into memory.
103****************************************************************************/
104
105char *file_pload(char *syscmd, size_t *size)
106{
107	int fd, n;
108	char *p;
109	pstring buf;
110	size_t total;
111
112	fd = sys_popen(syscmd);
113	if (fd == -1) {
114		return NULL;
115	}
116
117	p = NULL;
118	total = 0;
119
120	while ((n = read(fd, buf, sizeof(buf))) > 0) {
121		p = (char *)SMB_REALLOC(p, total + n + 1);
122		if (!p) {
123		        DEBUG(0,("file_pload: failed to expand buffer!\n"));
124			close(fd);
125			return NULL;
126		}
127		memcpy(p+total, buf, n);
128		total += n;
129	}
130
131	if (p) {
132		p[total] = 0;
133	}
134
135	/* FIXME: Perhaps ought to check that the command completed
136	 * successfully (returned 0); if not the data may be
137	 * truncated. */
138	sys_pclose(fd);
139
140	if (size) {
141		*size = total;
142	}
143
144	return p;
145}
146
147/****************************************************************************
148 Load a file into memory from a fd.
149 Truncate at maxsize. If maxsize == 0 - no limit.
150****************************************************************************/
151
152char *fd_load(int fd, size_t *psize, size_t maxsize)
153{
154	SMB_STRUCT_STAT sbuf;
155	size_t size;
156	char *p;
157
158	if (sys_fstat(fd, &sbuf) != 0) {
159		return NULL;
160	}
161
162	size = sbuf.st_size;
163	if (maxsize) {
164		size = MIN(size, maxsize);
165	}
166
167	p = (char *)SMB_MALLOC(size+1);
168	if (!p) {
169		return NULL;
170	}
171
172	if (read(fd, p, size) != size) {
173		SAFE_FREE(p);
174		return NULL;
175	}
176	p[size] = 0;
177
178	if (psize) {
179		*psize = size;
180	}
181
182	return p;
183}
184
185/****************************************************************************
186 Load a file into memory.
187****************************************************************************/
188
189char *file_load(const char *fname, size_t *size, size_t maxsize)
190{
191	int fd;
192	char *p;
193
194	if (!fname || !*fname) {
195		return NULL;
196	}
197
198	fd = open(fname,O_RDONLY);
199	if (fd == -1) {
200		return NULL;
201	}
202
203	p = fd_load(fd, size, maxsize);
204	close(fd);
205	return p;
206}
207
208/*******************************************************************
209 unmap or free memory
210*******************************************************************/
211
212BOOL unmap_file(void* start, size_t size)
213{
214#ifdef HAVE_MMAP
215	if ( munmap( start, size ) != 0 ) {
216		DEBUG( 1, ("map_file: Failed to unmap address %p "
217			"of size %u - %s\n",
218			start, (unsigned int)size, strerror(errno) ));
219		return False;
220	}
221	return True;
222#else
223	SAFE_FREE( start );
224	return True;
225#endif
226}
227
228/*******************************************************************
229 mmap (if possible) or read a file.
230********************************************************************/
231
232void *map_file(char *fname, size_t size)
233{
234	size_t s2 = 0;
235	void *p = NULL;
236#ifdef HAVE_MMAP
237	int fd;
238	fd = open(fname, O_RDONLY, 0);
239	if (fd == -1) {
240		DEBUG(2,("map_file: Failed to load %s - %s\n", fname, strerror(errno)));
241		return NULL;
242	}
243	p = mmap(NULL, size, PROT_READ, MAP_SHARED|MAP_FILE, fd, 0);
244	close(fd);
245	if (p == MAP_FAILED) {
246		DEBUG(1,("map_file: Failed to mmap %s - %s\n", fname, strerror(errno)));
247		return NULL;
248	}
249#endif
250	if (!p) {
251		p = file_load(fname, &s2, 0);
252		if (!p) {
253			return NULL;
254		}
255		if (s2 != size) {
256			DEBUG(1,("map_file: incorrect size for %s - got %lu expected %lu\n",
257				 fname, (unsigned long)s2, (unsigned long)size));
258			SAFE_FREE(p);
259			return NULL;
260		}
261	}
262	return p;
263}
264
265/****************************************************************************
266 Parse a buffer into lines.
267****************************************************************************/
268
269static char **file_lines_parse(char *p, size_t size, int *numlines)
270{
271	int i;
272	char *s, **ret;
273
274	if (!p) {
275		return NULL;
276	}
277
278	for (s = p, i=0; s < p+size; s++) {
279		if (s[0] == '\n') i++;
280	}
281
282	ret = SMB_MALLOC_ARRAY(char *, i+2);
283	if (!ret) {
284		SAFE_FREE(p);
285		return NULL;
286	}
287	memset(ret, 0, sizeof(ret[0])*(i+2));
288
289	ret[0] = p;
290	for (s = p, i=0; s < p+size; s++) {
291		if (s[0] == '\n') {
292			s[0] = 0;
293			i++;
294			ret[i] = s+1;
295		}
296		if (s[0] == '\r') {
297			s[0] = 0;
298		}
299	}
300
301	/* remove any blank lines at the end */
302	while (i > 0 && ret[i-1][0] == 0) {
303		i--;
304	}
305
306	if (numlines) {
307		*numlines = i;
308	}
309
310	return ret;
311}
312
313/****************************************************************************
314 Load a file into memory and return an array of pointers to lines in the file
315 must be freed with file_lines_free().
316****************************************************************************/
317
318char **file_lines_load(const char *fname, int *numlines, size_t maxsize)
319{
320	char *p;
321	size_t size = 0;
322
323	p = file_load(fname, &size, maxsize);
324	if (!p) {
325		return NULL;
326	}
327
328	return file_lines_parse(p, size, numlines);
329}
330
331/****************************************************************************
332 Load a fd into memory and return an array of pointers to lines in the file
333 must be freed with file_lines_free(). If convert is true calls unix_to_dos on
334 the list.
335****************************************************************************/
336
337char **fd_lines_load(int fd, int *numlines, size_t maxsize)
338{
339	char *p;
340	size_t size;
341
342	p = fd_load(fd, &size, maxsize);
343	if (!p) {
344		return NULL;
345	}
346
347	return file_lines_parse(p, size, numlines);
348}
349
350/****************************************************************************
351 Load a pipe into memory and return an array of pointers to lines in the data
352 must be freed with file_lines_free().
353****************************************************************************/
354
355char **file_lines_pload(char *syscmd, int *numlines)
356{
357	char *p;
358	size_t size;
359
360	p = file_pload(syscmd, &size);
361	if (!p) {
362		return NULL;
363	}
364
365	return file_lines_parse(p, size, numlines);
366}
367
368/****************************************************************************
369 Free lines loaded with file_lines_load.
370****************************************************************************/
371
372void file_lines_free(char **lines)
373{
374	if (!lines) {
375		return;
376	}
377	SAFE_FREE(lines[0]);
378	SAFE_FREE(lines);
379}
380
381/****************************************************************************
382 Take a list of lines and modify them to produce a list where \ continues
383 a line.
384****************************************************************************/
385
386void file_lines_slashcont(char **lines)
387{
388	int i, j;
389
390	for (i=0; lines[i];) {
391		int len = strlen(lines[i]);
392		if (lines[i][len-1] == '\\') {
393			lines[i][len-1] = ' ';
394			if (lines[i+1]) {
395				char *p = &lines[i][len];
396				while (p < lines[i+1]) {
397					*p++ = ' ';
398				}
399				for (j = i+1; lines[j]; j++) {
400					lines[j] = lines[j+1];
401				}
402			}
403		} else {
404			i++;
405		}
406	}
407}
408
409/****************************************************************************
410 Save a lump of data into a file. Mostly used for debugging.
411****************************************************************************/
412
413BOOL file_save(const char *fname, void *packet, size_t length)
414{
415	int fd;
416	fd = open(fname, O_WRONLY|O_CREAT|O_TRUNC, 0644);
417	if (fd == -1) {
418		return False;
419	}
420	if (write(fd, packet, length) != (size_t)length) {
421		return False;
422	}
423	close(fd);
424	return True;
425}
426