⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mread.c

📁 MTOOLS version 2.0 Mtools is a public domain collection of programs to allow Unix systems t
💻 C
字号:
/* * Read (copy) an MSDOS file to Unix * * Emmet P. Gray			US Army, HQ III Corps & Fort Hood * ...!uunet!uiucuxc!fthood!egray	Attn: AFZF-DE-ENV * fthood!egray@uxc.cso.uiuc.edu	Directorate of Engineering & Housing * 					Environmental Management Office * 					Fort Hood, TX 76544-5057 */#define LOWERCASE#include <stdio.h>#include <ctype.h>#include <sys/types.h>#include <sys/stat.h>#ifdef BSD#include <sys/time.h>#else /* BSD */#include <time.h>#endif /* BSD */#include "msdos.h"#include "patchlevel.h"int fd = -1;				/* the file descriptor for the device */int dir_start;				/* starting sector for directory */int dir_len;				/* length of directory (in sectors) */int dir_entries;			/* number of directory entries */int clus_size;				/* cluster size (in sectors) */char *mcwd;				/* the Current Working Directory */int fat_error;				/* FAT error detected? */static void set_mtime();static FILE *open_file();static long conv_stamp();main(argc, argv)int argc;char *argv[];{	FILE *fp;	extern int optind;	extern char *optarg;	int i, ismatch, entry, single, c, oops, preserve, nowarn, textmode;	int got_one, missed_one;	unsigned int fat;	long size, mtime;	char *filename, *newfile, *get_name(), *unix_name(), *pathname;	char *get_path(), *target, tmp[MAX_PATH], *strcat(), *strcpy(), drive;	char get_drive(), last_drive, *fix_mcwd(), *s;	void exit();	struct directory *dir, *dir_read();	struct stat stbuf;					/* get command line options */	oops = 0;	preserve = 0;	nowarn = 0;	textmode = 0;	got_one = 0;	missed_one = 0;	while ((c = getopt(argc, argv, "tnmv")) != EOF) {		switch (c) {			case 't':				textmode = 1;				break;			case 'n':				nowarn = 1;				break;			case 'm':				preserve = 1;				break;			case 'v':	/* dummy option for mcopy */				break;			default:				oops = 1;				break;		}	}	if (oops || (argc - optind) < 2) {		fprintf(stderr, "Mtools version %s, dated %s\n", VERSION, DATE);		fprintf(stderr, "Usage: %s [-tnm] msdosfile unixfile\n", argv[0]);		fprintf(stderr, "       %s [-tnm] msdosfile [msdosfiles...] unixdirectory\n", argv[0]);		exit(1);	}	last_drive = 'x';	mcwd = fix_mcwd();					/* only 1 file to copy... */	single = 1;	target = argv[argc - 1];					/* ...unless last arg is a directory */	if (!stat(target, &stbuf)) {		if ((stbuf.st_mode & S_IFMT) == S_IFDIR)			single = 0;	}					/* too many arguments */	if (single && (argc - optind) != 2) {		fprintf(stderr, "%s: Too many arguments or destination directory omitted\n", argv[0]);		exit(1);	}	for (i = optind; i < argc - 1; i++) {		drive = get_drive(argv[i]);		if (drive != last_drive) {			if (init(drive, 0)) {				fprintf(stderr, "%s: Cannot initialize '%c:'\n", argv[0], drive);				missed_one++;				continue;			}			last_drive = drive;		}		filename = get_name(argv[i]);		pathname = get_path(argv[i]);		if (subdir(drive, pathname)) {			missed_one++;			continue;		}		ismatch = 0;		for (entry = 0; entry < dir_entries; entry++) {			dir = dir_read(entry);					/* if empty */			if (dir->name[0] == 0x0)				break;					/* if erased */			if (dir->name[0] == 0xe5)				continue;					/* if dir or volume label */			if ((dir->attr & 0x10) || (dir->attr & 0x08))				continue;			newfile = unix_name(dir->name, dir->ext);					/* if single file */			if (single) {				if (!strcmp(newfile, filename)) {					fat = dir->start[1] * 0x100 + dir->start[0];					size = dir->size[3] * 0x1000000L + dir->size[2] * 0x10000L + dir->size[1] * 0x100 + dir->size[0];					if (preserve)						mtime = conv_stamp(dir->time, dir->date);					else						mtime = 0L;					if ((fp = open_file(target, nowarn))) {						if (file_read(fp, fat, textmode, 0, size)) {							fclose(fp);							missed_one++;							break;						}						fclose(fp);						set_mtime(target, mtime);						ismatch = 1;						got_one++;					}					else						missed_one++;					break;				}			}					/* if multiple files */			else {				if (match(newfile, filename)) {					fat = dir->start[1] * 0x100 + dir->start[0];					size = dir->size[3] * 0x1000000L + dir->size[2] * 0x10000L + dir->size[1] * 0x100 + dir->size[0];					if (preserve)						mtime = conv_stamp(dir->time, dir->date);					else						mtime = 0L;					printf("Copying %s\n", newfile);#ifdef LOWERCASE					s = newfile;					while (*s) {						if (isupper(*s))							*s = tolower(*s);						s++;					}#endif /* LOWERCASE */					strcpy(tmp, target);					strcat(tmp, "/");					strcat(tmp, newfile);					if ((fp = open_file(tmp, nowarn))) {						if (file_read(fp, fat, textmode, 0, size)) {							fclose(fp);							missed_one++;							break;						}						fclose(fp);						set_mtime(tmp, mtime);						ismatch = 1;						got_one++;					}					else						missed_one++;				}			}		}		if (fat_error) {			missed_one++;			break;		}		if (!ismatch) {			fprintf(stderr, "%s: File \"%s\" not found\n", argv[0], filename);			missed_one++;		}	}	close(fd);	if (got_one && missed_one)		exit(2);	if (missed_one)		exit(1);	exit(0);}/* * Open the named Unix file for write. */static FILE *open_file(target, nowarn)char *target;int nowarn;{	static FILE *fp;	char ans[10];	struct stat stbuf;	if (!nowarn) {		if (!access(target, 0)) {			/* CONSTCOND */			while (1) {				printf("File \"%s\" exists, overwrite (y/n) ? ", target);				gets(ans);				if (ans[0] == 'n' || ans[0] == 'N')					return(NULL);				if (ans[0] == 'y' || ans[0] == 'Y')					break;			}					/* sanity checking */			if (!stat(target, &stbuf)) {				if ((stbuf.st_mode & S_IFREG) != S_IFREG) {					fprintf(stderr, "\"%s\" is not a regular file\n", target);					return(NULL);				}			}		}	}	if (!(fp = fopen(target, "w"))) {		fprintf(stderr, "Can't open \"%s\" for write\n", target);		return(NULL);	}	return(fp);}/* * Convert an MSDOS time & date stamp to the Unix time() format */static longconv_stamp(time_field, date_field)unsigned char *time_field, *date_field;{#ifdef BSD	struct timeval tv;	struct timezone tz;#else /* BSD */	extern long timezone;	void tzset();#endif /* BSD */	struct tm *tmbuf, *localtime();	int year, mon, mday, hour, min, sec, old_leaps;	long answer, sec_year, sec_mon, sec_mday, sec_hour, sec_min, sec_leap;	long tzone, dst;	static int month[] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304,	334};					/* dissect the parts */	year = (date_field[1] >> 1) + 1980;	mon = (((date_field[1] & 0x1) << 3) + (date_field[0] >> 5));	mday = date_field[0] & 0x1f;	hour = time_field[1] >> 3;	min = (((time_field[1] & 0x7) << 3) + (time_field[0] >> 5));	sec = (time_field[0] & 0x1f) * 2;					/* how many previous leap years */	old_leaps = (year - 1972) / 4L;	sec_leap = old_leaps * 24L * 60L * 60L;					/* back off 1 day if before 29 Feb */	if (!(year % 4) && mon < 3)		sec_leap -= 24L * 60L * 60L;	sec_year = (year - 1970) * 365L * 24L * 60L * 60L;	sec_mon = month[mon - 1] * 24L * 60L * 60L;	sec_mday = mday * 24L * 60L * 60L;	sec_hour = hour * 60L * 60L;	sec_min = min * 60L;					/* correct for Time Zone */#ifdef BSD	gettimeofday(&tv, &tz);	tzone = tz.tz_minuteswest * 60L;#else /* BSD */	tzset();	tzone = timezone;#endif /* BSD */	answer = sec_leap + sec_year + sec_mon + sec_mday + sec_hour + sec_min + sec + tzone;					/* correct for Daylight Saving Time */	tmbuf = localtime(&answer);	dst = (tmbuf->tm_isdst) ? (-60L * 60L) : 0L;	answer += dst;		return(answer);}/* * Preserve the file modification times after the fclose() */static voidset_mtime(target, mtime)char *target;long mtime;{#ifdef BSD	struct timeval tv[2];	if (mtime != 0L) {		tv[0].tv_sec = mtime;		tv[0].tv_usec = 0;		tv[1].tv_sec = mtime;		tv[1].tv_usec = 0;		utimes(target, tv);	}#else /* BSD */	struct {		time_t actime;		time_t modtime;	} utbuf;	if (mtime != 0L) {		utbuf.actime = mtime;		utbuf.modtime = mtime;		utime(target, &utbuf);	}#endif /* BSD */	return;}/* * stubs for read-only programs */voiddisk_flush(){	extern int disk_dirty;	disk_dirty = 0;	return;}voiddir_flush(){	extern int dir_dirty;	dir_dirty = 0;	return;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -