glibc/time/getdate.c
Ulrich Drepper f21acc89c0 Update.
1997-07-13 01:18  Ulrich Drepper  <drepper@cygnus.com>

	* setjmp/setjmp.h: Define _setjmp and _longjmp also if __USE_XOPEN.

	* sysdeps/unix/sysv/linux/bits/ipc.h: Fix comment.
	* sysdeps/unix/sysv/linux/bits/msq.h: Likewise.
	* sysdeps/unix/sysv/linux/bits/sem.h: Likewise.
	* sysdeps/unix/sysv/linux/bits/shm.h: Likewise.

	* time/Makefile (routines): Add getdate.
	* time/time.h: Add prototype for getdate and getdate_r.
	* time/getdate.c: New file.
	Provided by Mark Kettenis <kettenis@phys.uva.nl>.

1997-06-30 14:49  H.J. Lu  <hjl@gnu.ai.mit.edu>

	From Ralf Baechle <ralf@informatik.uni-koblenz.de> on
	Sat Jun 21 18:11:21 1997:

	* sysdeps/unix/sysv/linux/syscalls.list (swapon): Add __swapon alias.
	(swapoff): New.

	* elf/Makefile: Add linker script support.
	(headers): Add bits/dlfcn.h.

	* elf/dl-load.c (MAP_BASE_ADDR): New.

	* elf/dlfcn.h: Include <bits/dlfcn.h>.

	* elf/elf.h: Add MIPS support.

	* sysdeps/generic/Dist: Add entry.h.
	* sysdeps/generic/entry.h: New, define the entry symbol.

	* elf/rtld.c (_start): Include <entry.h>.  Change to ENTRY_POINT.
	* sysdeps/generic/dl-sysdep.c (_start): Likewise.
	* mips/elf/start.S (_start): Likewise.

	* sysdeps/mips/bsd-_setjmp.S: Fix PIC.
	* sysdeps/mips/bsd-setjmp.S: Likewise.
	* sysdeps/mips/setjmp.S: Likewise.
	* mips/elf/start.S: Likewise.
	* sysdeps/unix/mips/brk.S: Likewise.
	* sysdeps/unix/mips/sysdep.S: Likewise.
	* sysdeps/unix/mips/sysdep.h: Likewise.
	* sysdeps/unix/mips/wait.S: Likewise.

	* sysdeps/mips/dl-machine.h: Update for Linux/MIPS.
	* sysdeps/mips/fpu_control.h: Likewise.

	* sysdeps/generic/bits/dlfcn.h: New file.

	* sysdeps/mips/rtld-ldscript.in: New for Linux/MIPS.
	* sysdeps/mips/rtld-parms: Likewise.
	* sysdeps/mips/bits/dlfcn.h: Likewise.
	* sysdeps/mips/mips64/rtld-parms: Likewise.
	* sysdeps/mips/mipsel/rtld-parms: Likewise.
	* sysdeps/unix/sysv/linux/mips/Dist: Likewise.
	* sysdeps/unix/sysv/linux/mips/Makefile: Likewise.
	* sysdeps/unix/sysv/linux/mips/clone.S: Likewise.
	* sysdeps/unix/sysv/linux/mips/entry.h: Likewise.
	* sysdeps/unix/sysv/linux/mips/fpregdef.h: Likewise.
	* sysdeps/unix/sysv/linux/mips/fxstat.c: Likewise.
	* sysdeps/unix/sysv/linux/mips/kernel_sigaction.h: Likewise.
	* sysdeps/unix/sysv/linux/mips/kernel_stat.h: Likewise.
	* sysdeps/unix/sysv/linux/mips/kernel_termios.h: Likewise.
	* sysdeps/unix/sysv/linux/mips/lxstat.c: Likewise.
	* sysdeps/unix/sysv/linux/mips/regdef.h: Likewise.
	* sysdeps/unix/sysv/linux/mips/sgidefs.h: Likewise.
	* sysdeps/unix/sysv/linux/mips/syscalls.list: Likewise.
	* sysdeps/unix/sysv/linux/mips/ustat.c: Likewise.
	* sysdeps/unix/sysv/linux/mips/xmknod.c: Likewise.
	* sysdeps/unix/sysv/linux/mips/xstat.c: Likewise.
	* sysdeps/unix/sysv/linux/mips/bits/endian.h: Likewise.
	* sysdeps/unix/sysv/linux/mips/bits/fcntl.h: Likewise.
	* sysdeps/unix/sysv/linux/mips/bits/ioctl-types.h:
	* sysdeps/unix/sysv/linux/mips/bits/ipc.h: Likewise.
	* sysdeps/unix/sysv/linux/mips/bits/shm.h: Likewise.
	* sysdeps/unix/sysv/linux/mips/bits/sigaction.h: Likewise.
	* sysdeps/unix/sysv/linux/mips/bits/signum.h: Likewise.
	* sysdeps/unix/sysv/linux/mips/bits/socket.h: Likewise.
	* sysdeps/unix/sysv/linux/mips/bits/stat.h: Likewise.
	* sysdeps/unix/sysv/linux/mips/bits/statfs.h: Likewise.
	* sysdeps/unix/sysv/linux/mips/bits/termios.h: Likewise.
	* sysdeps/unix/sysv/linux/mips/bits/time.h: Likewise.
	* sysdeps/unix/sysv/linux/mips/sys/acct.h: Likewise.
	* sysdeps/unix/sysv/linux/mips/sys/asm.h: Likewise.
	* sysdeps/unix/sysv/linux/mips/sys/cachectl.h: Likewise.
	* sysdeps/unix/sysv/linux/mips/sys/fpregdef.h: Likewise.
	* sysdeps/unix/sysv/linux/mips/sys/procfs.h: Likewise.
	* sysdeps/unix/sysv/linux/mips/sys/regdef.h: Likewise.
	* sysdeps/unix/sysv/linux/mips/sys/syscall.h: Likewise.
	* sysdeps/unix/sysv/linux/mips/sys/sysmips.h: Likewise.

