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

📄 rdcf2.c

📁 FAT16 Filesystem on Philips LPC2000 series processors
💻 C
📖 第 1 页 / 共 3 页
字号:
			// simply empty the file of clusters.		if (found) {			check_write_access(f);			release_FAT_entries(f);			flush_buffer(f);		} else lengthen_directory_if_necessary(f);		f->file.first_cluster = EMPTY_CLUSTER;		f->file.size = 0L;	}		// create new dir entry if mode is not purely read: "r"	if (!found && (mode & 0x3)) {		f->file.attribute = RDCF_ARCHIVE;		rdcf_get_date_and_time(&f->file.date_and_time);		f->mode |= WRITTEN;		f->file.first_cluster = EMPTY_CLUSTER;		f->file.size = 0L;		update_directory_entry(f, 0);		flush_buffer(f);	}	if ((mode & 0x3) == 0) {			// open for reading.		f->mode |= RDCF_READ;		if (!found) error_exit(f, ~ENOENT);	} else {			// open for writing or		f->mode |= RDCF_WRITE;			// open for read write.		if ((mode & 0x3) == 2) f->mode |= RDCF_READ;		check_write_access(f);	}	f->last_cluster = EMPTY_CLUSTER;	f->BufferInUse = True;	f->position = 0;	f->cluster = f->file.first_cluster;	if (mode & _FAPPEND) {			// seek to end of file.		if ((found = rdcf_seek(f, f->file.size)) != 0) return found;	}	return 0;}/*************************************************************** * rdcf_read * *   fill buf with data from opened file. *   returns positive number on succes of bytes read. ****************************************************************/int rdcf_read(struct rdcf *f, void *buf, int count){	ulong size = f->file.size;	unsigned unread_bytes = count;	ulong position = f->position;	char *buffer = buf;	if ((f->result=setjmp(f->error)) != 0) return f->result;	if (f->BufferInUse == False) error_exit(f, ~EBADF);	if ((f->mode & RDCF_READ) == 0) error_exit(f, ~EBADFD);	f->buffer_status = EMPTY;	while (unread_bytes>0) {		unsigned n = unread_bytes;		unsigned rest_of_sector = SECTOR_SIZE - position%SECTOR_SIZE;		unsigned sector;		if (size<position+n) n = size-position;		if (n==0) break;		sector = first_sector_in_cluster(f, f->cluster) +			(position/SECTOR_SIZE)%f->sectors_per_cluster;		if (n>rest_of_sector) n = rest_of_sector;		if (position%SECTOR_SIZE==0 && n==SECTOR_SIZE)			read_sector(f, sector, buffer);		else /* read a partial sector */ {			read_buffer(f, sector);			memcpy(buffer, &f->buffer.buf[position%SECTOR_SIZE], n);		}		buffer += n;		position += n;		unread_bytes -= n;		if (position%(f->sectors_per_cluster*SECTOR_SIZE)==0 && position<size) {			unsigned next_cluster = FAT_entry(f, f->cluster);			if (next_cluster >= f->last_cluster_mark) f->last_cluster = f->cluster;			f->cluster = next_cluster;		}	}	f->position = position;	return f->result = count - unread_bytes;}int rdcf_seek(struct rdcf *f, ulong offset){	unsigned i, cluster;	if ((f->result=setjmp(f->error)) != 0) return f->result;	if (offset>f->file.size) error_exit(f, ~ESPIPE);	f->buffer_status = EMPTY;	cluster = f->file.first_cluster;	for (i=offset/(f->sectors_per_cluster*SECTOR_SIZE); i>0; i--) {		unsigned new_cluster = FAT_entry(f, cluster);		if (new_cluster >= f->last_cluster_mark) f->last_cluster = cluster;		cluster = new_cluster;	}	f->cluster = cluster;	f->position = offset;	return 0;}static int real_rdcf_write(struct rdcf *f, const uchar *buf, int count){	ulong size = f->file.size;	ulong position = f->position;	unsigned unwritten_bytes = count;	unsigned first_possibly_empty_cluster = 2;	const char *buffer = buf;	if ((f->result=setjmp(f->error)) != 0) return f->result;	if (f->BufferInUse == False) error_exit(f, ~EBADF);	f->buffer_status = EMPTY;	if ((f->mode & RDCF_WRITE) == 0) error_exit(f, ~EBADFD);	while (unwritten_bytes>0) {		unsigned sector;		unsigned n = unwritten_bytes;		unsigned rest_of_sector = SECTOR_SIZE - position%SECTOR_SIZE;		if (n>rest_of_sector) n = rest_of_sector;		if (f->cluster == EMPTY_CLUSTER || f->cluster >= f->last_cluster_mark) {			unsigned new_cluster =				add_new_cluster(f, f->last_cluster, first_possibly_empty_cluster);			if (new_cluster == EMPTY_CLUSTER) break;			first_possibly_empty_cluster = new_cluster+1;			f->cluster = f->last_cluster = new_cluster;			if (f->file.first_cluster==EMPTY_CLUSTER)			f->file.first_cluster = new_cluster;		}		sector = first_sector_in_cluster(f, f->cluster) +			(position/SECTOR_SIZE)%f->sectors_per_cluster;		if (position%SECTOR_SIZE==0 &&				(n==SECTOR_SIZE || position+n>=size)) {			write_sector(f, sector, buffer);		} else /* write a partial sector */ {			read_buffer(f, sector);			memcpy(&f->buffer.buf[position%SECTOR_SIZE], buffer, n);			f->buffer_status = DIRTY;		}		buffer += n;		position += n;		unwritten_bytes -= n;		if (position>size) size = position;		if (position%(f->sectors_per_cluster*SECTOR_SIZE)==0) {			unsigned next_cluster = FAT_entry(f, f->cluster);			if (next_cluster >= f->last_cluster_mark)				f->last_cluster = f->cluster;			f->cluster = next_cluster;		}	}	flush_buffer(f);	f->position = position;	f->file.size = size;	f->mode |= WRITTEN;#ifdef RDCF_FLUSH_DIR_AFTER_WRITE	rdcf_get_date_and_time(&f->file.date_and_time);		// do not allow empty files.	update_directory_entry(f, (f->file.size) ? 0 : 1);	flush_buffer(f);#endif	return f->result = count-unwritten_bytes;}int rdcf_write(struct rdcf *f, const void *buf, int count){// traps write() and ensures no dangling FAT chains.int	result;	result = real_rdcf_write(f, buf, count);		// uhoh, something really bad happened!		// flush buffer and close the handle.	if (result <= 0) {		rdcf_close(f);	}	return result;}int rdcf_flush_directory(struct rdcf *f){	if ((f->result=setjmp(f->error)) != 0) return f->result;	if (f->BufferInUse == False) return 0;	rdcf_get_date_and_time(&f->file.date_and_time);		// do not allow empty files.	update_directory_entry(f, (f->file.size) ? 0 : 1);	flush_buffer(f);	return 0;}#if 0int rdcf_attribute(struct rdcf *f, const char *spec, unsigned attribute){	if ((f->result=setjmp(f->error)) != 0) return f->result;	if (!find_file(f, initialize_fcb(f, spec)) ||			f->file.attribute & RDCF_DIRECTORY) {		error_exit(f, ~ENOENT);	}	f->file.attribute = (f->file.attribute & ~CHANGEABLE_ATTRIBUTES) |		(attribute & CHANGEABLE_ATTRIBUTES);	update_directory_entry(f, 0);	flush_buffer(f);	return 0;}int rdcf_date_and_time(struct rdcf *f, const char *spec,	struct rdcf_date_and_time *p){	if ((f->result=setjmp(f->error)) != 0) return f->result;	spec = initialize_fcb(f, spec);	if (*spec == 0) {		f->directory_cluster = 0;		if (!find_file_in_directory_or_find_volume(f, NULL))			error_exit(f, ~ENOENT);		} else {			if (!find_file(f, spec)) error_exit(f, ~ENOENT);	}	f->file.date_and_time = *p;	if ((f->file.attribute & (RDCF_DIRECTORY+RDCF_VOLUME)) == 0) {		check_write_access(f);		f->file.attribute |= RDCF_ARCHIVE;	}	update_directory_entry(f, 0);	if (f->file.attribute & RDCF_DIRECTORY) update_dot_and_dot_dot(f);	flush_buffer(f);	return 0;}int rdcf_directory(struct rdcf *f, const char *spec){		/* uchar name_extension[NAME_SIZE+EXTENSION_SIZE]; ??? */	if ((f->result=setjmp(f->error)) != 0) return f->result;	if (find_file(f, initialize_fcb(f, spec))) error_exit(f, ~EISDIR);		/* spec_to_name_extension(f, name_extension, f->file.spec); ??? */		/* name_extension_to_spec(f->file.spec, name_extension); ??? */		/* determine whether there is enough free space for directory */	{		unsigned cluster = 2;		unsigned required_clusters =		f->directory_index == NO_DIRECTORY_INDEX ? 2 : 1;		for (cluster = 2; required_clusters != 0; cluster++) {			if (cluster > f->maximum_cluster_number) error_exit(f, ~ENOSPC);			if (FAT_entry(f, cluster)==EMPTY_CLUSTER) required_clusters--;		}	}	lengthen_directory_if_necessary(f);	f->file.attribute = RDCF_DIRECTORY;	f->file.first_cluster = add_new_cluster(f, EMPTY_CLUSTER, 2);	clear_cluster(f, f->file.first_cluster);	f->file.size = 0L;	rdcf_get_date_and_time(&f->file.date_and_time);	update_directory_entry(f, 0);	update_dot_and_dot_dot(f);	flush_buffer(f);	return 0;}long int rdcf_free_space(struct rdcf *f#ifdef RDCF_MULTIPLE_DRIVE	, char *spec#endif){	unsigned cluster;	unsigned number_of_empty_clusters = 0;	if ((f->result=setjmp(f->error)) != 0) return (long)(f->result);#ifndef RDCF_MULTIPLE_DRIVE	initialize_fcb(f, NULL);#else	if (*initialize_fcb(f, spec) != 0) error_exit(f, ~EINVAL);#endif	for (cluster = 2; cluster <= f->maximum_cluster_number; cluster++) {		if (FAT_entry(f, cluster) == EMPTY_CLUSTER) number_of_empty_clusters++;	}	f->file.size = (ulong) number_of_empty_clusters *	(f->sectors_per_cluster * SECTOR_SIZE);	return (long)(f->file.size);}int rdcf_get_file_information(struct rdcf *f, const char *spec, unsigned idx){	if ((f->result=setjmp(f->error)) != 0) return f->result;	find_entry(f, spec, idx);	read_directory_entry(f);	return f->result = f->file.spec[0] == DELETED_FILE ? ENOENT :		f->file.spec[0] == 0 ? ENOSPC : 0;}int rdcf_next_file_information(struct rdcf *f){	if ((f->result=setjmp(f->error)) != 0) return f->result;	f->directory_index++;	if (f->directory_cluster == 0) {		if (f->directory_index >=				(f->first_data_sector - f->first_directory_sector)*ENTRIES_PER_SECTOR) {			error_exit(f, ~ENOSPC);		}	} else {		if (f->directory_index >= ENTRIES_PER_SECTOR*f->sectors_per_cluster) {			f->directory_cluster = FAT_entry(f, f->directory_cluster);			if (f->directory_cluster >= f->last_cluster_mark)			error_exit(f, ~ENOSPC);			f->directory_index = 0;		}	}	read_directory_entry(f);	return f->result = f->file.spec[0] == DELETED_FILE ? ENOENT :		f->file.spec[0] == 0 ? ENOSPC : 0;}/*-----------------------------------------------------------------------------When f represents a subdirectory, this function updates the . and .. entries atthe beginning of its first cluster.-----------------------------------------------------------------------------*/static void update_dot_and_dot_dot(struct rdcf *f){	f->directory_cluster = f->file.first_cluster;	f->directory_index = 0;	memset(f->file.spec, ' ', NAME_SIZE+EXTENSION_SIZE);	f->file.spec[0] = '.';	update_directory_entry(f, 0);	f->file.first_cluster = f->directory_first_cluster;	f->directory_index = 1;	f->file.spec[1] = '.';	update_directory_entry(f, 0);}/*-----------------------------------------------------------------------------This function contains the common code from rdcf_get_file_information() andrdcf_set_file_information().  It finds the directory entry specified by thespec and index, and puts its cluster and index into f->directory_cluster andf->directory_index.-----------------------------------------------------------------------------*/static void find_entry(struct rdcf *f, const char *spec, unsigned idx){	spec = initialize_fcb(f, spec);	if (*spec == 0) {		if (idx >=				(f->first_data_sector - f->first_directory_sector)*ENTRIES_PER_SECTOR) {			error_exit(f, ~ENOSPC);		}		f->directory_first_cluster = f->directory_cluster = 0;	} else {		if (!find_file(f, spec) || (f->file.attribute&RDCF_DIRECTORY) == 0)			error_exit(f, ~ENOENT);		f->directory_first_cluster = f->directory_cluster = f->file.first_cluster;		while (idx >= ENTRIES_PER_SECTOR*f->sectors_per_cluster) {			f->directory_cluster = FAT_entry(f, f->directory_cluster);			if (f->directory_cluster >= f->last_cluster_mark)				error_exit(f, ~ENOSPC);			idx -= ENTRIES_PER_SECTOR*f->sectors_per_cluster;		}	}	f->directory_index = idx;}#endif// vi:nowrap:#endif	// HAS_MMC

⌨️ 快捷键说明

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