]> andersk Git - openssh.git/blob - misc.c
- (stevesk) handle systems without pw_expire and pw_change.
[openssh.git] / misc.c
1 /*      $OpenBSD: misc.c,v 1.11 2001/06/16 08:58:34 markus 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.11 2001/06/16 08:58:34 markus 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 clearing 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_EXPIRE_IN_PASSWD
135         copy->pw_expire = pw->pw_expire;
136 #endif
137 #ifdef HAVE_PW_CHANGE_IN_PASSWD
138         copy->pw_change = pw->pw_change;
139 #endif
140 #ifdef HAVE_PW_CLASS_IN_PASSWD
141         copy->pw_class = xstrdup(pw->pw_class);
142 #endif
143         copy->pw_dir = xstrdup(pw->pw_dir);
144         copy->pw_shell = xstrdup(pw->pw_shell);
145         return copy;
146 }
147
148 int a2port(const char *s)
149 {
150         long port;
151         char *endp;
152
153         errno = 0;
154         port = strtol(s, &endp, 0);
155         if (s == endp || *endp != '\0' ||
156             (errno == ERANGE && (port == LONG_MIN || port == LONG_MAX)) ||
157             port <= 0 || port > 65535)
158                 return 0;
159
160         return port;
161 }
162
163 #define SECONDS         1
164 #define MINUTES         (SECONDS * 60)
165 #define HOURS           (MINUTES * 60)
166 #define DAYS            (HOURS * 24)
167 #define WEEKS           (DAYS * 7)
168
169 long convtime(const char *s)
170 {
171         long total, secs;
172         const char *p;
173         char *endp;
174
175         errno = 0;
176         total = 0;
177         p = s;
178
179         if (p == NULL || *p == '\0')
180                 return -1;
181
182         while (*p) {
183                 secs = strtol(p, &endp, 10);
184                 if (p == endp ||
185                     (errno == ERANGE && (secs == LONG_MIN || secs == LONG_MAX)) ||
186                     secs < 0)
187                         return -1;
188
189                 switch (*endp++) {
190                 case '\0':
191                         endp--;
192                 case 's':
193                 case 'S':
194                         break;
195                 case 'm':
196                 case 'M':
197                         secs *= MINUTES;
198                         break;
199                 case 'h':
200                 case 'H':
201                         secs *= HOURS;
202                         break;
203                 case 'd':
204                 case 'D':
205                         secs *= DAYS;
206                         break;
207                 case 'w':
208                 case 'W':
209                         secs *= WEEKS;
210                         break;
211                 default:
212                         return -1;
213                 }
214                 total += secs;
215                 if (total < 0)
216                         return -1;
217                 p = endp;
218         }
219
220         return total;
221 }
222
223 char *
224 cleanhostname(char *host)
225 {
226         if (*host == '[' && host[strlen(host) - 1] == ']') {
227                 host[strlen(host) - 1] = '\0';
228                 return (host + 1);
229         } else
230                 return host;
231 }
232
233 char *
234 colon(char *cp)
235 {
236         int flag = 0;
237
238         if (*cp == ':')         /* Leading colon is part of file name. */
239                 return (0);
240         if (*cp == '[')
241                 flag = 1;
242
243         for (; *cp; ++cp) {
244                 if (*cp == '@' && *(cp+1) == '[')
245                         flag = 1;
246                 if (*cp == ']' && *(cp+1) == ':' && flag)
247                         return (cp+1);
248                 if (*cp == ':' && !flag)
249                         return (cp);
250                 if (*cp == '/')
251                         return (0);
252         }
253         return (0);
254 }
255
256 void
257 addargs(arglist *args, char *fmt, ...)
258 {
259         va_list ap;
260         char buf[1024];
261
262         va_start(ap, fmt);
263         vsnprintf(buf, sizeof(buf), fmt, ap);
264         va_end(ap);
265
266         if (args->list == NULL) {
267                 args->nalloc = 32;
268                 args->num = 0;
269         } else if (args->num+2 >= args->nalloc) 
270                 args->nalloc *= 2;
271
272         args->list = xrealloc(args->list, args->nalloc * sizeof(char *));
273         args->list[args->num++] = xstrdup(buf);
274         args->list[args->num] = NULL;
275 }
276
277 mysig_t
278 mysignal(int sig, mysig_t act)
279 {
280 #ifdef HAVE_SIGACTION
281         struct sigaction sa, osa;
282
283         if (sigaction(sig, NULL, &osa) == -1)
284                 return (mysig_t) -1;
285         if (osa.sa_handler != act) {
286                 memset(&sa, 0, sizeof(sa));
287                 sigemptyset(&sa.sa_mask);
288                 sa.sa_flags = 0;
289 #if defined(SA_INTERRUPT)
290                 if (sig == SIGALRM)
291                         sa.sa_flags |= SA_INTERRUPT;
292 #endif
293                 sa.sa_handler = act;
294                 if (sigaction(sig, &sa, NULL) == -1)
295                         return (mysig_t) -1;
296         }
297         return (osa.sa_handler);
298 #else
299         return (signal(sig, act));
300 #endif
301 }
This page took 0.08312 seconds and 5 git commands to generate.