source: trunk/third/openssh/misc.c @ 18759

Revision 18759, 7.2 KB checked in by zacheiss, 22 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r18758, which included commits to RCS files with non-trunk default branches.
Line 
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#include "includes.h"
26RCSID("$OpenBSD: misc.c,v 1.19 2002/03/04 17:27:39 stevesk Exp $");
27
28#include "misc.h"
29#include "log.h"
30#include "xmalloc.h"
31
32/* remove newline at end of string */
33char *
34chop(char *s)
35{
36        char *t = s;
37        while (*t) {
38                if (*t == '\n' || *t == '\r') {
39                        *t = '\0';
40                        return s;
41                }
42                t++;
43        }
44        return s;
45
46}
47
48/* set/unset filedescriptor to non-blocking */
49void
50set_nonblock(int fd)
51{
52        int val;
53
54        val = fcntl(fd, F_GETFL, 0);
55        if (val < 0) {
56                error("fcntl(%d, F_GETFL, 0): %s", fd, strerror(errno));
57                return;
58        }
59        if (val & O_NONBLOCK) {
60                debug2("fd %d is O_NONBLOCK", fd);
61                return;
62        }
63        debug("fd %d setting O_NONBLOCK", fd);
64        val |= O_NONBLOCK;
65        if (fcntl(fd, F_SETFL, val) == -1)
66                debug("fcntl(%d, F_SETFL, O_NONBLOCK): %s",
67                    fd, strerror(errno));
68}
69
70void
71unset_nonblock(int fd)
72{
73        int val;
74
75        val = fcntl(fd, F_GETFL, 0);
76        if (val < 0) {
77                error("fcntl(%d, F_GETFL, 0): %s", fd, strerror(errno));
78                return;
79        }
80        if (!(val & O_NONBLOCK)) {
81                debug2("fd %d is not O_NONBLOCK", fd);
82                return;
83        }
84        debug("fd %d clearing O_NONBLOCK", fd);
85        val &= ~O_NONBLOCK;
86        if (fcntl(fd, F_SETFL, val) == -1)
87                debug("fcntl(%d, F_SETFL, O_NONBLOCK): %s",
88                    fd, strerror(errno));
89}
90
91/* disable nagle on socket */
92void
93set_nodelay(int fd)
94{
95        int opt;
96        socklen_t optlen;
97
98        optlen = sizeof opt;
99        if (getsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &opt, &optlen) == -1) {
100                error("getsockopt TCP_NODELAY: %.100s", strerror(errno));
101                return;
102        }
103        if (opt == 1) {
104                debug2("fd %d is TCP_NODELAY", fd);
105                return;
106        }
107        opt = 1;
108        debug("fd %d setting TCP_NODELAY", fd);
109        if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof opt) == -1)
110                error("setsockopt TCP_NODELAY: %.100s", strerror(errno));
111}
112
113/* Characters considered whitespace in strsep calls. */
114#define WHITESPACE " \t\r\n"
115
116/* return next token in configuration line */
117char *
118strdelim(char **s)
119{
120        char *old;
121        int wspace = 0;
122
123        if (*s == NULL)
124                return NULL;
125
126        old = *s;
127
128        *s = strpbrk(*s, WHITESPACE "=");
129        if (*s == NULL)
130                return (old);
131
132        /* Allow only one '=' to be skipped */
133        if (*s[0] == '=')
134                wspace = 1;
135        *s[0] = '\0';
136
137        *s += strspn(*s + 1, WHITESPACE) + 1;
138        if (*s[0] == '=' && !wspace)
139                *s += strspn(*s + 1, WHITESPACE) + 1;
140
141        return (old);
142}
143
144struct passwd *
145pwcopy(struct passwd *pw)
146{
147        struct passwd *copy = xmalloc(sizeof(*copy));
148
149        memset(copy, 0, sizeof(*copy));
150        copy->pw_name = xstrdup(pw->pw_name);
151        copy->pw_passwd = xstrdup(pw->pw_passwd);
152        copy->pw_gecos = xstrdup(pw->pw_gecos);
153        copy->pw_uid = pw->pw_uid;
154        copy->pw_gid = pw->pw_gid;
155#ifdef HAVE_PW_EXPIRE_IN_PASSWD
156        copy->pw_expire = pw->pw_expire;
157#endif
158#ifdef HAVE_PW_CHANGE_IN_PASSWD
159        copy->pw_change = pw->pw_change;
160#endif
161#ifdef HAVE_PW_CLASS_IN_PASSWD
162        copy->pw_class = xstrdup(pw->pw_class);
163#endif
164        copy->pw_dir = xstrdup(pw->pw_dir);
165        copy->pw_shell = xstrdup(pw->pw_shell);
166        return copy;
167}
168
169/*
170 * Convert ASCII string to TCP/IP port number.
171 * Port must be >0 and <=65535.
172 * Return 0 if invalid.
173 */
174int
175a2port(const char *s)
176{
177        long port;
178        char *endp;
179
180        errno = 0;
181        port = strtol(s, &endp, 0);
182        if (s == endp || *endp != '\0' ||
183            (errno == ERANGE && (port == LONG_MIN || port == LONG_MAX)) ||
184            port <= 0 || port > 65535)
185                return 0;
186
187        return port;
188}
189
190#define SECONDS         1
191#define MINUTES         (SECONDS * 60)
192#define HOURS           (MINUTES * 60)
193#define DAYS            (HOURS * 24)
194#define WEEKS           (DAYS * 7)
195
196/*
197 * Convert a time string into seconds; format is
198 * a sequence of:
199 *      time[qualifier]
200 *
201 * Valid time qualifiers are:
202 *      <none>  seconds
203 *      s|S     seconds
204 *      m|M     minutes
205 *      h|H     hours
206 *      d|D     days
207 *      w|W     weeks
208 *
209 * Examples:
210 *      90m     90 minutes
211 *      1h30m   90 minutes
212 *      2d      2 days
213 *      1w      1 week
214 *
215 * Return -1 if time string is invalid.
216 */
217long
218convtime(const char *s)
219{
220        long total, secs;
221        const char *p;
222        char *endp;
223
224        errno = 0;
225        total = 0;
226        p = s;
227
228        if (p == NULL || *p == '\0')
229                return -1;
230
231        while (*p) {
232                secs = strtol(p, &endp, 10);
233                if (p == endp ||
234                    (errno == ERANGE && (secs == LONG_MIN || secs == LONG_MAX)) ||
235                    secs < 0)
236                        return -1;
237
238                switch (*endp++) {
239                case '\0':
240                        endp--;
241                case 's':
242                case 'S':
243                        break;
244                case 'm':
245                case 'M':
246                        secs *= MINUTES;
247                        break;
248                case 'h':
249                case 'H':
250                        secs *= HOURS;
251                        break;
252                case 'd':
253                case 'D':
254                        secs *= DAYS;
255                        break;
256                case 'w':
257                case 'W':
258                        secs *= WEEKS;
259                        break;
260                default:
261                        return -1;
262                }
263                total += secs;
264                if (total < 0)
265                        return -1;
266                p = endp;
267        }
268
269        return total;
270}
271
272char *
273cleanhostname(char *host)
274{
275        if (*host == '[' && host[strlen(host) - 1] == ']') {
276                host[strlen(host) - 1] = '\0';
277                return (host + 1);
278        } else
279                return host;
280}
281
282char *
283colon(char *cp)
284{
285        int flag = 0;
286
287        if (*cp == ':')         /* Leading colon is part of file name. */
288                return (0);
289        if (*cp == '[')
290                flag = 1;
291
292        for (; *cp; ++cp) {
293                if (*cp == '@' && *(cp+1) == '[')
294                        flag = 1;
295                if (*cp == ']' && *(cp+1) == ':' && flag)
296                        return (cp+1);
297                if (*cp == ':' && !flag)
298                        return (cp);
299                if (*cp == '/')
300                        return (0);
301        }
302        return (0);
303}
304
305/* function to assist building execv() arguments */
306void
307addargs(arglist *args, char *fmt, ...)
308{
309        va_list ap;
310        char buf[1024];
311
312        va_start(ap, fmt);
313        vsnprintf(buf, sizeof(buf), fmt, ap);
314        va_end(ap);
315
316        if (args->list == NULL) {
317                args->nalloc = 32;
318                args->num = 0;
319        } else if (args->num+2 >= args->nalloc)
320                args->nalloc *= 2;
321
322        args->list = xrealloc(args->list, args->nalloc * sizeof(char *));
323        args->list[args->num++] = xstrdup(buf);
324        args->list[args->num] = NULL;
325}
326
327mysig_t
328mysignal(int sig, mysig_t act)
329{
330#ifdef HAVE_SIGACTION
331        struct sigaction sa, osa;
332
333        if (sigaction(sig, NULL, &osa) == -1)
334                return (mysig_t) -1;
335        if (osa.sa_handler != act) {
336                memset(&sa, 0, sizeof(sa));
337                sigemptyset(&sa.sa_mask);
338                sa.sa_flags = 0;
339#if defined(SA_INTERRUPT)
340                if (sig == SIGALRM)
341                        sa.sa_flags |= SA_INTERRUPT;
342#endif
343                sa.sa_handler = act;
344                if (sigaction(sig, &sa, NULL) == -1)
345                        return (mysig_t) -1;
346        }
347        return (osa.sa_handler);
348#else
349        return (signal(sig, act));
350#endif
351}
Note: See TracBrowser for help on using the repository browser.