]>
git.saurik.com Git - apple/system_cmds.git/blob - chpass.tproj/util.c
2 * Copyright (c) 1999-2006 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
24 * Copyright (c) 1990, 1993, 1994
25 * The Regents of the University of California. All rights reserved.
26 * Copyright (c) 2002 Networks Associates Technology, Inc.
27 * All rights reserved.
29 * Portions of this software were developed for the FreeBSD Project by
30 * ThinkSec AS and NAI Labs, the Security Research Division of Network
31 * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035
32 * ("CBOSS"), as part of the DARPA CHATS research program.
34 * Redistribution and use in source and binary forms, with or without
35 * modification, are permitted provided that the following conditions
37 * 1. Redistributions of source code must retain the above copyright
38 * notice, this list of conditions and the following disclaimer.
39 * 2. Redistributions in binary form must reproduce the above copyright
40 * notice, this list of conditions and the following disclaimer in the
41 * documentation and/or other materials provided with the distribution.
42 * 3. All advertising materials mentioning features or use of this software
43 * must display the following acknowledgement:
44 * This product includes software developed by the University of
45 * California, Berkeley and its contributors.
46 * 4. Neither the name of the University nor the names of its contributors
47 * may be used to endorse or promote products derived from this software
48 * without specific prior written permission.
50 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
51 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
52 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
53 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
54 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
55 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
56 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
57 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
58 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
59 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
66 static char sccsid
[] = "@(#)util.c 8.4 (Berkeley) 4/2/94";
69 #include <sys/cdefs.h>
70 __FBSDID("$FreeBSD: src/usr.bin/chpass/util.c,v 1.13 2004/01/18 21:46:39 charnier Exp $");
73 #include <sys/types.h>
89 #include "open_directory.h"
92 #endif /* OPEN_DIRECTORY */
94 static const char *months
[] =
95 { "January", "February", "March", "April", "May", "June",
96 "July", "August", "September", "October", "November",
103 static char tbuf
[50];
106 tp
= localtime(&tval
);
107 (void)sprintf(tbuf
, "%s %d, %d", months
[tp
->tm_mon
],
108 tp
->tm_mday
, tp
->tm_year
+ TM_YEAR_BASE
);
116 atot(char *p
, time_t *store
)
118 static struct tm
*lt
;
122 int day
, month
, year
;
131 lt
= localtime(&tval
);
133 if (!(t
= strtok(p
, " \t")))
138 for (mp
= months
;; ++mp
) {
141 if (!strncasecmp(*mp
, t
, 3)) {
142 month
= mp
- months
+ 1;
147 if (!(t
= strtok((char *)NULL
, " \t,")) || !isdigit(*t
))
150 if (!(t
= strtok((char *)NULL
, " \t,")) || !isdigit(*t
))
153 if (day
< 1 || day
> 31 || month
< 1 || month
> 12)
155 /* Allow two digit years 1969-2068 */
159 year
+= TM_YEAR_BASE
;
160 if (year
< EPOCH_YEAR
)
162 lt
->tm_year
= year
- TM_YEAR_BASE
;
163 lt
->tm_mon
= month
- 1;
169 if ((tval
= mktime(lt
)) < 0)
185 while ((sh
= getusershell())) {
186 if (!strcmp(name
, sh
)) {
191 /* allow just shell name, but use "real" path */
192 if ((p
= strrchr(sh
, '/')) && strcmp(name
, p
+ 1) == 0) {
203 dup_shell(char *name
)
208 while ((sh
= getusershell())) {
209 if (!strcmp(name
, sh
)) {
211 return (strdup(name
));
213 /* allow just shell name, but use "real" path */
214 if ((p
= strrchr(sh
, '/')) && strcmp(name
, p
+ 1) == 0) {
226 cfprintf(FILE* file
, const char* format
, ...) {
230 va_start(args
, format
);
231 CFStringRef formatStr
= CFStringCreateWithCStringNoCopy(NULL
, format
, kCFStringEncodingUTF8
, kCFAllocatorNull
);
233 CFStringRef str
= CFStringCreateWithFormatAndArguments(NULL
, NULL
, formatStr
, args
);
235 size_t size
= CFStringGetMaximumSizeForEncoding(CFStringGetLength(str
), kCFStringEncodingUTF8
) + 1;
238 if (cstr
&& CFStringGetCString(str
, cstr
, size
, kCFStringEncodingUTF8
)) {
239 result
= fprintf(file
, "%s", cstr
);
244 CFRelease(formatStr
);
250 * Edit the temp file. Return -1 on error, >0 if the file was modified, 0
254 editfile(const char* tfn
)
256 struct sigaction sa
, sa_int
, sa_quit
;
257 sigset_t oldsigset
, sigset
;
258 struct stat st1
, st2
;
259 const char *p
, *editor
;
263 if ((editor
= getenv("EDITOR")) == NULL
)
265 if (p
= strrchr(editor
, '/'))
270 if (stat(tfn
, &st1
) == -1)
272 sa
.sa_handler
= SIG_IGN
;
273 sigemptyset(&sa
.sa_mask
);
275 sigaction(SIGINT
, &sa
, &sa_int
);
276 sigaction(SIGQUIT
, &sa
, &sa_quit
);
277 sigemptyset(&sigset
);
278 sigaddset(&sigset
, SIGCHLD
);
279 sigprocmask(SIG_BLOCK
, &sigset
, &oldsigset
);
280 switch ((editpid
= fork())) {
284 sigaction(SIGINT
, &sa_int
, NULL
);
285 sigaction(SIGQUIT
, &sa_quit
, NULL
);
286 sigprocmask(SIG_SETMASK
, &oldsigset
, NULL
);
289 (void)setgid(getgid());
290 (void)setuid(getuid());
292 execlp(editor
, p
, tfn
, (char *)NULL
);
299 if (waitpid(editpid
, &pstat
, WUNTRACED
) == -1) {
305 } else if (WIFSTOPPED(pstat
)) {
306 raise(WSTOPSIG(pstat
));
307 } else if (WIFEXITED(pstat
) && WEXITSTATUS(pstat
) == 0) {
316 sigaction(SIGINT
, &sa_int
, NULL
);
317 sigaction(SIGQUIT
, &sa_quit
, NULL
);
318 sigprocmask(SIG_SETMASK
, &oldsigset
, NULL
);
319 if (stat(tfn
, &st2
) == -1)
321 return (st1
.st_mtime
!= st2
.st_mtime
);
325 pw_error(char *name
, int err
, int eval
)
332 #endif /* OPEN_DIRECTORY */