📄 msdos.c
字号:
/* The following DOS date/time structure is machine-dependent as it * assumes "little-endian" byte order. For MSDOS-specific code, which * is run on ix86 CPUs (or emulators), this assumption is valid; but * care should be taken when using this code as template for other ports. */typedef union { ulg z_dostime;# ifdef __TURBOC__ struct ftime ft; /* system file time record */# endif struct { /* date and time words */ ush ztime; /* DOS file modification time word */ ush zdate; /* DOS file modification date word */ } zft; struct { /* DOS date/time components bitfield */ unsigned zt_se : 5; unsigned zt_mi : 6; unsigned zt_hr : 5; unsigned zd_dy : 5; unsigned zd_mo : 4; unsigned zd_yr : 7; } z_dtf;} dos_fdatetime;#endif /* USE_EF_UT_TIME || TIMESTAMP *//****************************//* Function close_outfile() *//****************************/void close_outfile(__G) __GDEF /* * MS-DOS VERSION * * Set the output file date/time stamp according to information from the * zipfile directory record for this member, then close the file and set * its permissions (archive, hidden, read-only, system). Aside from closing * the file, this routine is optional (but most compilers support it). */{#ifdef USE_EF_UT_TIME dos_fdatetime dos_dt; iztimes z_utime; struct tm *t;#endif /* USE_EF_UT_TIME *//*--------------------------------------------------------------------------- Copy and/or convert time and date variables, if necessary; then set the file time/date. WEIRD BORLAND "BUG": if output is buffered, and if run under at least some versions of DOS (e.g., 6.0), and if files are smaller than DOS physical block size (i.e., 512 bytes) (?), then files MAY NOT get timestamped correctly--apparently setftime() occurs before any data are written to the file, and when file is closed and buffers are flushed, timestamp is overwritten with current time. Even with a 32K buffer, this does not seem to occur with larger files. UnZip output is now unbuffered, but if it were not, could still avoid problem by adding "fflush(outfile)" just before setftime() call. Weird, huh? ---------------------------------------------------------------------------*/#ifdef USE_EF_UT_TIME if (G.extra_field &&#ifdef IZ_CHECK_TZ G.tz_is_valid &&#endif (ef_scan_for_izux(G.extra_field, G.lrec.extra_field_length, 0, G.lrec.last_mod_dos_datetime, &z_utime, NULL) & EB_UT_FL_MTIME)) { TTrace((stderr, "close_outfile: Unix e.f. modif. time = %ld\n", z_utime.mtime)); /* round up (down if "up" overflows) to even seconds */ if (z_utime.mtime & 1) z_utime.mtime = (z_utime.mtime + 1 > z_utime.mtime) ? z_utime.mtime + 1 : z_utime.mtime - 1; TIMET_TO_NATIVE(z_utime.mtime) /* NOP unless MSC 7.0 or Macintosh */ t = localtime(&(z_utime.mtime)); } else t = (struct tm *)NULL; if (t != (struct tm *)NULL) { if (t->tm_year < 80) { dos_dt.z_dtf.zt_se = 0; dos_dt.z_dtf.zt_mi = 0; dos_dt.z_dtf.zt_hr = 0; dos_dt.z_dtf.zd_dy = 1; dos_dt.z_dtf.zd_mo = 1; dos_dt.z_dtf.zd_yr = 0; } else { dos_dt.z_dtf.zt_se = t->tm_sec >> 1; dos_dt.z_dtf.zt_mi = t->tm_min; dos_dt.z_dtf.zt_hr = t->tm_hour; dos_dt.z_dtf.zd_dy = t->tm_mday; dos_dt.z_dtf.zd_mo = t->tm_mon + 1; dos_dt.z_dtf.zd_yr = t->tm_year - 80; } } else { dos_dt.z_dostime = G.lrec.last_mod_dos_datetime; }# ifdef __TURBOC__ setftime(fileno(G.outfile), &dos_dt.ft);# else _dos_setftime(fileno(G.outfile), dos_dt.zft.zdate, dos_dt.zft.ztime);# endif#else /* !USE_EF_UT_TIME */# ifdef __TURBOC__ setftime(fileno(G.outfile), (struct ftime *)(&(G.lrec.last_mod_dos_datetime)));# else _dos_setftime(fileno(G.outfile), (ush)(G.lrec.last_mod_dos_datetime >> 16), (ush)(G.lrec.last_mod_dos_datetime));# endif#endif /* ?USE_EF_UT_TIME *//*--------------------------------------------------------------------------- And finally we can close the file...at least everybody agrees on how to do *this*. I think... Also change the mode according to the stored file attributes, since we didn't do that when we opened the dude. ---------------------------------------------------------------------------*/ fclose(G.outfile); z_dos_chmod(__G__ G.filename, G.pInfo->file_attr);} /* end function close_outfile() */#ifdef TIMESTAMP/*************************//* Function stamp_file() *//*************************/int stamp_file(fname, modtime) ZCONST char *fname; time_t modtime;{ dos_fdatetime dos_dt; time_t t_even; struct tm *t; int fd; /* file handle */ /* round up (down if "up" overflows) to even seconds */ t_even = ((modtime + 1 > modtime) ? modtime + 1 : modtime) & (~1); TIMET_TO_NATIVE(t_even) /* NOP unless MSC 7.0 or Macintosh */ t = localtime(&t_even); if (t == (struct tm *)NULL) return -1; /* time conversion error */ if (t->tm_year < 80) { dos_dt.z_dtf.zt_se = 0; dos_dt.z_dtf.zt_mi = 0; dos_dt.z_dtf.zt_hr = 0; dos_dt.z_dtf.zd_dy = 1; dos_dt.z_dtf.zd_mo = 1; dos_dt.z_dtf.zd_yr = 0; } else { dos_dt.z_dtf.zt_se = t->tm_sec >> 1; dos_dt.z_dtf.zt_mi = t->tm_min; dos_dt.z_dtf.zt_hr = t->tm_hour; dos_dt.z_dtf.zd_dy = t->tm_mday; dos_dt.z_dtf.zd_mo = t->tm_mon + 1; dos_dt.z_dtf.zd_yr = t->tm_year - 80; } if (((fd = open((char *)fname, 0)) == -1) ||# ifdef __TURBOC__ (setftime(fd, &dos_dt.ft)))# else (_dos_setftime(fd, dos_dt.zft.zdate, dos_dt.zft.ztime)))# endif { if (fd != -1) close(fd); return -1; } close(fd); return 0;} /* end function stamp_file() */#endif /* TIMESTAMP */#ifndef SFX/*************************//* Function dateformat() *//*************************/int dateformat(){/*--------------------------------------------------------------------------- For those operating systems that support it, this function returns a value that tells how national convention says that numeric dates are displayed. Return values are DF_YMD, DF_DMY and DF_MDY (the meanings should be fairly obvious). ---------------------------------------------------------------------------*/#ifndef WINDLL ush CountryInfo[18];#if (!defined(__GO32__) && !defined(__EMX__)) ush far *_CountryInfo = CountryInfo; struct SREGS sregs; union REGS regs;#ifdef WATCOMC_386 ush seg, para; memset(&sregs, 0, sizeof(sregs)); memset(®s, 0, sizeof(regs)); /* PMODE/W does not support an extended version of dos function 38, */ /* so we have to use brute force, allocating real mode memory for it. */ regs.w.ax = 0x0100; regs.w.bx = 3; /* 36 bytes rounds up to 48 */ int386(0x31, ®s, ®s); /* DPMI allocate DOS memory */ if (regs.w.cflag) return DF_MDY; /* no memory, return default */ seg = regs.w.dx; para = regs.w.ax;#ifdef XXX__MK_FP_IS_BROKEN /* XXX This code may not be trustworthy in general, though it is * valid with DOS/4GW and PMODE/w, which is all we support for now. */ /* _CountryInfo = (ush far *) (para << 4); */ /* works for some extenders */ regs.w.ax = 6; regs.w.bx = seg; int386(0x31, ®s, ®s); /* convert seg to linear address */ _CountryInfo = (ush far *) (((ulg) regs.w.cx << 16) | regs.w.dx);#else _CountryInfo = (ush far *) MK_FP(seg, 0);#endif sregs.ds = para; /* real mode paragraph */ regs.w.dx = 0; /* no offset from segment */ regs.w.ax = 0x3800; int86x_realmode(0x21, ®s, ®s, &sregs); CountryInfo[0] = regs.w.cflag ? 0 : _CountryInfo[0]; regs.w.ax = 0x0101; regs.w.dx = seg; int386(0x31, ®s, ®s); /* DPMI free DOS memory */#else /* !WATCOMC_386 */ sregs.ds = FP_SEG(_CountryInfo); regs.x.dx = FP_OFF(_CountryInfo); regs.x.ax = 0x3800; intdosx(®s, ®s, &sregs);#endif /* ?WATCOMC_386 */#else /* __GO32__ || __EMX__ */ _dos_getcountryinfo(CountryInfo);#endif /* ?(__GO32__ || __EMX__) */ switch(CountryInfo[0]) { case 0: return DF_MDY; case 1: return DF_DMY; case 2: return DF_YMD; }#endif /* !WINDLL && !WATCOMC_386 */ return DF_MDY; /* default for systems without locale info */} /* end function dateformat() */#ifndef WINDLL/************************//* Function version() *//************************/void version(__G) __GDEF{ int len;#if defined(__DJGPP__) || defined(__WATCOMC__) || \ (defined(_MSC_VER) && (_MSC_VER != 800)) char buf[80];#endif len = sprintf((char *)slide, LoadFarString(CompiledWith),#if defined(__GNUC__)# if defined(__DJGPP__) (sprintf(buf, "djgpp v%d.%02d / gcc ", __DJGPP__, __DJGPP_MINOR__), buf),# elif defined(__GO32__) /* __GO32__ is defined as "1" only (sigh) */ "djgpp v1.x / gcc ",# elif defined(__EMX__) /* ...so is __EMX__ (double sigh) */ "emx+gcc ",# else "gcc ",# endif __VERSION__,#elif defined(__WATCOMC__)# if (__WATCOMC__ % 10 != 0) "Watcom C/C++", (sprintf(buf, " %d.%02d", __WATCOMC__ / 100, __WATCOMC__ % 100), buf),# else "Watcom C/C++", (sprintf(buf, " %d.%d", __WATCOMC__ / 100, (__WATCOMC__ % 100) / 10), buf),# endif#elif defined(__TURBOC__)# ifdef __BORLANDC__ "Borland C++",# if (__BORLANDC__ < 0x0200) " 1.0",# elif (__BORLANDC__ == 0x0200) /* James: __TURBOC__ = 0x0297 */ " 2.0",# elif (__BORLANDC__ == 0x0400) " 3.0",# elif (__BORLANDC__ == 0x0410) /* __BCPLUSPLUS__ = 0x0310 */ " 3.1",# elif (__BORLANDC__ == 0x0452) /* __BCPLUSPLUS__ = 0x0320 */ " 4.0 or 4.02",# elif (__BORLANDC__ == 0x0460) /* __BCPLUSPLUS__ = 0x0340 */ " 4.5",# elif (__BORLANDC__ == 0x0500) " 5.0",# else " later than 5.0",# endif# else "Turbo C",# if (__TURBOC__ > 0x0401) /* Kevin: 3.0 -> 0x0401 */ "++ later than 3.0",# elif (__TURBOC__ >= 0x0400) "++ 3.0",# elif (__TURBOC__ >= 0x0297) /* see remark for Borland C++ 2.0 */ "++ 2.0",# elif (__TURBOC__ == 0x0296) /* [662] checked by SPC */ "++ 1.01",# elif (__TURBOC__ == 0x0295) /* [661] vfy'd by Kevin */ "++ 1.0",# elif (__TURBOC__ == 0x0201) /* Brian: 2.01 -> 0x0201 */ " 2.01",# elif ((__TURBOC__ >= 0x018d) && (__TURBOC__ <= 0x0200)) /* James: 0x0200 */ " 2.0",# elif (__TURBOC__ > 0x0100) " 1.5", /* James: 0x0105? */# else " 1.0", /* James: 0x0100 */# endif# endif#elif defined(MSC)# if defined(_QC) && !defined(_MSC_VER) "MS Quick C ", "2.0 or earlier", /* _QC is defined as 1 */# elif defined(_QC) && (_MSC_VER == 600) "MS Quick C ", "2.5 (MSC 6.00)",# else "Microsoft C ",# ifdef _MSC_VER# if (_MSC_VER == 800) "8.0
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -