Exemplo n.º 1
0
/* Write now that connection is set */
static ZERO_OR_ERROR FS_w_given_bus(struct one_wire_query *owq)
{
	struct parsedname *pn = PN(owq);

	if ( BAD(TestConnection(pn)) ) {
		return -ECONNABORTED;
	} else if (KnownBus(pn) && BusIsServer(pn->selected_connection)) {
		return ServerWrite(owq);
	} else if (OWQ_pn(owq).type == ePN_real) {
		ZERO_OR_ERROR write_or_error = DeviceLockGet(pn);
		if (write_or_error == 0) {
			write_or_error = FS_w_local(owq);
			DeviceLockRelease(pn);
		} else {
			LEVEL_DEBUG("Cannot lock device for writing") ;
		}
		return write_or_error ;
	} else if ( IsInterfaceDir(pn) ) {
		ZERO_OR_ERROR write_or_error;
		BUSLOCK(pn);
		write_or_error = FS_w_local(owq);
		BUSUNLOCK(pn);
		return write_or_error ;
	} else {
		return FS_w_local(owq);
	}
}
Exemplo n.º 2
0
/* See if a cached location is accurate -- called with "Known Bus" set */
INDEX_OR_ERROR ReCheckPresence(struct parsedname *pn)
{
	INDEX_OR_ERROR bus_nr;
	
	if (NotRealDir(pn)) {
		return INDEX_DEFAULT;
	}
	
	if ((pn->selected_device == DeviceSimultaneous)
		|| (pn->selected_device == DeviceThermostat)) {
		return INDEX_DEFAULT;
	}
	
	if (KnownBus(pn)) {
		if ( INDEX_VALID( CheckThisConnection(pn->known_bus->index,pn) ) ) {
			return pn->known_bus->index ;
		}
	}
	
	if ( GOOD( Cache_Get_Device(&bus_nr, pn)) ) {
		LEVEL_DEBUG("Found device on bus %d",bus_nr);
		if ( INDEX_VALID( CheckThisConnection(bus_nr,pn) ) ) {
			SetKnownBus(bus_nr, pn);
			return bus_nr ;
		}
	}
	
	UnsetKnownBus(pn);
	Cache_Del_Device(pn) ;
	return CheckPresence(pn);
}
Exemplo n.º 3
0
// This function should return number of bytes read... not status.
static SIZE_OR_ERROR FS_r_given_bus(struct one_wire_query *owq)
{
	// Device locking occurs here
	struct parsedname *pn = PN(owq);
	SIZE_OR_ERROR read_or_error = 0;

	LEVEL_DEBUG("About to read <%s> extension=%d size=%d offset=%d",SAFESTRING(pn->path),(int) pn->extension,(int) OWQ_size(owq),(int) OWQ_offset(owq));

	if (KnownBus(pn) && BusIsServer(pn->selected_connection)) {
		/* The bus is not local... use a network connection instead */
		LEVEL_DEBUG("pid=%ld call ServerRead", pthread_self());

		// Read afar -- returns already formatted in buffer
		read_or_error = ServerRead(owq);
		LEVEL_DEBUG("back from server");
		//printf("FS_r_given_bus pid=%ld r=%d\n",pthread_self(), read_or_error);
	} else {
		STAT_ADD1(read_calls);	/* statistics */
		if (DeviceLockGet(pn) == 0) {
			read_or_error = FS_r_local(owq);	// this returns status
			DeviceLockRelease(pn);
			LEVEL_DEBUG("return=%d", read_or_error);
			if (read_or_error >= 0) {
				// local success -- now format in buffer
				read_or_error = OWQ_parse_output(owq);	// this returns nr. bytes
			}
		} else {
			LEVEL_DEBUG("Cannot lock bus to perform read") ;
			read_or_error = -EADDRINUSE;
		}
	}
	LEVEL_DEBUG("After read is performed (bytes or error %d)", read_or_error);
	Debug_OWQ(owq);
	return read_or_error;
}
Exemplo n.º 4
0
/* Write to settings dir */
static ZERO_OR_ERROR FS_w_settings(struct one_wire_query *owq)
{
	struct parsedname *pn = PN(owq);

	if ( BAD(TestConnection(pn)) ) {
		// safe for connection_in == NULL
		return -ECONNABORTED;
	} else if (KnownBus(pn) && BusIsServer(pn->selected_connection)) {
		return ServerWrite(owq);
	} else if ( pn->selected_connection != NO_CONNECTION ) {
		LEVEL_DEBUG("Attempt to write to local bus for /settings");
		return -ENODEV ;
	} else {
		return FS_w_local(owq);
	}
}
Exemplo n.º 5
0
/* After parsing, but before sending to various devices. Will repeat 3 times if needed */
SIZE_OR_ERROR FS_read_postparse(struct one_wire_query *owq)
{
	struct parsedname *pn = PN(owq);
	SIZE_OR_ERROR read_or_error;

	/* Normal read. Try three times */
	LEVEL_DEBUG("%s", pn->path);
	STATLOCK;
	AVERAGE_IN(&read_avg);
	AVERAGE_IN(&all_avg);
	STATUNLOCK;

	/* First try */
	STAT_ADD1(read_tries[0]);

	/* Check file type. */
	if (pn->selected_device == NO_DEVICE || pn->selected_filetype == NO_FILETYPE) {
		if (KnownBus(pn) && BusIsServer(pn->selected_connection)) {
			/* Pass unknown remote filetype to remote owserver. */
			read_or_error = FS_r_given_bus(owq);
		} else {
			/* Local unknown filetypes are directories. */
			return -EISDIR;
		}	
	} else {
		/* Local known filetypes are handled here. */
		read_or_error = (pn->type == ePN_real) ? FS_read_real(owq) : FS_r_virtual(owq);
	}

	STATLOCK;
	if (read_or_error >= 0) {
		++read_success;			/* statistics */
		read_bytes += read_or_error;	/* statistics */
	}
	AVERAGE_OUT(&read_avg);
	AVERAGE_OUT(&all_avg);
	STATUNLOCK;
	LEVEL_DEBUG("%s return %d", pn->path, read_or_error);
	return read_or_error;
}
Exemplo n.º 6
0
/* Check if device exists -- >=0 yes, -1 no */
INDEX_OR_ERROR CheckPresence(struct parsedname *pn)
{
	INDEX_OR_ERROR bus_nr;
	
	if (NotRealDir(pn)) {
		return INDEX_DEFAULT;
	}
	
	if ((pn->selected_device == DeviceSimultaneous)
		|| (pn->selected_device == DeviceThermostat)) {
		return INDEX_DEFAULT;
	}
	
	/* If set, already found bus. */
	/* Use UnsetKnownBus to clear and allow a new search */
	if (KnownBus(pn)) {
		return pn->known_bus->index;
	}
	
	if ( GOOD( Cache_Get_Device(&bus_nr, pn)) ) {
		LEVEL_DEBUG("Found device on bus %d",bus_nr);
		SetKnownBus(bus_nr, pn);
		return bus_nr;
	}
	
	LEVEL_DETAIL("Checking presence of %s", SAFESTRING(pn->path));
	
	bus_nr = CheckPresence_low(pn);	// check only allocated inbound connections
	if ( INDEX_VALID(bus_nr) ) {
		SetKnownBus(bus_nr, pn);
		Cache_Add_Device( bus_nr, pn->sn ) ;
		return bus_nr;
	}
	UnsetKnownBus(pn);
	return INDEX_BAD;
}
Exemplo n.º 7
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;
	}
}