1*099bc362Sguenther /* $OpenBSD: rcstime.c,v 1.6 2016/08/26 09:02:54 guenther Exp $ */
22dc36bedSjoris /*
32dc36bedSjoris * Copyright (c) 2006 Joris Vink <joris@openbsd.org>
42dc36bedSjoris * All rights reserved.
52dc36bedSjoris *
62dc36bedSjoris * Redistribution and use in source and binary forms, with or without
72dc36bedSjoris * modification, are permitted provided that the following conditions
82dc36bedSjoris * are met:
92dc36bedSjoris *
102dc36bedSjoris * 1. Redistributions of source code must retain the above copyright
112dc36bedSjoris * notice, this list of conditions and the following disclaimer.
122dc36bedSjoris * 2. The name of the author may not be used to endorse or promote products
132dc36bedSjoris * derived from this software without specific prior written permission.
142dc36bedSjoris *
152dc36bedSjoris * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
162dc36bedSjoris * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
172dc36bedSjoris * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
182dc36bedSjoris * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
192dc36bedSjoris * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
202dc36bedSjoris * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
212dc36bedSjoris * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
222dc36bedSjoris * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
232dc36bedSjoris * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
242dc36bedSjoris * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
252dc36bedSjoris */
262dc36bedSjoris
274781e2faSxsa #include <err.h>
284781e2faSxsa #include <stdlib.h>
294781e2faSxsa #include <string.h>
30*099bc362Sguenther #include <time.h>
312dc36bedSjoris
322dc36bedSjoris #include "rcs.h"
332dc36bedSjoris
342dc36bedSjoris void
rcs_set_tz(char * tz,struct rcs_delta * rdp,struct tm * tb)352dc36bedSjoris rcs_set_tz(char *tz, struct rcs_delta *rdp, struct tm *tb)
362dc36bedSjoris {
372dc36bedSjoris int tzone;
382dc36bedSjoris int pos;
392dc36bedSjoris char *h, *m;
405a713317Sotto const char *errstr;
412dc36bedSjoris struct tm *ltb;
422dc36bedSjoris time_t now;
432dc36bedSjoris
442dc36bedSjoris if (!strcmp(tz, "LT")) {
452dc36bedSjoris now = mktime(&rdp->rd_date);
462dc36bedSjoris ltb = localtime(&now);
472dc36bedSjoris ltb->tm_hour += ((int)ltb->tm_gmtoff/3600);
48cbab9f86Sniallo memcpy(tb, ltb, sizeof(*tb));
492dc36bedSjoris } else {
502dc36bedSjoris pos = 0;
512dc36bedSjoris switch (*tz) {
522dc36bedSjoris case '-':
532dc36bedSjoris break;
542dc36bedSjoris case '+':
552dc36bedSjoris pos = 1;
562dc36bedSjoris break;
572dc36bedSjoris default:
582dc36bedSjoris errx(1, "%s: not a known time zone", tz);
592dc36bedSjoris }
602dc36bedSjoris
612dc36bedSjoris h = (tz + 1);
622dc36bedSjoris if ((m = strrchr(tz, ':')) != NULL)
632dc36bedSjoris *(m++) = '\0';
642dc36bedSjoris
65cbab9f86Sniallo memcpy(tb, &rdp->rd_date, sizeof(*tb));
662dc36bedSjoris
675a713317Sotto tzone = strtonum(h, -23, 23, &errstr);
685a713317Sotto if (errstr)
692dc36bedSjoris errx(1, "%s: not a known time zone", tz);
702dc36bedSjoris
712dc36bedSjoris if (pos) {
722dc36bedSjoris tb->tm_hour += tzone;
732dc36bedSjoris tb->tm_gmtoff += (tzone * 3600);
742dc36bedSjoris } else {
752dc36bedSjoris tb->tm_hour -= tzone;
762dc36bedSjoris tb->tm_gmtoff -= (tzone * 3600);
772dc36bedSjoris }
782dc36bedSjoris
792dc36bedSjoris if ((tb->tm_hour >= 24) || (tb->tm_hour <= -24))
802dc36bedSjoris tb->tm_hour = 0;
812dc36bedSjoris
822dc36bedSjoris if (m != NULL) {
835a713317Sotto tzone = strtonum(m, 0, 59, &errstr);
845a713317Sotto if (errstr)
855a713317Sotto errx(1, "%s: not a known minute", m);
862dc36bedSjoris
872dc36bedSjoris if ((tb->tm_min + tzone) >= 60) {
882dc36bedSjoris tb->tm_hour++;
892dc36bedSjoris tb->tm_min -= (60 - tzone);
902dc36bedSjoris } else
912dc36bedSjoris tb->tm_min += tzone;
922dc36bedSjoris
932dc36bedSjoris tb->tm_gmtoff += (tzone*60);
942dc36bedSjoris }
952dc36bedSjoris }
962dc36bedSjoris }
97