1/* 2 Copyright 1999-2001, Be Incorporated. All Rights Reserved. 3 This file may be used under the terms of the Be Sample Code License. 4*/ 5 6 7#include "system_dependencies.h" 8 9#ifndef FS_SHELL 10#include <real_time_clock.h> 11#endif 12 13#include "dosfs.h" 14#include "fat.h" 15#include "util.h" 16 17static int32 tzoffset = -1; /* in minutes */ 18 19#ifdef DEBUG 20 21int 22_assert_(char *a, int b, char *c) 23{ 24 dprintf("tripped assertion in %s/%d (%s)\n", a, b, c); 25 kernel_debugger("tripped assertion"); 26 return 0; 27} 28 29#endif 30 31static void 32print_byte(uint8 c) 33{ 34 dprintf("%c", ((c >= ' ') && (c <= '~')) ? c : '.'); 35} 36 37 38void 39dump_bytes(uint8 *buffer, uint32 count) 40{ 41 uint32 i, j, k; 42 for (i = 0; i < 0x10; i++) 43 dprintf(" %" B_PRIu32 " ", i); 44 45 dprintf("\n"); 46 for (i = 0; i < count; i += 0x10) { 47 j = (i + 0x10 > count) ? count - i : 0x10; 48 for (k = i; k < i + j; k++) 49 dprintf("%2.2X ", buffer[k]); 50 for (; k < i + 0x10; k++) 51 dprintf(" "); 52 dprintf(" "); 53 for (k = i; k < i + j; k++) 54 print_byte(buffer[k]); 55 dprintf("\n"); 56 } 57} 58 59 60void 61dump_directory(uint8 *buffer) 62{ 63 dump_bytes(buffer, 32); 64} 65 66 67static void 68get_tzoffset() 69{ 70 if (tzoffset != -1) 71 return; 72 73 #ifdef FS_SHELL 74 // We just assume UTC ;-) 75 tzoffset = 0; 76 #else 77 tzoffset = get_timezone_offset() / 60; 78 #endif 79} 80 81 82// If divisible by 4, but not divisible by 100, but divisible by 400, it's a leap year 83// 1996 is leap, 1900 is not, 2000 is, 2100 is not 84#define IS_LEAP_YEAR(y) ((((y) % 4) == 0) && (((y) % 100) || ((((y)) % 400) == 0))) 85 86/* returns leap days since 1970 */ 87static int leaps(int yr, int mon) 88{ 89 // yr is 1970-based, mon 0-based 90 int result = (yr+2)/4 - (yr + 70) / 100; 91 if((yr+70) >= 100) result++; // correct for 2000 92 if (IS_LEAP_YEAR(yr + 1970)) 93 if (mon < 2) result--; 94 return result; 95} 96 97static int daze[] = { 0,0,31,59,90,120,151,181,212,243,273,304,334,0,0,0 }; 98 99time_t 100dos2time_t(uint32 t) 101{ 102 time_t days; 103 104 get_tzoffset(); 105 106 //dprintf("%d/%d/%d %d:%2.2d:%2.2d\n", 107 // (t>>25)+1980,((t>>21)&15),((t>>16)&31), 108 // (t>>11)&31,(t>>5)&63,2*(t&31)); 109 110 days = daze[(t>>21)&15] + ((t>>25)+10)*365 + leaps((t>>25)+10,((t>>21)&15)-1)+((t>>16)&31)-1; 111 112 return (((days * 24) + ((t>>11)&31)) * 60 + ((t>>5)&63) - tzoffset) * 60 + 2*(t&31); 113} 114 115 116uint32 117time_t2dos(time_t s) 118{ 119 uint32 t, d, y; 120 int days; 121 122 get_tzoffset(); 123 124 t = (s % 60) / 2; s /= 60; s += tzoffset; 125 t += (s % 60) << 5; s /= 60; 126 t += (s % 24) << 11;s /= 24; 127 128 s -= 10*365 + 2; // convert from 1970-based year to 1980-based year 129 130 for (y=0;;y++) { 131 days = IS_LEAP_YEAR(1980+y) ? 366 : 365; 132 if (s < days) break; 133 s -= days; 134 } 135 136 if (IS_LEAP_YEAR(1980+y)) { 137 if (s == 59) { 138 d = (1 << 5) + 28; /* 2/29, 0 based */ 139 goto bi; 140 } else if (s > 59) 141 s--; 142 } 143 144 for (d=0;d<11;d++) 145 if (daze[d+2] > s) 146 break; 147 d = (d << 5) + (s - daze[d+1]); 148 149bi: 150 d += (1 << 5) + 1; // make date 1-based 151 152 return t + (d << 16) + (y << 25); 153} 154 155 156uint8 157hash_msdos_name(const char *name) 158{ 159 const uint8 *p = (const uint8 *)name; 160 int i; 161 uint8 c = 0; 162 for (i=0;i<11;i++) 163 c = (c << 7) + (c >> 1) + *(p++); 164 return c; 165} 166 167 168void 169sanitize_name(char *name, int length) 170{ 171 int i; 172 173 for (i = length - 1; i > 0; i--) { 174 if (name[i] != ' ') 175 break; 176 } 177 name[i + 1] = 0; 178 for (; i >= 0; i--) { 179 if (name[i] >= 'A' && name[i] <= 'Z') 180 name[i] += 'a' - 'A'; 181 } 182} 183