util.c revision 99112
11590Srgrimes/*- 21590Srgrimes * Copyright (c) 1988, 1993, 1994 31590Srgrimes * The Regents of the University of California. All rights reserved. 496201Sdes * Copyright (c) 2002 Networks Associates Technology, Inc. 596201Sdes * All rights reserved. 61590Srgrimes * 796201Sdes * Portions of this software were developed for the FreeBSD Project by 896201Sdes * ThinkSec AS and NAI Labs, the Security Research Division of Network 996201Sdes * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 1096201Sdes * ("CBOSS"), as part of the DARPA CHATS research program. 1196201Sdes * 121590Srgrimes * Redistribution and use in source and binary forms, with or without 131590Srgrimes * modification, are permitted provided that the following conditions 141590Srgrimes * are met: 151590Srgrimes * 1. Redistributions of source code must retain the above copyright 161590Srgrimes * notice, this list of conditions and the following disclaimer. 171590Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 181590Srgrimes * notice, this list of conditions and the following disclaimer in the 191590Srgrimes * documentation and/or other materials provided with the distribution. 201590Srgrimes * 3. All advertising materials mentioning features or use of this software 211590Srgrimes * must display the following acknowledgement: 221590Srgrimes * This product includes software developed by the University of 231590Srgrimes * California, Berkeley and its contributors. 241590Srgrimes * 4. Neither the name of the University nor the names of its contributors 251590Srgrimes * may be used to endorse or promote products derived from this software 261590Srgrimes * without specific prior written permission. 271590Srgrimes * 281590Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 291590Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 301590Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 311590Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 321590Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 331590Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 341590Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 351590Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 361590Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 371590Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 381590Srgrimes * SUCH DAMAGE. 391590Srgrimes */ 401590Srgrimes 411590Srgrimes#ifndef lint 4299112Sobrien#if 0 4399112Sobrienstatic char sccsid[] = "@(#)util.c 8.4 (Berkeley) 4/2/94"; 4499112Sobrien#endif 451590Srgrimes#endif /* not lint */ 4693086Smarkm#include <sys/cdefs.h> 4793086Smarkm__FBSDID("$FreeBSD: head/usr.bin/chpass/util.c 99112 2002-06-30 05:25:07Z obrien $"); 4893086Smarkm 491590Srgrimes#include <sys/types.h> 501590Srgrimes 511590Srgrimes#include <ctype.h> 521590Srgrimes#include <pwd.h> 531590Srgrimes#include <stdio.h> 541590Srgrimes#include <stdlib.h> 551590Srgrimes#include <string.h> 561590Srgrimes#include <time.h> 571590Srgrimes#include <unistd.h> 581590Srgrimes 591590Srgrimes#include "chpass.h" 601590Srgrimes 6193086Smarkmstatic const char *months[] = 621590Srgrimes { "January", "February", "March", "April", "May", "June", 631590Srgrimes "July", "August", "September", "October", "November", 641590Srgrimes "December", NULL }; 651590Srgrimes 661590Srgrimeschar * 6793086Smarkmttoa(time_t tval) 681590Srgrimes{ 691590Srgrimes struct tm *tp; 701590Srgrimes static char tbuf[50]; 711590Srgrimes 721590Srgrimes if (tval) { 731590Srgrimes tp = localtime(&tval); 741590Srgrimes (void)sprintf(tbuf, "%s %d, %d", months[tp->tm_mon], 759987Swollman tp->tm_mday, tp->tm_year + 1900); 761590Srgrimes } 771590Srgrimes else 781590Srgrimes *tbuf = '\0'; 791590Srgrimes return (tbuf); 808874Srgrimes} 811590Srgrimes 821590Srgrimesint 8393086Smarkmatot(char *p, time_t *store) 841590Srgrimes{ 851590Srgrimes static struct tm *lt; 8693086Smarkm char *t; 8793086Smarkm const char **mp; 881590Srgrimes time_t tval; 891590Srgrimes int day, month, year; 901590Srgrimes 911590Srgrimes if (!*p) { 921590Srgrimes *store = 0; 931590Srgrimes return (0); 941590Srgrimes } 951590Srgrimes if (!lt) { 961590Srgrimes unsetenv("TZ"); 971590Srgrimes (void)time(&tval); 981590Srgrimes lt = localtime(&tval); 991590Srgrimes } 1001590Srgrimes if (!(t = strtok(p, " \t"))) 1011590Srgrimes goto bad; 10217544Speter if (isdigit(*t)) { 10317544Speter month = atoi(t); 10417544Speter } else { 10517544Speter for (mp = months;; ++mp) { 10617544Speter if (!*mp) 10717544Speter goto bad; 10817544Speter if (!strncasecmp(*mp, t, 3)) { 10917544Speter month = mp - months + 1; 11017544Speter break; 11117544Speter } 1121590Srgrimes } 1131590Srgrimes } 1141590Srgrimes if (!(t = strtok((char *)NULL, " \t,")) || !isdigit(*t)) 1151590Srgrimes goto bad; 1161590Srgrimes day = atoi(t); 1171590Srgrimes if (!(t = strtok((char *)NULL, " \t,")) || !isdigit(*t)) 1181590Srgrimes goto bad; 1191590Srgrimes year = atoi(t); 12092554Scjc if (day < 1 || day > 31 || month < 1 || month > 12) 1211590Srgrimes goto bad; 12242815Sdanny /* Allow two digit years 1969-2068 */ 12342815Sdanny if (year < 69) 12442815Sdanny year += 2000; 12542815Sdanny else if (year < 100) 1269987Swollman year += 1900; 12742815Sdanny if (year < 1969) 1281590Srgrimesbad: return (1); 1299987Swollman lt->tm_year = year - 1900; 1309554Smpp lt->tm_mon = month - 1; 1319554Smpp lt->tm_mday = day; 1329554Smpp lt->tm_hour = 0; 1339554Smpp lt->tm_min = 0; 1349554Smpp lt->tm_sec = 0; 1359554Smpp lt->tm_isdst = -1; 1369554Smpp if ((tval = mktime(lt)) < 0) 1379554Smpp return (1); 1381590Srgrimes *store = tval; 1391590Srgrimes return (0); 1401590Srgrimes} 1411590Srgrimes 1421590Srgrimeschar * 14393086Smarkmok_shell(char *name) 1441590Srgrimes{ 1451590Srgrimes char *p, *sh; 1461590Srgrimes 1471590Srgrimes setusershell(); 14834797Scharnier while ((sh = getusershell())) { 1491590Srgrimes if (!strcmp(name, sh)) 1501590Srgrimes return (name); 1511590Srgrimes /* allow just shell name, but use "real" path */ 1521590Srgrimes if ((p = strrchr(sh, '/')) && strcmp(name, p + 1) == 0) 1531590Srgrimes return (sh); 1541590Srgrimes } 1551590Srgrimes return (NULL); 1561590Srgrimes} 157