1/* 2 Copyright (c) 1990-2007 Info-ZIP. All rights reserved. 3 4 See the accompanying file LICENSE, version 2000-Apr-09 or later 5 (the contents of which are also included in unzip.h) for terms of use. 6 If, for some reason, all these files are missing, the Info-ZIP license 7 also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html 8*/ 9/*--------------------------------------------------------------------------- 10 11 tops20.c 12 13 TOPS20-specific routines for use with Info-ZIP's UnZip 5.1 and later. 14 15 Contains: mapattr() 16 close_outfile() 17 version() 18 upper() 19 enquote() 20 dequote() 21 fnlegal() 22 23 (not yet ported: do_wild(), mapname(), checkdir(), ...) 24 25 ---------------------------------------------------------------------------*/ 26 27 28#define UNZIP_INTERNAL 29#include "unzip.h" 30 31 32/**********************/ 33/* Function mapattr() */ 34/**********************/ 35 36int mapattr(__G) /* just like Unix except no umask() */ 37 __GDEF 38{ 39 ulg tmp = G.crec.external_file_attributes; 40 41 switch (G.pInfo->hostnum) { 42 case UNIX_: 43 case VMS_: 44 case ACORN_: 45 case ATARI_: 46 case ATHEOS_: 47 case BEOS_: 48 case QDOS_: 49 G.pInfo->file_attr = (unsigned)(tmp >> 16); 50 break; 51 case AMIGA_: 52 tmp = (unsigned)(tmp>>1 & 7); /* Amiga RWE bits */ 53 G.pInfo->file_attr = (unsigned)(tmp<<6 | tmp<<3 | tmp); 54 break; 55 case FS_FAT_: /* MSDOS half of attributes should always be correct */ 56 case FS_HPFS_: 57 case FS_NTFS_: 58 case MAC_: 59 case TOPS20_: 60 default: 61 tmp = !(tmp & 1) << 1; /* read-only bit --> write perms bits */ 62 G.pInfo->file_attr = (unsigned)(0444 | tmp<<6 | tmp<<3 | tmp); 63 break; 64#if 0 65 case ATARI_: 66 case TOPS20_: 67 default: 68 G.pInfo->file_attr = 0666; 69 break; 70#endif 71 } /* end switch (host-OS-created-by) */ 72 73 return 0; 74 75} /* end function mapattr() */ 76 77 78 79 80 81/****************************/ 82/* Function close_outfile() */ 83/****************************/ 84 85void close_outfile(__G) 86 __GDEF 87{ 88# define JSYS_CLASS 0070000000000 89# define FLD(val,mask) (((unsigned)(val)*((mask)&(-(mask))))&(mask)) 90# define _DEFJS(name,class) (FLD(class,JSYS_CLASS) | (monsym(name)&0777777)) 91# define IDTIM _DEFJS("IDTIM%", 1) 92# define SFTAD _DEFJS("SFTAD%", 0) 93# define YRBASE 1900 94 int ablock[5], tblock[2]; 95 int yr, mo, dy, hh, mm, ss; 96 char temp[100]; 97 unsigned tad; 98#ifdef USE_EF_UT_TIME 99 iztimes z_utime; 100 struct tm *t; 101 102 103 /* skip restoring time stamps on user's request */ 104 if (uO.D_flag <= 1) { 105 106 if (G.extra_field && 107#ifdef IZ_CHECK_TZ 108 G.tz_is_valid && 109#endif 110 (ef_scan_for_izux(G.extra_field, G.lrec.extra_field_length, 0, 111 G.lrec.last_mod_dos_date, &z_utime, NULL) 112 & EB_UT_FL_MTIME)) 113 t = localtime(&(z_utime.mtime)); 114 else 115 t = (struct tm *)NULL; 116 117 if (t != (struct tm *)NULL) 118 { 119 yr = t->tm_year + 1900; 120 mo = t->tm_mon; 121 dy = t->tm_mday; 122 hh = t->tm_hour; 123 mm = t->tm_min; 124 ss = t->tm_sec; 125 } 126 else 127 { 128 /* dissect the date */ 129 yr = ((G.lrec.last_mod_dos_date >> 9) & 0x7f) + 1980; 130 mo = ((G.lrec.last_mod_dos_date >> 5) & 0x0f) - 1; 131 dy = (G.lrec.last_mod_dos_date & 0x1f); 132 133 /* dissect the time */ 134 hh = (G.lrec.last_mod_dos_time >> 11) & 0x1f; 135 mm = (G.lrec.last_mod_dos_time >> 5) & 0x3f; 136 ss = (G.lrec.last_mod_dos_time & 0x1f) * 2; 137 } 138#else /* !USE_EF_UT_TIME */ 139 140 /* dissect the date */ 141 yr = ((G.lrec.last_mod_dos_datetime >> 25) & 0x7f) + (1980 - YRBASE); 142 mo = (G.lrec.last_mod_dos_datetime >> 21) & 0x0f; 143 dy = (G.lrec.last_mod_dos_datetime >> 16) & 0x1f; 144 145 /* dissect the time */ 146 hh = (G.lrec.last_mod_dos_datetime >> 11) & 0x1f; 147 mm = (G.lrec.last_mod_dos_datetime >> 5) & 0x3f; 148 ss = (G.lrec.last_mod_dos_datetime << 1) & 0x1f; 149#endif /* ?USE_EF_UT_TIME */ 150 151 sprintf(temp, "%02d/%02d/%02d %02d:%02d:%02d", mo, dy, yr, hh, mm, ss); 152 153 ablock[1] = (int)(temp - 1); 154 ablock[2] = 0; 155 if (!jsys(IDTIM, ablock)) { 156 Info(slide, 1, ((char *)slide, "error: IDTIM failure for %s\n", 157 G.filename)); 158 fclose(G.outfile); 159 return; 160 } 161 162 tad = ablock[2]; 163 tblock[0] = tad; 164 tblock[1] = tad; 165 tblock[2] = -1; 166 167 ablock[1] = fcntl(fileno(G.outfile), F_GETSYSFD, 0); 168 /* _uffd[outfd]->uf_ch */ 169 ablock[2] = (int) tblock; 170 ablock[3] = 3; 171 if (!jsys(SFTAD, ablock)) 172 Info(slide, 1,((char *)slide, 173 "error: cannot set the time for %s\n", G.filename)); 174 175 } /* if (uO.D_flag <= 1) */ 176 177 fclose(G.outfile); 178 179} /* end function close_outfile() */ 180 181 182 183 184 185#ifndef SFX 186 187/************************/ 188/* Function version() */ 189/************************/ 190 191void version(__G) 192 __GDEF 193{ 194#if 0 195 char buf[40]; 196#endif 197 198 sprintf((char *)slide, LoadFarString(CompiledWith), 199 200#ifdef __GNUC__ 201 "gcc ", __VERSION__, 202#else 203# if 0 204 "cc ", (sprintf(buf, " version %d", _RELEASE), buf), 205# else 206# ifdef __COMPILER_KCC__ 207 "KCC", "", 208# else 209 "unknown compiler", "", 210# endif 211# endif 212#endif 213 214 "TOPS-20", 215 216#if defined(foobar) || defined(FOOBAR) 217 " (Foo BAR)", /* OS version or hardware */ 218#else 219 "", 220#endif /* Foo BAR */ 221 222#ifdef __DATE__ 223 " on ", __DATE__ 224#else 225 "", "" 226#endif 227 ); 228 229 (*G.message)((zvoid *)&G, slide, (ulg)strlen((char *)slide), 0); 230 231} /* end function version() */ 232 233#endif /* !SFX */ 234 235 236 237 238 239/**********************/ 240/* Function upper() */ 241/**********************/ 242 243int upper(s) /* returns s in uppercase */ 244 char *s; /* string to be uppercased */ 245{ 246 for (; *s; ++s) 247 *s = toupper(*s); 248} 249 250 251 252 253 254/************************/ 255/* Function enquote() */ 256/************************/ 257 258int enquote(s) /* calls dequote(s) to normalize string, then */ 259 char *s; /* inserts ^Vs before otherwise illegal characters */ 260{ /* in s, assuming that s is a TOPS-20 filename */ 261 char d[100]; 262 char *p, *q; 263 char c; 264 265 if (s && *s) { 266 dequote(s); 267 p = s - 1; 268 q = d - 1; 269 while (c = *++p) { 270 if (!fnlegal(c)) 271 *++q = '\026'; 272 *++q = c; 273 } 274 *++q = '\0'; 275 strcpy(s, d); 276 } 277 return 0; 278} 279 280 281 282 283 284/************************/ 285/* Function dequote() */ 286/************************/ 287 288int dequote(s) /* returns s without ^Vs */ 289 char *s; /* string to be dequoted */ 290{ 291 char d[100]; 292 char *p, *q; 293 int c; 294 295 if (s && *s) { 296 p = s - 1; 297 q = d - 1; 298 while (c = *++p) 299 if (c != '\026') 300 *++q = c; 301 *++q = '\0'; 302 strcpy(s, d); 303 } 304 return 0; 305} 306 307 308 309 310 311/************************/ 312/* Function fnlegal() */ 313/************************/ 314 315int fnlegal(c) /* returns TRUE if c is a member of the */ 316 char c; /* legal character set for filenames */ 317{ 318 char *q; 319 static char *legals = {"$%**-<>>AZ[[]]__az"}; 320 321 q = legals; 322 while (*q) 323 if (c < *q++) 324 break; 325 else if (c <= *q++) 326 return TRUE; 327 328 return FALSE; 329} 330