]> andersk Git - openssh.git/blob - misc.c
- stevesk@cvs.openbsd.org 2001/05/19 19:43:57
[openssh.git] / misc.c
1 /*      $OpenBSD: misc.c,v 1.9 2001/05/19 19:43:57 stevesk Exp $        */
2
3 /*
4  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26
27 #include "includes.h"
28 RCSID("$OpenBSD: misc.c,v 1.9 2001/05/19 19:43:57 stevesk Exp $");
29
30 #include "misc.h"
31 #include "log.h"
32 #include "xmalloc.h"
33
34 char *
35 chop(char *s)
36 {
37         char *t = s;
38         while (*t) {
39                 if(*t == '\n' || *t == '\r') {
40                         *t = '\0';
41                         return s;
42                 }
43                 t++;
44         }
45         return s;
46
47 }
48
49 void
50 set_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                 if (errno != ENODEV)
67                         error("fcntl(%d, F_SETFL, O_NONBLOCK): %s",
68                             fd, strerror(errno));
69 }
70
71 void
72 unset_nonblock(int fd)
73 {
74         int val;
75
76         val = fcntl(fd, F_GETFL, 0);
77         if (val < 0) {
78                 error("fcntl(%d, F_GETFL, 0): %s", fd, strerror(errno));
79                 return;
80         }
81         if (!(val & O_NONBLOCK)) {
82                 debug2("fd %d is not O_NONBLOCK", fd);
83                 return;
84         }
85         debug("fd %d setting O_NONBLOCK", fd);
86         val &= ~O_NONBLOCK;
87         if (fcntl(fd, F_SETFL, val) == -1)
88                 if (errno != ENODEV)
89                         error("fcntl(%d, F_SETFL, O_NONBLOCK): %s",
90                             fd, strerror(errno));
91 }
92
93 /* Characters considered whitespace in strsep calls. */
94 #define WHITESPACE " \t\r\n"
95
96 char *
97 strdelim(char **s)
98 {
99         char *old;
100         int wspace = 0;
101
102         if (*s == NULL)
103                 return NULL;
104
105         old = *s;
106
107         *s = strpbrk(*s, WHITESPACE "=");
108         if (*s == NULL)
109                 return (old);
110
111         /* Allow only one '=' to be skipped */
112         if (*s[0] == '=')
113                 wspace = 1;
114         *s[0] = '\0';
115
116         *s += strspn(*s + 1, WHITESPACE) + 1;
117         if (*s[0] == '=' && !wspace)
118                 *s += strspn(*s + 1, WHITESPACE) + 1;
119
120         return (old);
121 }
122
123 struct passwd *
124 pwcopy(struct passwd *pw)
125 {
126         struct passwd *copy = xmalloc(sizeof(*copy));
127
128         memset(copy, 0, sizeof(*copy));
129         copy->pw_name = xstrdup(pw->pw_name);
130         copy->pw_passwd = xstrdup(pw->pw_passwd);
131         copy->pw_gecos = xstrdup(pw->pw_gecos);
132         copy->pw_uid = pw->pw_uid;
133         copy->pw_gid = pw->pw_gid;
134 #ifdef HAVE_PW_CLASS_IN_PASSWD
135         copy->pw_class = xstrdup(pw->pw_class);
136 #endif
137         copy->pw_dir = xstrdup(pw->pw_dir);
138         copy->pw_shell = xstrdup(pw->pw_shell);
139         return copy;
140 }
141
142 int a2port(const char *s)
143 {
144         long port;
145         char *endp;
146
147         errno = 0;
148         port = strtol(s, &endp, 0);
149         if (s == endp || *endp != '\0' ||
150             (errno == ERANGE && (port == LONG_MIN || port == LONG_MAX)) ||
151             port <= 0 || port > 65535)
152                 return 0;
153
154         return port;
155 }
156
157 #define SECONDS         1
158 #define MINUTES         (SECONDS * 60)
159 #define HOURS           (MINUTES * 60)
160 #define DAYS            (HOURS * 24)
161 #define WEEKS           (DAYS * 7)
162
163 long convtime(const char *s)
164 {
165         long total, secs;
166         const char *p;
167         char *endp;
168
169         errno = 0;
170         total = 0;
171         p = s;
172
173         if (p == NULL || *p == '\0')
174                 return -1;
175
176         while (*p) {
177                 secs = strtol(p, &endp, 10);
178                 if (p == endp ||
179                     (errno == ERANGE && (secs == LONG_MIN || secs == LONG_MAX)) ||
180                     secs < 0)
181                         return -1;
182
183                 switch (*endp++) {
184                 case '\0':
185                         endp--;
186                 case 's':
187                 case 'S':
188                         break;
189                 case 'm':
190                 case 'M':
191                         secs *= MINUTES;
192                         break;
193                 case 'h':
194                 case 'H':
195                         secs *= HOURS;
196                         break;
197                 case 'd':
198                 case 'D':
199                         secs *= DAYS;
200                         break;
201                 case 'w':
202                 case 'W':
203                         secs *= WEEKS;
204                         break;
205                 default:
206                         return -1;
207                 }
208                 total += secs;
209                 if (total < 0)
210                         return -1;
211                 p = endp;
212         }
213
214         return total;
215 }
216
217 char *
218 cleanhostname(char *host)
219 {
220         if (*host == '[' && host[strlen(host) - 1] == ']') {
221                 host[strlen(host) - 1] = '\0';
222                 return (host + 1);
223         } else
224                 return host;
225 }
226
227 char *
228 colon(char *cp)
229 {
230         int flag = 0;
231
232         if (*cp == ':')         /* Leading colon is part of file name. */
233                 return (0);
234         if (*cp == '[')
235                 flag = 1;
236
237         for (; *cp; ++cp) {
238                 if (*cp == '@' && *(cp+1) == '[')
239                         flag = 1;
240                 if (*cp == ']' && *(cp+1) == ':' && flag)
241                         return (cp+1);
242                 if (*cp == ':' && !flag)
243                         return (cp);
244                 if (*cp == '/')
245                         return (0);
246         }
247         return (0);
248 }
249
250 void
251 addargs(arglist *args, char *fmt, ...)
252 {
253         va_list ap;
254         char buf[1024];
255
256         va_start(ap, fmt);
257         vsnprintf(buf, sizeof(buf), fmt, ap);
258         va_end(ap);
259
260         if (args->list == NULL) {
261                 args->nalloc = 32;
262                 args->num = 0;
263         } else if (args->num+2 >= args->nalloc) 
264                 args->nalloc *= 2;
265
266         args->list = xrealloc(args->list, args->nalloc * sizeof(char *));
267         args->list[args->num++] = xstrdup(buf);
268         args->list[args->num] = NULL;
269 }
270
271 mysig_t
272 mysignal(int sig, mysig_t act)
273 {
274 #ifdef HAVE_SIGACTION
275         struct sigaction sa, osa;
276
277         if (sigaction(sig, NULL, &osa) == -1)
278                 return (mysig_t) -1;
279         if (osa.sa_handler != act) {
280                 memset(&sa, 0, sizeof(sa));
281                 sigemptyset(&sa.sa_mask);
282                 sa.sa_flags = 0;
283 #if defined(SA_RESTART)
284                 if (sig == SIGCHLD)
285                         sa.sa_flags |= SA_RESTART;
286 #endif
287 #if defined(SA_INTERRUPT)
288                 if (sig == SIGALRM)
289                         sa.sa_flags |= SA_INTERRUPT;
290 #endif
291                 sa.sa_handler = act;
292                 if (sigaction(sig, &sa, NULL) == -1)
293                         return (mysig_t) -1;
294         }
295         return (osa.sa_handler);
296 #else
297         return (signal(sig, act));
298 #endif
299 }
This page took 0.05904 seconds and 5 git commands to generate.