• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
14  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
15  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
16  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
17  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
18  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
19  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
20  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
22  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23  */
24 
25 /*RCSID("OpenBSD: misc.c,v 1.22 2003/09/18 08:49:45 markus Exp ");*/
26 
27 /* For xmalloc, xfree etc:
28  * Author: Tatu Ylonen <ylo@cs.hut.fi>
29  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
30  *                    All rights reserved
31  * Versions of malloc and friends that check their results, and never return
32  * failure (they call fatal if they encounter an error).
33  *
34  * As far as I am concerned, the code I have written for this software
35  * can be used freely for any purpose.  Any derived versions of this
36  * software must be clearly marked as such, and if the derived work is
37  * incompatible with the protocol description in the RFC file, it must be
38  * called by a name other than "ssh" or "Secure Shell".
39  */
40 
41 /*RCSID("OpenBSD: xmalloc.c,v 1.16 2001/07/23 18:21:46 stevesk Exp ");*/
42 
43 #include "includes.h"
44 #include "scpmisc.h"
45 
46 void *
xmalloc(size_t size)47 xmalloc(size_t size)
48 {
49 	void *ptr;
50 
51 	if (size == 0) {
52 		fprintf(stderr, "xmalloc: zero size\n");
53 		exit(EXIT_FAILURE);
54 	}
55 	ptr = malloc(size);
56 	if (ptr == NULL) {
57 		fprintf(stderr, "xmalloc: out of memory (allocating %lu bytes)\n", (u_long) size);
58 		exit(EXIT_FAILURE);
59 	}
60 	return ptr;
61 }
62 
63 void *
xrealloc(void * ptr,size_t new_size)64 xrealloc(void *ptr, size_t new_size)
65 {
66 	void *new_ptr;
67 
68 	if (new_size == 0) {
69 		fprintf(stderr, "xrealloc: zero size\n");
70 		exit(EXIT_FAILURE);
71 	}
72 	if (ptr == NULL)
73 		new_ptr = malloc(new_size);
74 	else
75 		new_ptr = realloc(ptr, new_size);
76 	if (new_ptr == NULL) {
77 		fprintf(stderr, "xrealloc: out of memory (new_size %lu bytes)\n", (u_long) new_size);
78 		exit(EXIT_FAILURE);
79 	}
80 	return new_ptr;
81 }
82 
83 void
xfree(void * ptr)84 xfree(void *ptr)
85 {
86 	if (ptr == NULL) {
87 		fprintf(stderr, "xfree: NULL pointer given as argument\n");
88 		exit(EXIT_FAILURE);
89 	}
90 	free(ptr);
91 }
92 
93 char *
xstrdup(const char * str)94 xstrdup(const char *str)
95 {
96 	size_t len;
97 	char *cp;
98 
99 	len = strlen(str) + 1;
100 	cp = xmalloc(len);
101 	strncpy(cp, str, len);
102 	return cp;
103 }
104 
105 char *
cleanhostname(char * host)106 cleanhostname(char *host)
107 {
108 	if (*host == '[' && host[strlen(host) - 1] == ']') {
109 		host[strlen(host) - 1] = '\0';
110 		return (host + 1);
111 	} else
112 		return host;
113 }
114 
115 char *
colon(char * cp)116 colon(char *cp)
117 {
118 	int flag = 0;
119 
120 	if (*cp == ':')		/* Leading colon is part of file name. */
121 		return (0);
122 	if (*cp == '[')
123 		flag = 1;
124 
125 	for (; *cp; ++cp) {
126 		if (*cp == '@' && *(cp+1) == '[')
127 			flag = 1;
128 		if (*cp == ']' && *(cp+1) == ':' && flag)
129 			return (cp+1);
130 		if (*cp == ':' && !flag)
131 			return (cp);
132 		if (*cp == '/')
133 			return (0);
134 	}
135 	return (0);
136 }
137 
138 /* function to assist building execv() arguments */
139 void
addargs(arglist * args,char * fmt,...)140 addargs(arglist *args, char *fmt, ...)
141 {
142 	va_list ap;
143 	char *cp;
144 	u_int nalloc;
145 	int r;
146 
147 	va_start(ap, fmt);
148 	r = vasprintf(&cp, fmt, ap);
149 	va_end(ap);
150 	if (r == -1)
151 		fatal("addargs: argument too long");
152 
153 	nalloc = args->nalloc;
154 	if (args->list == NULL) {
155 		nalloc = 32;
156 		args->num = 0;
157 	} else if (args->num+2 >= nalloc)
158 		nalloc *= 2;
159 
160 	args->list = xrealloc(args->list, nalloc * sizeof(char *));
161 	args->nalloc = nalloc;
162 	args->list[args->num++] = cp;
163 	args->list[args->num] = NULL;
164 }
165 
166 void
replacearg(arglist * args,u_int which,char * fmt,...)167 replacearg(arglist *args, u_int which, char *fmt, ...)
168 {
169 	va_list ap;
170 	char *cp;
171 	int r;
172 
173 	va_start(ap, fmt);
174 	r = vasprintf(&cp, fmt, ap);
175 	va_end(ap);
176 	if (r == -1)
177 		fatal("replacearg: argument too long");
178 
179 	if (which >= args->num)
180 		fatal("replacearg: tried to replace invalid arg %d >= %d",
181 		    which, args->num);
182 	xfree(args->list[which]);
183 	args->list[which] = cp;
184 }
185 
186 void
freeargs(arglist * args)187 freeargs(arglist *args)
188 {
189 	u_int i;
190 
191 	if (args->list != NULL) {
192 		for (i = 0; i < args->num; i++)
193 			xfree(args->list[i]);
194 		xfree(args->list);
195 		args->nalloc = args->num = 0;
196 		args->list = NULL;
197 	}
198 }
199 
200 /*
201  * NB. duplicate __progname in case it is an alias for argv[0]
202  * Otherwise it may get clobbered by setproctitle()
203  */
ssh_get_progname(char * argv0)204 char *ssh_get_progname(char *argv0)
205 {
206 	char *p;
207 
208 	if (argv0 == NULL)
209 		return ("unknown");	/* XXX */
210 	p = strrchr(argv0, '/');
211 	if (p == NULL)
212 		p = argv0;
213 	else
214 		p++;
215 
216 	return (xstrdup(p));
217 }
218 
fatal(char * fmt,...)219 void fatal(char* fmt,...)
220 {
221 	va_list args;
222 	va_start(args, fmt);
223 	vfprintf(stderr, fmt, args);
224 	va_end(args);
225 	exit(255);
226 }
227 
228 void
sanitise_stdfd(void)229 sanitise_stdfd(void)
230 {
231 	int nullfd, dupfd;
232 
233 	if ((nullfd = dupfd = open(_PATH_DEVNULL, O_RDWR)) == -1) {
234 		fprintf(stderr, "Couldn't open /dev/null: %s", strerror(errno));
235 		exit(1);
236 	}
237 	while (++dupfd <= 2) {
238 		/* Only clobber closed fds */
239 		if (fcntl(dupfd, F_GETFL, 0) >= 0)
240 			continue;
241 		if (dup2(nullfd, dupfd) == -1) {
242 			fprintf(stderr, "dup2: %s", strerror(errno));
243 			exit(1);
244 		}
245 	}
246 	if (nullfd > 2)
247 		close(nullfd);
248 }
249