/* * Copyright (c) 2015 Carsten Larsen * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #include "private.h" #include "amiga_tz.h" struct LocaleBase* ctypeBase = NULL; struct Locale* ctypeLocale= NULL; /**********************************************************************/ void InitCTypeLocale() { ctypeBase = (struct LocaleBase*)OpenLibrary("locale.library", 38L); ctypeLocale = OpenLocale(NULL); } void CleanupCTypeLocale() { if (ctypeBase != NULL) { CloseLocale(ctypeLocale); ctypeLocale = NULL; CloseLibrary((struct Library*)ctypeBase); ctypeBase = NULL; } } /**********************************************************************/ int isalnum(int c) { int res; InitCTypeLocale(); res = IsAlNum(ctypeLocale, (ULONG)c); CleanupCTypeLocale(); return res; } int isalpha(int c) { int res; InitCTypeLocale(); res = IsAlpha(ctypeLocale, (ULONG)c); CleanupCTypeLocale(); return res; } int isdigit(int c) { int res; InitCTypeLocale(); res = IsDigit(ctypeLocale, (ULONG)c); CleanupCTypeLocale(); return res; } int ispunct(int c) { int res; InitCTypeLocale(); res = IsPunct(ctypeLocale, (ULONG)c); CleanupCTypeLocale(); return res; } int isspace(int c) { int res; InitCTypeLocale(); res = IsSpace(ctypeLocale, (ULONG)c); CleanupCTypeLocale(); return res; } int isupper(int c) { int res; InitCTypeLocale(); res = IsUpper(ctypeLocale, (ULONG)c); CleanupCTypeLocale(); return res; } int iscntrl(int c) { int res; InitCTypeLocale(); res = IsCntrl(ctypeLocale, (ULONG)c); CleanupCTypeLocale(); return res; } /**********************************************************************/ struct Device *TimerBase = NULL; struct timerequest *request = NULL; int delete_timer() { struct MsgPort *port; if (request == NULL) return 1; port = request->tr_node.io_Message.mn_ReplyPort; if (port != 0) DeletePort(port); CloseDevice((struct IORequest*)request); DeleteExtIO((struct IORequest*)request); return 0; } int create_timer() { LONG error; struct MsgPort *port = CreatePort(0, 0); if (port == NULL) return 1; request = (struct timerequest*)CreateExtIO(port, sizeof(struct timerequest)); if (request == NULL) { DeletePort(port); return 1; } error = OpenDevice(TIMERNAME, UNIT_MICROHZ, (struct IORequest*)request, 0L); if (error != 0) { delete_timer(request); return 1; } TimerBase = (struct Device*)request->tr_node.io_Device; return 0; } /**********************************************************************/ // The time () function returns the value of time in seconds since 0 hours, // 0 minutes, 0 seconds, January 1, 1970, Coordinated Universal Time. If an // error occurs, time () returns the value Po Vt time_t Pc Ns -1 . // // The return value is also stored in * tloc , provided that tloc is non-null. // // NOTICE: This function does not comply with above specifications yet. // tz_time_t time(tz_time_t *tloc) { struct LocaleBase* localeBase; struct Locale* locale; struct timeval tv; int error; localeBase = (struct LocaleBase*)OpenLibrary("locale.library", 38L); if (localeBase == NULL) { return 0; } locale = OpenLocale(NULL); if (locale == NULL) { CloseLibrary((struct Library*)localeBase); return 0; } error = create_timer(); if (error != 0) { return 0; } GetSysTime(&tv); // TODO: Check TZPatch envvar // If set time is gmt -> Do not use locale to modify // If not set, time is local -> use locale to modify // TODO: Check TZ envvar is valid // If set time is locale -> use TZ gmtoffset to get gmt. // if not set, ignore value if (tloc) { *tloc = (time_t)tv.tv_secs - locale->loc_GMTOffset * 60; // Check for TZ GMT offset } CloseLocale(locale); CloseLibrary((struct Library*)localeBase); delete_timer(); return (time_t)tv.tv_secs; //- locale->loc_GMTOffset * 60; // Check for TZ GMT offset } int get_gmtoffset() { struct tm tm; timezone_t tz = NULL; time_t now = time(NULL); char *ret = getenv("TZ"); tz = tzalloc(ret); if (tz) { localtime_rz(tz, &now, &tm); tzfree(tz); return tm.tm_gmtoff; } return 0; } /**********************************************************************/ int settimeofday(const struct timeval *tv, const struct timezone *tz) { struct LocaleBase* localeBase; struct Locale* locale; int error; localeBase = (struct LocaleBase*)OpenLibrary("locale.library", 38L); if (localeBase == NULL) { return 1; } locale = OpenLocale(NULL); if (locale == NULL) { CloseLibrary((struct Library*)localeBase); return 1; } error = create_timer(); if (error != 0) { return error; } // TODO: Check TZPatch envvar // If set time is gmt -> Do not use locale to modify // If not set, time is local -> use locale to modify // TODO: Check TZ envvar is valid // If set time is locale -> use TZ gmtoffset to get gmt. // if not set, ignore value request->tr_node.io_Command = TR_SETSYSTIME; request->tr_time.tv_secs = (long)tv->tv_secs - AMIGAOFFSET + locale->loc_GMTOffset * 60; request->tr_time.tv_micro = tv->tv_micro; DoIO((struct IORequest*)request); error = delete_timer(); CloseLocale(locale); CloseLibrary((struct Library*)localeBase); return error; } /**********************************************************************/ int gettime(struct timeval *tv) { int error = create_timer(); if (error != 0) { return error; } GetSysTime(tv); error = delete_timer(); return error; } int settime(struct timeval *tv) { int error = create_timer(); if (error != 0) { return error; } request->tr_node.io_Command = TR_SETSYSTIME; request->tr_time.tv_secs = (long)tv->tv_secs; request->tr_time.tv_micro = tv->tv_micro; DoIO((struct IORequest*)request); error = delete_timer(); return error; } /**********************************************************************/ void underscore_add(char *string) { char *s = string; while (*s) { if (*s == ' ') { *s = '_'; } s++; } } void underscore_remove(char *string) { char *s = string; while (*s) { if (*s == '_') { *s = ' '; } s++; } } /**********************************************************************/