xref: /netbsd-src/usr.sbin/makefs/cd9660/cd9660_conversion.c (revision 17ee9e3fb6e1bae5e93c48d0bccc7b00d4ee2fd5)
1*17ee9e3fSreinoud /*	$NetBSD: cd9660_conversion.c,v 1.6 2024/06/17 13:31:17 reinoud Exp $	*/
23550dc98Sfvdl 
33550dc98Sfvdl /*
43550dc98Sfvdl  * Copyright (c) 2005 Daniel Watt, Walter Deignan, Ryan Gabrys, Alan
53550dc98Sfvdl  * Perez-Rathke and Ram Vedam.  All rights reserved.
63550dc98Sfvdl  *
73550dc98Sfvdl  * This code was written by Daniel Watt, Walter Deignan, Ryan Gabrys,
83550dc98Sfvdl  * Alan Perez-Rathke and Ram Vedam.
93550dc98Sfvdl  *
103550dc98Sfvdl  * Redistribution and use in source and binary forms, with or
113550dc98Sfvdl  * without modification, are permitted provided that the following
123550dc98Sfvdl  * conditions are met:
133550dc98Sfvdl  * 1. Redistributions of source code must retain the above copyright
143550dc98Sfvdl  *    notice, this list of conditions and the following disclaimer.
153550dc98Sfvdl  * 2. Redistributions in binary form must reproduce the above
163550dc98Sfvdl  *    copyright notice, this list of conditions and the following
173550dc98Sfvdl  *    disclaimer in the documentation and/or other materials provided
183550dc98Sfvdl  *    with the distribution.
193550dc98Sfvdl  *
203550dc98Sfvdl  * THIS SOFTWARE IS PROVIDED BY DANIEL WATT, WALTER DEIGNAN, RYAN
213550dc98Sfvdl  * GABRYS, ALAN PEREZ-RATHKE AND RAM VEDAM ``AS IS'' AND ANY EXPRESS OR
223550dc98Sfvdl  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
233550dc98Sfvdl  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
243550dc98Sfvdl  * DISCLAIMED.  IN NO EVENT SHALL DANIEL WATT, WALTER DEIGNAN, RYAN
253550dc98Sfvdl  * GABRYS, ALAN PEREZ-RATHKE AND RAM VEDAM BE LIABLE FOR ANY DIRECT, INDIRECT,
263550dc98Sfvdl  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
273550dc98Sfvdl  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
283550dc98Sfvdl  * USE,DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
293550dc98Sfvdl  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
303550dc98Sfvdl  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
313550dc98Sfvdl  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
323550dc98Sfvdl  * OF SUCH DAMAGE.
333550dc98Sfvdl  */
343550dc98Sfvdl #include "cd9660.h"
353550dc98Sfvdl 
363550dc98Sfvdl #include <sys/cdefs.h>
373550dc98Sfvdl #if defined(__RCSID) && !defined(__lint)
38*17ee9e3fSreinoud __RCSID("$NetBSD: cd9660_conversion.c,v 1.6 2024/06/17 13:31:17 reinoud Exp $");
393550dc98Sfvdl #endif  /* !__lint */
403550dc98Sfvdl 
413550dc98Sfvdl 
423550dc98Sfvdl static char cd9660_compute_gm_offset(time_t);
433550dc98Sfvdl 
443550dc98Sfvdl #if 0
45ae6ae2c3Sperry static inline int
463550dc98Sfvdl cd9660_pad_even(length)
473550dc98Sfvdl int length;
483550dc98Sfvdl {
493550dc98Sfvdl 	return length + (length & 0x01);
503550dc98Sfvdl }
513550dc98Sfvdl #endif
523550dc98Sfvdl 
533550dc98Sfvdl /*
543550dc98Sfvdl * These can probably be implemented using a macro
553550dc98Sfvdl */
563550dc98Sfvdl 
573550dc98Sfvdl /* Little endian */
583550dc98Sfvdl void
cd9660_721(uint16_t w,unsigned char * twochar)593550dc98Sfvdl cd9660_721(uint16_t w, unsigned char *twochar)
603550dc98Sfvdl {
613550dc98Sfvdl #if BYTE_ORDER == BIG_ENDIAN
623550dc98Sfvdl 	w = bswap16(w);
633550dc98Sfvdl #endif
643550dc98Sfvdl 	memcpy(twochar,&w,2);
653550dc98Sfvdl }
663550dc98Sfvdl 
673550dc98Sfvdl void
cd9660_731(uint32_t w,unsigned char * fourchar)683550dc98Sfvdl cd9660_731(uint32_t w, unsigned char *fourchar)
693550dc98Sfvdl {
703550dc98Sfvdl #if BYTE_ORDER == BIG_ENDIAN
713550dc98Sfvdl 	w = bswap32(w);
723550dc98Sfvdl #endif
733550dc98Sfvdl 	memcpy(fourchar,&w,4);
743550dc98Sfvdl }
753550dc98Sfvdl 
763550dc98Sfvdl /* Big endian */
773550dc98Sfvdl void
cd9660_722(uint16_t w,unsigned char * twochar)783550dc98Sfvdl cd9660_722(uint16_t w, unsigned char *twochar)
793550dc98Sfvdl {
803550dc98Sfvdl #if BYTE_ORDER == LITTLE_ENDIAN
813550dc98Sfvdl 	w = bswap16(w);
823550dc98Sfvdl #endif
833550dc98Sfvdl 	memcpy(twochar,&w,2);
843550dc98Sfvdl }
853550dc98Sfvdl 
863550dc98Sfvdl void
cd9660_732(uint32_t w,unsigned char * fourchar)873550dc98Sfvdl cd9660_732(uint32_t w, unsigned char *fourchar)
883550dc98Sfvdl {
893550dc98Sfvdl #if BYTE_ORDER == LITTLE_ENDIAN
903550dc98Sfvdl 	w = bswap32(w);
913550dc98Sfvdl #endif
923550dc98Sfvdl 	memcpy(fourchar,&w,4);
933550dc98Sfvdl }
943550dc98Sfvdl 
953550dc98Sfvdl /**
963550dc98Sfvdl * Convert a dword into a double endian string of eight characters
973550dc98Sfvdl * @param int The double word to convert
983550dc98Sfvdl * @param char* The string to write the both endian double word to - It is assumed this is allocated and at least
993550dc98Sfvdl *		eight characters long
1003550dc98Sfvdl */
1013550dc98Sfvdl void
cd9660_bothendian_dword(uint32_t dw,unsigned char * eightchar)1023550dc98Sfvdl cd9660_bothendian_dword(uint32_t dw, unsigned char *eightchar)
1033550dc98Sfvdl {
1043550dc98Sfvdl 	uint32_t le, be;
1053550dc98Sfvdl #if BYTE_ORDER == LITTLE_ENDIAN
1063550dc98Sfvdl 	le = dw;
1073550dc98Sfvdl 	be = bswap32(dw);
1083550dc98Sfvdl #endif
1093550dc98Sfvdl #if BYTE_ORDER == BIG_ENDIAN
1103550dc98Sfvdl 	be = dw;
1113550dc98Sfvdl 	le = bswap32(dw);
1123550dc98Sfvdl #endif
1133550dc98Sfvdl 	memcpy(eightchar, &le, 4);
1143550dc98Sfvdl 	memcpy((eightchar+4), &be, 4);
1153550dc98Sfvdl }
1163550dc98Sfvdl 
1173550dc98Sfvdl /**
1183550dc98Sfvdl * Convert a word into a double endian string of four characters
1193550dc98Sfvdl * @param int The word to convert
1203550dc98Sfvdl * @param char* The string to write the both endian word to - It is assumed this is allocated and at least
1213550dc98Sfvdl *		four characters long
1223550dc98Sfvdl */
1233550dc98Sfvdl void
cd9660_bothendian_word(uint16_t dw,unsigned char * fourchar)1243550dc98Sfvdl cd9660_bothendian_word(uint16_t dw, unsigned char *fourchar)
1253550dc98Sfvdl {
1263550dc98Sfvdl 	uint16_t le, be;
1273550dc98Sfvdl #if BYTE_ORDER == LITTLE_ENDIAN
1283550dc98Sfvdl 	le = dw;
1293550dc98Sfvdl 	be = bswap16(dw);
1303550dc98Sfvdl #endif
1313550dc98Sfvdl #if BYTE_ORDER == BIG_ENDIAN
1323550dc98Sfvdl 	be = dw;
1333550dc98Sfvdl 	le = bswap16(dw);
1343550dc98Sfvdl #endif
1353550dc98Sfvdl 	memcpy(fourchar, &le, 2);
1363550dc98Sfvdl 	memcpy((fourchar+2), &be, 2);
1373550dc98Sfvdl }
1383550dc98Sfvdl 
1393550dc98Sfvdl void
cd9660_pad_string_spaces(char * str,int len)1403550dc98Sfvdl cd9660_pad_string_spaces(char *str, int len)
1413550dc98Sfvdl {
1423550dc98Sfvdl 	int i;
1433550dc98Sfvdl 
1443550dc98Sfvdl 	for (i = 0; i < len; i ++) {
1453550dc98Sfvdl 		if (str[i] == '\0')
1463550dc98Sfvdl 			str[i] = 0x20;
1473550dc98Sfvdl 	}
1483550dc98Sfvdl }
1493550dc98Sfvdl 
1503550dc98Sfvdl static char
cd9660_compute_gm_offset(time_t tim)1513550dc98Sfvdl cd9660_compute_gm_offset(time_t tim)
1523550dc98Sfvdl {
153683c28c5Schristos 	if (stampst.st_ino)
154683c28c5Schristos 		return 0;
155683c28c5Schristos 
156a516872cSchristos 	struct tm t, gm;
1573550dc98Sfvdl 
158a516872cSchristos 	(void)localtime_r(&tim, &t);
159a516872cSchristos 	(void)gmtime_r(&tim, &gm);
160a516872cSchristos 	gm.tm_year -= t.tm_year;
161a516872cSchristos 	gm.tm_yday -= t.tm_yday;
162a516872cSchristos 	gm.tm_hour -= t.tm_hour;
163a516872cSchristos 	gm.tm_min  -= t.tm_min;
164a516872cSchristos 	if (gm.tm_year < 0)
165a516872cSchristos 		gm.tm_yday = -1;
166a516872cSchristos 	else if (gm.tm_year > 0)
167a516872cSchristos 		gm.tm_yday = 1;
1683550dc98Sfvdl 
169a516872cSchristos 	return (char)(-(gm.tm_min + 60* (24 * gm.tm_yday + gm.tm_hour)) / 15);
1703550dc98Sfvdl }
1713550dc98Sfvdl 
1723550dc98Sfvdl /* Long dates: 17 characters */
1733550dc98Sfvdl void
cd9660_time_8426(unsigned char * buf,time_t tim)1743550dc98Sfvdl cd9660_time_8426(unsigned char *buf, time_t tim)
1753550dc98Sfvdl {
176a516872cSchristos 	struct tm t;
177*17ee9e3fSreinoud 	char temp[70];	/* we know its only 18 but gcc can't figure this out */
1783550dc98Sfvdl 
179683c28c5Schristos 	if (stampst.st_ino)
180683c28c5Schristos 		(void)gmtime_r(&tim, &t);
181683c28c5Schristos 	else
182a516872cSchristos 		(void)localtime_r(&tim, &t);
183a516872cSchristos 	(void)snprintf(temp, sizeof(temp), "%04i%02i%02i%02i%02i%02i%02i",
184a516872cSchristos 		1900+(int)t.tm_year,
185a516872cSchristos 		(int)t.tm_mon+1,
186a516872cSchristos 		(int)t.tm_mday,
187a516872cSchristos 		(int)t.tm_hour,
188a516872cSchristos 		(int)t.tm_min,
189a516872cSchristos 		(int)t.tm_sec,
1903550dc98Sfvdl 		0);
191a516872cSchristos 	(void)memcpy(buf, temp, 16);
1923550dc98Sfvdl 	buf[16] = cd9660_compute_gm_offset(tim);
1933550dc98Sfvdl }
1943550dc98Sfvdl 
1953550dc98Sfvdl /* Short dates: 7 characters */
1963550dc98Sfvdl void
cd9660_time_915(unsigned char * buf,time_t tim)1973550dc98Sfvdl cd9660_time_915(unsigned char *buf, time_t tim)
1983550dc98Sfvdl {
199a516872cSchristos 	struct tm t;
2003550dc98Sfvdl 
201683c28c5Schristos 	if (stampst.st_ino)
202683c28c5Schristos 		(void)gmtime_r(&tim, &t);
203683c28c5Schristos 	else
204a516872cSchristos 		(void)localtime_r(&tim, &t);
205a516872cSchristos 	buf[0] = t.tm_year;
206a516872cSchristos 	buf[1] = t.tm_mon+1;
207a516872cSchristos 	buf[2] = t.tm_mday;
208a516872cSchristos 	buf[3] = t.tm_hour;
209a516872cSchristos 	buf[4] = t.tm_min;
210a516872cSchristos 	buf[5] = t.tm_sec;
2113550dc98Sfvdl 	buf[6] = cd9660_compute_gm_offset(tim);
2123550dc98Sfvdl }
213