Beispiel #1
0
ZERO_OR_ERROR FS_read_tester(struct one_wire_query *owq)
{
	switch (OWQ_pn(owq).extension) {
	case EXTENSION_ALL:		/* array */
		if (OWQ_offset(owq)) {
			return 0;
		}
		if (OWQ_size(owq) < FullFileLength(PN(owq))) {
			return -ERANGE;
		}
		return FS_read_tester_array(owq);
	case EXTENSION_BYTE:		/* bitfield */
	default:
		return FS_read_tester_single(owq);
	}
}
// create the buffer of size filesize
GOOD_OR_BAD OWQ_allocate_read_buffer(struct one_wire_query * owq )
{
	struct parsedname * pn = PN(owq) ;
	size_t size = FullFileLength(pn);

	if ( size > 0 ) {
		char * buffer = owmalloc(size+1) ;
		if ( buffer == NULL ) {
			return gbBAD ;
		}
		memset(buffer,0,size+1) ;
		OWQ_buffer(owq) = buffer ;
		OWQ_size(owq) = size ;
		OWQ_offset(owq) = 0 ;
		OWQ_cleanup(owq) |= owq_cleanup_buffer ;
	}
	return gbGOOD;
}
Beispiel #3
0
/* If offset is too large, size is set to 0 */
static void adjust_file_size(struct one_wire_query *owq)
{
	size_t file_length = 0;

	/* Adjust file length -- especially important for fuse which uses 4k buffers */
	/* First file filelength */
	file_length = FullFileLength(PN(owq));

	/* next adjust for offset */
	if ((unsigned long) OWQ_offset(owq) >= (unsigned long) file_length) {
		// This check is done in OWQ_parse_output() too, since it's always called when this function
		OWQ_size(owq) = 0 ;           // this is status ok... but 0 bytes were read...
	} else if ( OWQ_size(owq) + OWQ_offset(owq) > file_length ) {
		// Finally adjust buffer length
		OWQ_size(owq) = file_length - OWQ_offset(owq) ;
	}
	LEVEL_DEBUG("file_length=%lu offset=%lu size=%lu",
				(unsigned long) file_length, (unsigned long) OWQ_offset(owq), (unsigned long) OWQ_size(owq));
}
Beispiel #4
0
/* Fstat with parsedname already done */
ZERO_OR_ERROR FS_fstat_postparse(struct stat *stbuf, const struct parsedname *pn)
{
	memset(stbuf, 0, sizeof(struct stat));

	LEVEL_CALL("ATTRIBUTES path=%s", SAFESTRING(pn->path));
	if (KnownBus(pn) && pn->known_bus == NULL) {
		/* check for presence of first in-device at least since FS_ParsedName
		 * doesn't do it yet. */
		return -ENOENT;
	} else if (pn->selected_device == NO_DEVICE) {	/* root directory */
		int nr = 0;
		//printf("FS_fstat root\n");
		stbuf->st_mode = S_IFDIR | 0755;
		stbuf->st_nlink = 2;	// plus number of sub-directories
		nr = -1;				// make it 1
		/*
		   If calculating NSUB is hard, the filesystem can set st_nlink of
		   directories to 1, and find will still work.  This is not documented
		   behavior of find, and it's not clear whether this is intended or just
		   by accident.  But for example the NTFS filesysem relies on this, so
		   it's unlikely that this "feature" will go away.
		 */
		stbuf->st_nlink += nr;
		FSTATLOCK;
		stbuf->st_atime = stbuf->st_ctime = stbuf->st_mtime = StateInfo.start_time;
		FSTATUNLOCK;
		stbuf->st_size = 4096 ; // Common directory size
		return 0;
	} else if (pn->selected_filetype == NO_FILETYPE) {
		int nr = 0;
		//printf("FS_fstat pn.selected_filetype == NULL  (1-wire device)\n");
		stbuf->st_mode = S_IFDIR | 0777;
		stbuf->st_nlink = 2;	// plus number of sub-directories

		nr = -1;				// make it 1
		//printf("FS_fstat seem to be %d entries (%d dirs) in device\n", pn.selected_device->nft, nr);
		stbuf->st_nlink += nr;
		FSTATLOCK;
		stbuf->st_atime = stbuf->st_ctime = stbuf->st_mtime = StateInfo.dir_time;
		FSTATUNLOCK;
		stbuf->st_size = 4096 ; // Common directory size
		return 0;
	} else if (pn->selected_filetype->format == ft_directory || pn->selected_filetype->format == ft_subdir) {	/* other directory */
		int nr = 0;
		stbuf->st_mode = S_IFDIR | 0777;
		stbuf->st_nlink = 2;	// plus number of sub-directories
		nr = -1;				// make it 1
		stbuf->st_nlink += nr;

		FSTATLOCK;
		stbuf->st_atime = stbuf->st_ctime = stbuf->st_mtime = StateInfo.dir_time;
		FSTATUNLOCK;
		stbuf->st_size = 4096 ; // Common directory size
		return 0;
	} else {					/* known 1-wire filetype */
		stbuf->st_mode = S_IFREG;
        if (pn->selected_filetype->read != NO_READ_FUNCTION) {
			stbuf->st_mode |= 0444;
		}
		if (!Globals.readonly && (pn->selected_filetype->write != NO_WRITE_FUNCTION)) {
			stbuf->st_mode |= 0222;
        }
		stbuf->st_nlink = 1;

		switch (pn->selected_filetype->change) {
		case fc_volatile:
		case fc_second:
		case fc_statistic:
			stbuf->st_atime = stbuf->st_ctime = stbuf->st_mtime = NOW_TIME;
			break;
		case fc_stable:
			FSTATLOCK;
			stbuf->st_atime = stbuf->st_ctime = stbuf->st_mtime = StateInfo.dir_time;
			FSTATUNLOCK;
			break;
		default:
			stbuf->st_atime = stbuf->st_ctime = stbuf->st_mtime = StateInfo.start_time;
			break;
		}
		stbuf->st_size = FullFileLength(pn);
		return 0;
	}
}
Beispiel #5
0
/* Structure file */
static ZERO_OR_ERROR FS_structure(struct one_wire_query *owq)
{
	char structure_text[PROPERTY_LENGTH_STRUCTURE+1] ;
	int output_length;
	struct parsedname * pn = PN(owq) ;
	struct filetype * ftype = pn->selected_filetype ;
	char format_char ;
	char change_char ;
	int index_num ;
	int elements_num ;
	

	// TEMPORARY change type from structure->real to get real length rhather than structure length
	pn->type = ePN_real;	/* "real" type to get return length, rather than "structure" length */

	// Set property type
	switch ( ftype->format ) {
		case ft_directory:
		case ft_subdir:
			format_char = 'D' ;
			break ;
		case ft_integer:
			format_char = 'i' ;
			break ;
		case ft_unsigned:
			format_char = 'u' ;
			break ;
		case ft_float:
			format_char = 'f' ;
			break ;
		case ft_alias:
			format_char = 'l' ;
			break ;
		case ft_ascii:
		case ft_vascii:
			format_char = 'a' ;
			break ;
		case ft_binary:
			format_char = 'b' ;
			break ;
		case ft_yesno:
		case ft_bitfield:
			format_char = 'y' ;
			break ;
		case ft_date:
			format_char = 'd' ;
			break ;
		case ft_temperature:
			format_char = 't' ;
			break ;
		case ft_tempgap:
			format_char = 'g' ;
			break ;
		case ft_pressure:
			format_char = 'p' ;
			break ;
		case ft_unknown:
		default:
			format_char = '?' ;
			break ;
	}

	// Set index
	index_num = (ftype->ag) ? pn->extension : 0 ;
	
	// Set elements
	if ( ftype-> ag ) { // array
		if ( ftype -> ag -> combined == ag_sparse) {
			if ( ftype -> ag -> letters == ag_letters) {
				elements_num = -1 ;
			} else { // numbered
				elements_num = 0 ;
			}
		} else { // non sparse
			elements_num = ftype->ag->elements ;
		}
	} else { // scallar
		elements_num = 1 ;
	}

	// Set changability
	switch ( ftype->change ) {
		case fc_static:
		case fc_subdir:
		case fc_directory:
			change_char = 'f' ;
			break ;
		case fc_stable:
		case fc_persistent:
			change_char = 's' ;
			break ;
		case fc_volatile:
		case fc_read_stable:
		case fc_simultaneous_temperature:
		case fc_simultaneous_voltage:
		case fc_uncached:
		case fc_statistic:
		case fc_presence:
		case fc_link:
		case fc_page:
			change_char = 'v' ;
			break ;
		case fc_second:
		default:
			change_char = 't' ;
			break ;
	}

	UCLIBCLOCK;
	output_length = snprintf(structure_text,
		 PROPERTY_LENGTH_STRUCTURE+1,
		 "%c,%.6d,%.6d,%.2s,%.6d,%c,",
		 format_char,
		 index_num ,
		 elements_num,
		 (ftype->read == NO_READ_FUNCTION) ? ((ftype->write == NO_WRITE_FUNCTION) ? "oo" : "wo")
		                                   : ((ftype->write == NO_WRITE_FUNCTION) ? "ro" : "rw"), 
		 (int) FullFileLength(PN(owq)),
		 change_char
		);
	UCLIBCUNLOCK;
	LEVEL_DEBUG("length=%d", output_length);

	// TEMPORARY restore type from real to structure
	pn->type = ePN_structure;

	if (output_length < 0) {
		LEVEL_DEBUG("Problem formatting structure string");
		return -EFAULT;
	}
	if ( output_length > PROPERTY_LENGTH_STRUCTURE ) {
		LEVEL_DEBUG("Structure string too long");
		return -EINVAL ;
	}

	return OWQ_format_output_offset_and_size(structure_text,output_length,owq);
}