1997-04-09 19:05  H.J. Lu (hjl@gnu.ai.mit.edu)

	* isomac.c (xstrndup): New, use it instead of strndup ().

1997-07-02 08:55  H.J. Lu  <hjl@gnu.ai.mit.edu>

	* sysdeps/i386/dl-machine.h (elf_machine_rel): Print
	the program name for different sizes.

1997-07-10 15:47  Fila Kolodny  <fila@ibi.com>

	* nis/ypclnt.c: Change references to MAXHOSTNAMELEN to NIS_MAXNAMELEN.
	Add include of rpcsvc/nis.h.
	* inet/getnameinfo.c: Delete references to MAXHOSTNAMELEN.
	* sysdeps/posix/getaddrinfo.c: Likewise.
	Change size of variable buffer to be big enough to hold an IPv6
	address in printable format.

1997-07-12 18:47  Ulrich Drepper  <drepper@cygnus.com>

	* assert/assert.h [!NDEBUG] (assert, assert_perror): Don't use ||
	and && in tests to allow use in C++ code which overloads these
	operators.  Reported by Istvan Marko <istvan@cmdmail.amd.com>.

	* configure.in: Move mips64* recognition before mips*.
	Patch by Zack Weinberg <zack@rabi.phys.columbia.edu>.

1997-07-03 20:44  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>

	* Makerules (lib%.so, $(common-objpfx)libc.so): Don't use
	automatic variables in dependency lists.
	(build-shlib): Always filter out the version script file.
	* extra-lib.mk ($(objpfx)$(lib).so): Depend on version script.

1997-07-12 17:56  Ulrich Drepper  <drepper@cygnus.com>

	* login/login.c (tty_name): Test return value of ttyname_r for !=
	0, not < 0.
	* misc/ttyslot.c (ttyslot): Test return value of ttyname_r for ==
	0, not >= 0.
	* sysdeps/unix/getlogin.c (getlogin): Test return value of
	ttyname_r for != 0.
	* sysdeps/unix/getlogin_r.c (getlogin_r): Likewise.

