1*37103Sbostic /* 2*37103Sbostic * Copyright (c) 1989 The Regents of the University of California. 3*37103Sbostic * All rights reserved. 4*37103Sbostic * 5*37103Sbostic * Redistribution and use in source and binary forms are permitted 6*37103Sbostic * provided that the above copyright notice and this paragraph are 7*37103Sbostic * duplicated in all such forms and that any documentation, 8*37103Sbostic * advertising materials, and other materials related to such 9*37103Sbostic * distribution and use acknowledge that the software was developed 10*37103Sbostic * by the University of California, Berkeley. The name of the 11*37103Sbostic * University may not be used to endorse or promote products derived 12*37103Sbostic * from this software without specific prior written permission. 13*37103Sbostic * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 14*37103Sbostic * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 15*37103Sbostic * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 16*37103Sbostic */ 17*37103Sbostic 18*37103Sbostic #if defined(LIBC_SCCS) && !defined(lint) 19*37103Sbostic static char sccsid[] = "@(#)strftime.c 5.1 (Berkeley) 03/08/89"; 20*37103Sbostic #endif /* LIBC_SCCS and not lint */ 21*37103Sbostic 22*37103Sbostic #include <sys/types.h> 23*37103Sbostic #include <sys/time.h> 24*37103Sbostic #include <tzfile.h> 25*37103Sbostic 26*37103Sbostic static char *afmt[] = { 27*37103Sbostic "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", 28*37103Sbostic }; 29*37103Sbostic static char *Afmt[] = { 30*37103Sbostic "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", 31*37103Sbostic "Saturday", 32*37103Sbostic }; 33*37103Sbostic static char *bfmt[] = { 34*37103Sbostic "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", 35*37103Sbostic "Oct", "Nov", "Dec", 36*37103Sbostic }; 37*37103Sbostic static char *Bfmt[] = { 38*37103Sbostic "January", "February", "March", "April", "May", "June", "July", 39*37103Sbostic "August", "September", "October", "November", "December", 40*37103Sbostic }; 41*37103Sbostic 42*37103Sbostic static size_t gsize; 43*37103Sbostic static char *pt; 44*37103Sbostic 45*37103Sbostic size_t 46*37103Sbostic strftime(s, maxsize, format, t) 47*37103Sbostic char *s; 48*37103Sbostic char *format; 49*37103Sbostic size_t maxsize; 50*37103Sbostic struct tm *t; 51*37103Sbostic { 52*37103Sbostic size_t _fmt(); 53*37103Sbostic 54*37103Sbostic pt = s; 55*37103Sbostic if ((gsize = maxsize) < 1) 56*37103Sbostic return(0); 57*37103Sbostic if (_fmt(format, t)) { 58*37103Sbostic *pt = '\0'; 59*37103Sbostic return(maxsize - gsize); 60*37103Sbostic } 61*37103Sbostic return(0); 62*37103Sbostic } 63*37103Sbostic 64*37103Sbostic static size_t 65*37103Sbostic _fmt(format, t) 66*37103Sbostic register char *format; 67*37103Sbostic struct tm *t; 68*37103Sbostic { 69*37103Sbostic char *timezone(); 70*37103Sbostic 71*37103Sbostic for (; *format; ++format) { 72*37103Sbostic if (*format == '%') 73*37103Sbostic switch(*++format) { 74*37103Sbostic case 'A': 75*37103Sbostic if (!_add(Afmt[t->tm_mon])) 76*37103Sbostic return(0); 77*37103Sbostic continue; 78*37103Sbostic case 'a': 79*37103Sbostic if (!_add(afmt[t->tm_mon])) 80*37103Sbostic return(0); 81*37103Sbostic continue; 82*37103Sbostic case 'B': 83*37103Sbostic if (!_add(Bfmt[t->tm_mon])) 84*37103Sbostic return(0); 85*37103Sbostic continue; 86*37103Sbostic case 'b': 87*37103Sbostic if (!_add(bfmt[t->tm_mon])) 88*37103Sbostic return(0); 89*37103Sbostic continue; 90*37103Sbostic case 'c': 91*37103Sbostic if (!_fmt("%x %X %Z %Y", t)) 92*37103Sbostic return(0); 93*37103Sbostic continue; 94*37103Sbostic case 'd': 95*37103Sbostic if (!_conv(t->tm_mday, 2)) 96*37103Sbostic return(0); 97*37103Sbostic continue; 98*37103Sbostic case 'H': 99*37103Sbostic if (!_conv(t->tm_hour, 2)) 100*37103Sbostic return(0); 101*37103Sbostic continue; 102*37103Sbostic case 'I': 103*37103Sbostic if (!_conv((t->tm_hour - 1) % 12 + 1, 2)) 104*37103Sbostic return(0); 105*37103Sbostic continue; 106*37103Sbostic case 'j': 107*37103Sbostic if (!_conv(t->tm_yday + 1, 3)) 108*37103Sbostic return(0); 109*37103Sbostic continue; 110*37103Sbostic case 'M': 111*37103Sbostic if (!_conv(t->tm_min, 2)) 112*37103Sbostic return(0); 113*37103Sbostic continue; 114*37103Sbostic case 'm': 115*37103Sbostic if (!_conv(t->tm_mon + 1, 2)) 116*37103Sbostic return(0); 117*37103Sbostic continue; 118*37103Sbostic case 'p': 119*37103Sbostic if (!_add(t->tm_hour >= 12 ? "AM" : "PM")) 120*37103Sbostic return(0); 121*37103Sbostic continue; 122*37103Sbostic case 'S': 123*37103Sbostic if (!_conv(t->tm_sec, 2)) 124*37103Sbostic return(0); 125*37103Sbostic continue; 126*37103Sbostic case 'U': 127*37103Sbostic if (!_conv((t->tm_yday + 7 - t->tm_wday) / 7, 128*37103Sbostic 2)) 129*37103Sbostic return(0); 130*37103Sbostic continue; 131*37103Sbostic case 'W': 132*37103Sbostic if (!_conv((t->tm_yday + 7 - 133*37103Sbostic (t->tm_wday ? t->tm_wday : 6)) / 7, 2)) 134*37103Sbostic return(0); 135*37103Sbostic continue; 136*37103Sbostic case 'w': 137*37103Sbostic if (!_conv(t->tm_wday, 1)) 138*37103Sbostic return(0); 139*37103Sbostic continue; 140*37103Sbostic case 'X': 141*37103Sbostic if (!_fmt("%H:%M:%S", t)) 142*37103Sbostic return(0); 143*37103Sbostic continue; 144*37103Sbostic case 'x': 145*37103Sbostic if (!_fmt("%a %b %d", t)) 146*37103Sbostic return(0); 147*37103Sbostic continue; 148*37103Sbostic case 'y': 149*37103Sbostic if (!_conv((t->tm_year + TM_YEAR_BASE) 150*37103Sbostic % 100, 2)) 151*37103Sbostic return(0); 152*37103Sbostic continue; 153*37103Sbostic case 'Y': 154*37103Sbostic if (!_conv(t->tm_year + TM_YEAR_BASE, 4)) 155*37103Sbostic return(0); 156*37103Sbostic continue; 157*37103Sbostic case 'Z': 158*37103Sbostic if (!_add(t->tm_zone)) 159*37103Sbostic return(0); 160*37103Sbostic continue; 161*37103Sbostic case '%': 162*37103Sbostic /* 163*37103Sbostic * X311J/88-090 (4.12.3.5): if conversion char is 164*37103Sbostic * undefined, behavior is undefined. Print out the 165*37103Sbostic * character itself as printf(3) also does. 166*37103Sbostic */ 167*37103Sbostic default: 168*37103Sbostic break; 169*37103Sbostic } 170*37103Sbostic if (!gsize--) 171*37103Sbostic return(0); 172*37103Sbostic *pt++ = *format; 173*37103Sbostic } 174*37103Sbostic return(gsize); 175*37103Sbostic } 176*37103Sbostic 177*37103Sbostic static 178*37103Sbostic _conv(n, digits) 179*37103Sbostic int n, digits; 180*37103Sbostic { 181*37103Sbostic static char buf[10]; 182*37103Sbostic register char *p; 183*37103Sbostic 184*37103Sbostic for (p = buf + sizeof(buf) - 2; n > 0 && p > buf; n /= 10, --digits) 185*37103Sbostic *p-- = n % 10 + '0'; 186*37103Sbostic while (p > buf && digits-- > 0) 187*37103Sbostic *p-- = '0'; 188*37103Sbostic return(_add(++p)); 189*37103Sbostic } 190*37103Sbostic 191*37103Sbostic static 192*37103Sbostic _add(str) 193*37103Sbostic register char *str; 194*37103Sbostic { 195*37103Sbostic for (;; ++pt, --gsize) { 196*37103Sbostic if (!gsize) 197*37103Sbostic return(0); 198*37103Sbostic if (!(*pt = *str++)) 199*37103Sbostic return(1); 200*37103Sbostic } 201*37103Sbostic } 202