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

📄 dosread.c

📁 操作系统源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
  do {	disk_io(READ, clus_add(cl_no), buffer, cluster_size);	rest = (entry->d_size > (long) cluster_size) ? cluster_size : (short) entry->d_size;	if (Aflag) {		for (i = 0; i < rest; i ++) {			if (buffer [i] != '\r') putchar (buffer [i]);		}		if (ferror (stdout)) {			fprintf (stderr, "%s: cannot write to stdout: %s\n",				 cmnd, strerror (errno));			exit (1);		}	} else {		if (fwrite (buffer, 1, rest, stdout) != rest) {			fprintf (stderr, "%s: cannot write to stdout: %s\n",				 cmnd, strerror (errno));			exit (1);		}	}	entry->d_size -= (long) rest;	cl_no = next_cluster(cl_no);	if (cl_no == BAD16) {		fflush (stdout);		fprintf (stderr, "%s: reserved cluster value %x encountered.\n",			 cmnd, cl_no);		exit (1);	}  } while (entry->d_size && cl_no != LAST_CLUSTER);  if (cl_no != LAST_CLUSTER)	fprintf (stderr, "%s: Too many clusters allocated for file.\n", cmnd);  else if (entry->d_size != 0)	fprintf (stderr, "%s: Premature EOF: %ld bytes left.\n", cmnd,		     entry->d_size);}/* Minimum of two long values */long lmin (a, b)long a, b;{	if (a < b) return a;	else return b;}void make_file(dir_ptr, entries, name)DIRECTORY *dir_ptr;int entries;char *name;{  register DIRECTORY *entry = new_entry(dir_ptr, entries);  register char *ptr;  char buffer[MAX_CLUSTER_SIZE];  unsigned short cl_no = 0;  int i, r;  long size = 0L;  unsigned short first_cluster, last_cluster;  long chunk;  memset (&entry->d_name[0], ' ', 11);    /* clear entry */  for (i = 0, ptr = name; i < 8 && *ptr != '.' && *ptr; i++)	entry->d_name[i] = *ptr++;  while (*ptr != '.' && *ptr) ptr++;  if (*ptr == '.') ptr++;  for (i = 0; i < 3 && *ptr != '.' && *ptr; i++) entry->d_ext[i] = *ptr++;  for (i = 0; i < 10; i++) entry->d_reserved[i] = '\0';  entry->d_attribute = '\0';  entry->d_cluster = 0;  while (free_range (&first_cluster, &last_cluster)) {	do {		unsigned short	nr_clus;		chunk = lmin ((long) (last_cluster - first_cluster + 1) *			     		  cluster_size,			      (long) MAX_CLUSTER_SIZE);		r = fill(buffer, chunk);		if (r == 0) goto done;		nr_clus = (r + cluster_size - 1) / cluster_size;		disk_io(WRITE, clus_add(first_cluster), buffer, r);		for (i = 0; i < nr_clus; i ++) {			if (entry->d_cluster == 0)				cl_no = entry->d_cluster = first_cluster;			else {				link_fat(cl_no, first_cluster);				cl_no = first_cluster;			}			first_cluster ++;		}		size += r;	} while (first_cluster <= last_cluster);  }  fprintf (stderr, "%s: disk full. File truncated\n", cmnd);done:  if (entry->d_cluster != 0) link_fat(cl_no, LAST_CLUSTER);  entry->d_size = size;  fill_date(entry);  disk_io(WRITE, mark, entry, DIR_SIZE);  if (fat_dirty) flush_fat ();}#define SEC_MIN	60L#define SEC_HOUR	(60L * SEC_MIN)#define SEC_DAY	(24L * SEC_HOUR)#define SEC_YEAR	(365L * SEC_DAY)#define SEC_LYEAR	(366L * SEC_DAY)unsigned short mon_len[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};void fill_date(entry)DIRECTORY *entry;{  register long cur_time = time((long *) 0) - DOS_TIME;  unsigned short year = 0, month = 1, day, hour, minutes, seconds;  int i;  long tmp;  if (cur_time < 0)		/* Date not set on booting ... */	cur_time = 0;  for (;;) {	tmp = (year % 4 == 0) ? SEC_LYEAR : SEC_YEAR;	if (cur_time < tmp) break;	cur_time -= tmp;	year++;  }  day = (unsigned short) (cur_time / SEC_DAY);  cur_time -= (long) day *SEC_DAY;  hour = (unsigned short) (cur_time / SEC_HOUR);  cur_time -= (long) hour *SEC_HOUR;  minutes = (unsigned short) (cur_time / SEC_MIN);  cur_time -= (long) minutes *SEC_MIN;  seconds = (unsigned short) cur_time;  mon_len[1] = (year % 4 == 0) ? 29 : 28;  i = 0;  while (day >= mon_len[i]) {	month++;	day -= mon_len[i++];  }  day++;  entry->d_date = (year << 9) | (month << 5) | day;  entry->d_time = (hour << 11) | (minutes << 5) | seconds;}char *make_name(dir_ptr, dir_fl)register DIRECTORY *dir_ptr;short dir_fl;{  static char name_buf[14];  register char *ptr = name_buf;  short i;  for (i = 0; i < 8; i++) *ptr++ = dir_ptr->d_name[i];  while (*--ptr == ' ');  assert (ptr >= name_buf);  ptr++;  if (dir_ptr->d_ext[0] != ' ') {	*ptr++ = '.';	for (i = 0; i < 3; i++) *ptr++ = dir_ptr->d_ext[i];	while (*--ptr == ' ');	ptr++;  }  if (dir_fl) *ptr++ = '/';  *ptr = '\0';  return name_buf;}int fill(buffer, size)register char *buffer;size_t	size;{  static BOOL nl_mark = FALSE;  char *last = &buffer[size];  char *begin = buffer;  register int c;  while (buffer < last) {  	if (nl_mark) {  		*buffer ++ = '\n';  		nl_mark = FALSE;  	} else {		c = getchar();		if (c == EOF) break;		if (Aflag && c == '\n') {			*buffer ++ = '\r';			nl_mark = TRUE;		} else {			*buffer++ = c;		}	}  }  return (buffer - begin);}#define HOUR	0xF800		/* Upper 5 bits */#define MIN	0x07E0		/* Middle 6 bits */#define YEAR	0xFE00		/* Upper 7 bits */#define MONTH	0x01E0		/* Mid 4 bits */#define DAY	0x01F		/* Lowest 5 bits */char *month[] = {	 "Jan", "Feb", "Mar", "Apr", "May", "Jun",	 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};void xmodes(mode)int mode;{  printf ( "\t%c%c%c%c%c", (mode & SUB_DIR) ? 'd' : '-',	     (mode & 02) ? 'h' : '-', (mode & 04) ? 's' : '-',	     (mode & 01) ? '-' : 'w', (mode & 0x20) ? 'a' : '-');}void show(dir_ptr, name)DIRECTORY *dir_ptr;char *name;{  register unsigned short e_date = dir_ptr->d_date;  register unsigned short e_time = dir_ptr->d_time;  unsigned short next;  char bname[20];  short i = 0;  while (*name && *name != '/') bname[i++] = *name++;  bname[i] = '\0';  if (!Lflag) {	printf ( "%s\n", bname);	return;  }  xmodes( (int) dir_ptr->d_attribute);  printf ( "\t%s%s", bname, strlen(bname) < 8 ? "\t\t" : "\t");  i = 1;  if (is_dir(dir_ptr)) {	next = dir_ptr->d_cluster;	while ((next = next_cluster(next)) != LAST_CLUSTER) i++;	printf ("%8ld", (long) i * (long) cluster_size);  } else	printf ("%8ld", dir_ptr->d_size);  printf (" %02d:%02d %2d %s %d\n", ((e_time & HOUR) >> 11),	     ((e_time & MIN) >> 5), (e_date & DAY),   month[((e_date & MONTH) >> 5) - 1], ((e_date & YEAR) >> 9) + 1980);}void free_blocks(){  register unsigned short cl_no;  long nr_free = 0;  long nr_bad = 0;  for (cl_no = 2; cl_no < total_clusters; cl_no++) {	switch (next_cluster(cl_no)) {	    case FREE:	nr_free++;	break;	    case BAD16:	nr_bad++;	break;	}  }  printf ("Free space: %ld bytes.\n", nr_free * (long) cluster_size);  if (nr_bad != 0)	printf ("Bad sectors: %ld bytes.\n", nr_bad * (long) cluster_size);}DIRECTORY *read_cluster(cluster)register unsigned int cluster;{  register DIRECTORY *sub_dir;  if ((sub_dir = malloc(cluster_size)) == NULL) {	fprintf (stderr, "%s: Cannot set break!\n", cmnd);	exit(1);  }  disk_io(READ, clus_add(cluster), sub_dir, cluster_size);  return sub_dir;}static unsigned short cl_index = 2;/* find a range of consecutive free clusters. Return TRUE if found * and return the first and last cluster in the |*first| and |*last|. * If no free clusters are left, return FALSE. * * Warning: Assumes that all of the range is used before the next call *	to free_range or free_cluster. */BOOL free_range (first, last)unsigned short *first, *last;{  while (cl_index < total_clusters && next_cluster(cl_index) != FREE)	cl_index++;  if (cl_index >= total_clusters) return FALSE;  *first = cl_index;  while (cl_index < total_clusters && next_cluster(cl_index) == FREE)	cl_index++;  *last = cl_index - 1;  return TRUE;}/* find a free cluster. * Return the number of the free cluster or a number > |total_clusters| * if none is found. * If |leave_fl| is TRUE, the the program will be terminated if  * no free cluster can be found * * Warning: Assumes that the cluster is used before the next call *	to free_range or free_cluster. */unsigned short free_cluster(leave_fl)BOOL leave_fl;{  while (cl_index < total_clusters && next_cluster(cl_index) != FREE)	cl_index++;  if (leave_fl && cl_index >= total_clusters) {	fprintf (stderr, "%s: Diskette full. File not added.\n", cmnd);	exit(1);  }  return cl_index++;}/* read a portion of the fat containing |cl_no| into the cache */void read_fat (cl_no)   unsigned int cl_no;{  if (!cooked_fat) {  	/* Read the fat for the first time. We have to allocate all the  	 * buffers  	 */  	if (fat_16) {		/* FAT consists of little endian shorts. Easy to convert		 */		if ((cooked_fat = malloc (fat_size)) == NULL) {			/* Oops, FAT doesn't fit into memory, just read			 * a chunk			 */			if ((cooked_fat = malloc (COOKED_SIZE)) == NULL) {				fprintf (stderr, "%s: not enough memory for FAT cache. Use chmem\n",					 cmnd);				exit (1);			}			cache_size = COOKED_SIZE / 2;		} else {			cache_size = fat_size / 2;		}	} else {		/* 12 bit FAT. Difficult encoding, but small. Keep		 * both raw FAT and cooked version in memory.		 */		if ((cooked_fat = malloc (total_clusters * sizeof (short))) == NULL ||		    (raw_fat = malloc (fat_size)) == NULL) {			fprintf (stderr, "%s: not enough memory for FAT cache. Use chmem\n",				 cmnd);			exit (1);		}		cache_size = total_clusters;	}  }  fat_low = cl_no / cache_size * cache_size;  fat_high = fat_low + cache_size - 1;  if (!fat_16) {  	unsigned short	*cp;  	unsigned char	*rp;  	unsigned short	i;	disk_io (READ, FAT_START, raw_fat, fat_size);	for (rp = raw_fat, cp = cooked_fat, i = 0;	     i < cache_size;	     rp += 3, i += 2) {	     	*cp = *rp + ((*(rp + 1) & 0x0f) << 8);	     	if (*cp == BAD) *cp = BAD16;	     	else if (*cp == LAST_CLUSTER12) *cp = LAST_CLUSTER;	     	cp ++;	     	*cp = ((*(rp + 1) & 0xf0) >> 4) + (*(rp + 2) << 4);	     	if (*cp == BAD) *cp = BAD16;	     	else if (*cp == LAST_CLUSTER12) *cp = LAST_CLUSTER;	     	cp ++;	}  } else {	assert (sizeof (short) == 2);	assert (CHAR_BIT == 8);		/* just in case */	disk_io (READ, FAT_START + fat_low * 2, (void *)cooked_fat, cache_size * 2);	if (big_endian) {		unsigned short	*cp;		unsigned char	*rp;		unsigned short	i;		for (i = 0, rp = (unsigned char *)cooked_fat /* sic */, cp = cooked_fat;		     i < cache_size;		     rp += 2, cp ++, i ++) {		     	*cp = c2u2 (rp);		}	}  }}/* flush the fat cache out to disk */void flush_fat (){  if (fat_16) {	if (big_endian) {		unsigned short	*cp;		unsigned char	*rp;		unsigned short	i;		for (i = 0, rp = (unsigned char *)cooked_fat /* sic */, cp = cooked_fat;		     i < cache_size;		     rp += 2, cp ++, i ++) {		     	*rp = *cp;		     	*(rp + 1) = *cp >> 8;		}	}	disk_io (WRITE, FAT_START + fat_low * 2, (void *)cooked_fat, cache_size * 2);	disk_io (WRITE, FAT_START + fat_size + fat_low * 2, (void *)cooked_fat, cache_size * 2);  } else {  	unsigned short	*cp;  	unsigned char	*rp;  	unsigned short	i;	for (rp = raw_fat, cp = cooked_fat, i = 0;	     i < cache_size;	     rp += 3, cp += 2, i += 2) {	     	*rp = *cp;	     	*(rp + 1) = ((*cp & 0xf00) >> 8) |	     		    ((*(cp + 1) & 0x00f) << 4);	     	*(rp + 2) = ((*(cp + 1) & 0xff0) >> 4);	}	disk_io (WRITE, FAT_START, raw_fat, fat_size);	disk_io (WRITE, FAT_START + fat_size, raw_fat, fat_size);  }}/* make cl_2 the successor of cl_1 */void link_fat(cl_1, cl_2)unsigned int cl_1;unsigned int cl_2;{  if (cl_1 < fat_low || cl_1 > fat_high) {  	if (fat_dirty) flush_fat ();  	read_fat (cl_1);  }  cooked_fat [cl_1 - fat_low] = cl_2;  fat_dirty = TRUE;}unsigned short next_cluster(cl_no)register unsigned int cl_no;{  if (cl_no < fat_low || cl_no > fat_high) {  	if (fat_dirty) flush_fat ();  	read_fat (cl_no);  }  return cooked_fat [cl_no - fat_low];}char *slash(str)register char *str;{  register char *result = str;  while (*str)	if (*str++ == '/') result = str;  return result;}void add_path(file, slash_fl)char *file;BOOL slash_fl;{  register char *ptr = path;  while (*ptr) ptr++;  if (file == NIL_PTR) {	if (ptr != path) ptr--;	if (ptr != path) do {			ptr--;		} while (*ptr != '/' && ptr != path);	if (ptr != path && !slash_fl) *ptr++ = '/';	*ptr = '\0';  } else	strcpy (ptr, file);}void disk_io(op, seek, address, bytes)register BOOL op;unsigned long seek;void *address;register unsigned bytes;{  unsigned int r;  if (lseek(disk, seek, SEEK_SET) < 0L) {	fflush (stdout);	fprintf (stderr, "%s: Bad lseek: %s\n", cmnd, strerror (errno));	exit(1);  }  if (op == READ)	r = read(disk, (char *) address, bytes);  else {	r = write(disk, (char *) address, bytes);  }  if (r != bytes) {  	fprintf (stderr, "%s: read error: %s\n", cmnd, strerror (errno));  	exit (1);  }}char dosread_c_rcs_id [] = 	"$Id: dosread.c,v 1.8 1994/05/14 21:53:08 hjp Rel $";/* $Log: dosread.c,v $ * Revision 1.8  1994/05/14  21:53:08  hjp * filenames with more than 3 characters and extension work again. * removed debugging stuff and b_copy. * * Revision 1.7  1994/04/09  03:09:01  hjp * (posted to comp.os.minix) * merged branch 1.5.387 with stem. * changed treatment of drive parameter * * Revision 1.5.387.9  1994/04/09  02:07:51  hjp * Disk full no longer produces lost clusters but a truncated file. * Truncated file names to 8+3 before comparisons to avoid duplicate * files and filenames containing dots in the extension. * Replaced sbrk and brk by malloc and free (mixing brk and malloc causes * heap corruption which sometimes lead to core dumps. It may also have * been the cause of data corruption Kees reported). * Made global variables static and removed some unused ones. * Error messages now contain program name. * * Revision 1.5.387.8  1993/11/13  00:38:45  hjp * Posted to comp.os.minix and included in Minix-386vm 1.6.25.1. * Speed optimizations for 1.44 MB disks. * Replaced lowlevel I/O by stdio. * Simplified -a: Now only removes resp. adds CRs * Cleaned up. *  * Revision 1.5.387.1  1993/01/15  19:32:29  ast * Released with 1.6.24b */

⌨️ 快捷键说明

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