1997-07-10  Andreas Jaeger  <aj@arthur.rhein-neckar.de>

	* login/utmp_file.c (getutline_r_file): Fix type: compare with
	*result.

1997-07-11 00:21  Mark Kettenis  <kettenis@phys.uva.nl>

	* login/Makefile (headers): Add utmpx.h and bits/utmpx.h.

1997-07-09 19:21  Mark Kettenis  <kettenis@phys.uva.nl>

	* login/programs/utmpd.c, login/programs/database.c,
	login/programs/request.c: Prepare messages for
	internationalization.

	* login/programs/utmpd.c:
	(main): Change handling of errors in opening the database.
	* login/programs/database.c:
	(open_database, synchronize_dtatabase, initialize_database):
	Properly handle errors.
	(get_mtime): Use fstat instead of stat.  All callers changed.

	* login/getutent_r.c: Make setutxent a weak alias for __setutxent.
	* login/getutent.c: Rename getutent to __getutent and make
	getutent a weak alias.
	Make getutxent a weak alias for	__getutent.
	* login/utmpx.h: New file.
	* sysdeps/gnu/bits/utmp.h: Cleanup.  Added comments.
	* sysdeps/gnu/bits/utmpx.h: New file.

	* stdio-common/strops.c: Partialy undo last change.  Will need
	more investigation.
1997-07-12 23:35:19 +00:00

248 lines
6.4 KiB
C

/* Convert a string representation of time to a time value.
Copyright (C) 1997 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Mark Kettenis <kettenis@phys.uva.nl>, 1997.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If not,
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <sys/stat.h>
/* Prototypes for local functions. */
static int first_wday (int year, int mon, int wday);
static int check_mday (int year, int mon, int mday);
/* Set to one of the following values to indicate an error.
1 the DATEMSK environment variable is null or undefined,
2 the template file cannot be opened for reading,
3 failed to get file status information,
4 the template file is not a regular file,
5 an error is encountered while reading the template file,
6 memory allication failed (not enough memory available),
7 there is no line in the template that matches the input,
8 invalid input specification Example: February 31 or a time is
specified that can not be represented in a time_t (representing
the time in seconds since 00:00:00 UTC, January 1, 1970) */
int getdate_err = 0;
/* Returns the first weekday WDAY of month MON in the year YEAR. */
static int
first_wday (int year, int mon, int wday)
{
struct tm tm;
if (wday == INT_MIN)
return 1;
memset (&tm, 0, sizeof (struct tm));
tm.tm_year = year;
tm.tm_mon = mon;
tm.tm_mday = 1;
mktime (&tm);
return (1 + (wday - tm.tm_wday + 7) % 7);
}
/* Returns 1 if MDAY is a valid day of the month in month MON of year
YEAR, and 0 if it is not. */
static int
check_mday (int year, int mon, int mday)
{
switch (mon)
{
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
if (mday >= 1 && mday <= 31)
return 1;
break;
case 4:
case 6:
case 9:
case 11:
if (mday >= 1 && mday <= 30)
return 1;
break;
case 2:
if (mday >= 1 && mday < (__isleap (year) ? 29 : 28))
return 1;
break;
}
return 0;
}
int
__getdate_r (const char *string, struct tm *tp)
{
FILE *fp;
char *line;
size_t len;
char *datemsk;
char *result = NULL;
time_t timer;
struct tm tm;
struct stat st;
int mday_ok = 0;
datemsk = getenv ("DATEMSK");
if (datemsk == NULL || *datemsk == '\0')
return 1;
if (stat (datemsk, &st) < 0)
return 3;
if (!S_ISREG (st.st_mode))
return 4;
/* Open the template file. */
fp = fopen (datemsk, "r");
if (fp == NULL)
return 2;
line = NULL;
len = 0;
do
{
ssize_t n;
n = __getline (&line, &len, fp);
if (n < 0)
break;
if (line[n - 1] == '\n')
line[n - 1] = '\0';
/* Do the conversion. */
tp->tm_year = tp->tm_mon = tp->tm_mday = tp->tm_wday = INT_MIN;
tp->tm_hour = tp->tm_sec = tp->tm_min = INT_MIN;
result = strptime (string, line, tp);
if (result && *result == '\0')
break;
}
while (!feof (fp));
/* Free the buffer. */
free (line);
/* Check for errors. */
if (ferror (fp))
{
fclose (fp);
return 5;
}
/* Close template file. */
fclose (fp);
if (result == NULL)
return 7;
/* Get current time. */
time (&timer);
__localtime_r (&timer, &tm);
/* If only the weekday is given, today is assumed if the given day
is equal to the current day and next week if it is less. */
if (tp->tm_wday >= 0 && tp->tm_wday <= 6 && tp->tm_year == INT_MIN
&& tp->tm_mon == INT_MIN && tp->tm_mday == INT_MIN)
{
tp->tm_year = tm.tm_year;
tp->tm_mon = tm.tm_mon;
tp->tm_mday = tm.tm_mday + (tp->tm_wday - tm.tm_wday + 7) % 7;
mday_ok = 1;
}
/* If only the month is given, the current month is assumed if the
given month is equal to the current month and next year if it is
less and no year is given (the first day of month is assumed if
no day is given. */
if (tp->tm_mon >= 0 && tp->tm_mon <= 11 && tp->tm_mday == INT_MIN)
{
if (tp->tm_year == INT_MIN)
tp->tm_year = tm.tm_year + (((tp->tm_mon - tm.tm_mon) < 0) ? 1 : 0);
tp->tm_mday = first_wday (tp->tm_year, tp->tm_mon, tp->tm_wday);
mday_ok = 1;
}
/* If no hour, minute and second are given the current hour, minute
and second are assumed. */
if (tp->tm_hour == INT_MIN && tp->tm_min == INT_MIN && tp->tm_sec == INT_MIN)
{
tp->tm_hour = tm.tm_hour;
tp->tm_min = tm.tm_min;
tp->tm_sec = tm.tm_sec;
}
/* If no date is given, today is assumed if the given hour is
greater than the current hour and tomorrow is assumed if
it is less. */
if (tp->tm_hour >= 0 && tp->tm_hour <= 23
&& tp->tm_year == INT_MIN && tp->tm_mon == INT_MIN
&& tp->tm_mday == INT_MIN && tp->tm_wday == INT_MIN)
{
tp->tm_year = tm.tm_year;
tp->tm_mon = tm.tm_mon;
tp->tm_mday = tm.tm_mday + ((tp->tm_hour - tm.tm_hour) < 0 ? 1 : 0);
mday_ok = 1;
}
/* Fill in the gaps. */
if (tp->tm_year == INT_MIN)
tp->tm_year = tm.tm_year;
if (tp->tm_hour == INT_MIN)
tp->tm_hour = 0;
if (tp->tm_min == INT_MIN)
tp->tm_min = 0;
if (tp->tm_sec == INT_MIN)
tp->tm_sec = 0;
/* Check if the day of month is within range, and if the time can be
represented in a time_t. We make use of the fact that the mktime
call normalizes the struct tm. */
if ((!mday_ok && !check_mday (tp->tm_year, tp->tm_mon, tp->tm_mday))
|| mktime (tp) == (time_t) -1)
return 8;
return 0;
}
#ifdef weak_alias
weak_alias (__getdate_r, getdate_r)
#endif
struct tm *
getdate (const char *string)
{
/* Buffer returned by getdate. */
static struct tm tmbuf;
int errval = __getdate_r (string, &tmbuf);
return errval == 0 ? &tmbuf : NULL;
}