void
AutoMounter::MessageReceived(BMessage *message)
{
	switch (message->what) {
#if _INCLUDES_CLASS_DEVICE_MAP
		case kAutomounterRescan:
			RescanDevices();
			break;

		case kStartPolling:	
			// PRINT(("starting the automounter\n"));
			
			fScanThread = spawn_thread(AutoMounter::WatchVolumeBinder, 
#if DEBUG				
				"HiroshiLikesAtomountScan",	// long story
#else
				"AutomountScan",
#endif				
				B_LOW_PRIORITY, this);
			resume_thread(fScanThread);
			break;

		case kMountVolume:
			MountVolume(message);
			break;

		case kUnmountVolume:
			UnmountAndEjectVolume(message);
			break;

		case kSetAutomounterParams:
			{
				bool rescanNow = false;
				message->FindBool("rescanNow", &rescanNow);
				SetParams(message, rescanNow);
				WriteSettings();
				break;
			}

		case kMountAllNow:
			RescanDevices();
			MountAllNow();
			break;

		case kSuspendAutomounter:
			SuspendResume(true);
			break;

		case kResumeAutomounter:
			SuspendResume(false);
			break;

		case kTryMountingFloppy:
			TryMountingFloppy();
			break;

		case B_NODE_MONITOR:
			{
				int32 opcode;
				if (message->FindInt32("opcode", &opcode) != B_OK)
					break;
	
				switch (opcode) {
					case B_DEVICE_MOUNTED: {
						WRITELOG(("** Received Device Mounted Notification"));
						dev_t device;
						if (message->FindInt32("new device", &device) == B_OK) {
							Partition *partition =  FindPartition(device);
							if (partition == NULL || partition->Mounted() != kMounted) {
								WRITELOG(("Device %i not in device list.  Someone mounted it outside "
									"of Tracker", device));
		
								//
								// This is the worst case.  Someone has mounted
								// something from outside of tracker.  
								// Unfortunately, there's no easy way to tell which
								// partition was just mounted (or if we even know about the device),
								// so stop watching all nodes, rescan to see what is now mounted,
								// and start watching again.
								//
								RescanDevices();
							} else
								WRITELOG(("Found partition\n"));
						} else {
							WRITELOG(("ERROR: Could not find mounted device ID in message"));
							PRINT_OBJECT(*message);
						}
	
						break;
					}
	
	
					case B_DEVICE_UNMOUNTED: {
						WRITELOG(("*** Received Device Unmounted Notification"));
						dev_t device;
						if (message->FindInt32("device", &device) == B_OK) {
							Partition *partition = FindPartition(device);
	
							if (partition != 0) {
								WRITELOG(("Found device in device list. Updating state to unmounted."));
								partition->SetMountState(kNotMounted);
							} else
								WRITELOG(("Unmounted device %i was not in device list", device));
						} else {
							WRITELOG(("ERROR: Could not find unmounted device ID in message"));
							PRINT_OBJECT(*message);
						}
	
						break;
					}	
	
	
					//	The name of a mount point has changed
					case B_ENTRY_MOVED: {
						WRITELOG(("*** Received Mount Point Renamed Notification"));
					
						const char *newName;
						if (message->FindString("name", &newName) != B_OK) {
							WRITELOG(("ERROR: Couldn't find name field in update message"));
							PRINT_OBJECT(*message);
							break ;
						}
	
						//
						// When the node monitor reports a move, it gives the
						// parent device and inode that moved.  The problem is 
						// that  the inode is the inode of root *in* the filesystem,
						// which is generally always the same number for every 
						// filesystem of a type.
						//
						// What we'd really like is the device that the moved	
						// volume is mounted on.  Find this by using the 
						// *new* name and directory, and then stat()ing that to
						// find the device.
						//
						dev_t parentDevice;
						if (message->FindInt32("device", &parentDevice) != B_OK) {
							WRITELOG(("ERROR: Couldn't find 'device' field in update"
								" message"));
							PRINT_OBJECT(*message);
							break;
						}
		
						ino_t toDirectory;	
						if (message->FindInt64("to directory", &toDirectory)!=B_OK){
							WRITELOG(("ERROR: Couldn't find 'to directory' field in update"
							  "message"));
							PRINT_OBJECT(*message);
							break;
						}
		
						entry_ref root_entry(parentDevice, toDirectory, newName);
	
						BNode entryNode(&root_entry);
						if (entryNode.InitCheck() != B_OK) {
							WRITELOG(("ERROR: Couldn't create mount point entry node: %s/n", 
								strerror(entryNode.InitCheck())));
							break;
						}	
	
						node_ref mountPointNode;
						if (entryNode.GetNodeRef(&mountPointNode) != B_OK) {
							WRITELOG(("ERROR: Couldn't get node ref for new mount point"));
							break;
						}
				
	
						WRITELOG(("Attempt to rename device %li to %s", mountPointNode.device,
							newName));

						Partition *partition = FindPartition(mountPointNode.device);
						if (partition != NULL) {
							WRITELOG(("Found device, changing name."));

							BVolume mountVolume(partition->VolumeDeviceID());
							BDirectory mountDir;
							mountVolume.GetRootDirectory(&mountDir);
							BPath dirPath(&mountDir, 0);
					
							partition->SetMountedAt(dirPath.Path());
							partition->SetVolumeName(newName);					
							break;
						}
						else
							WRITELOG(("ERROR: Device %li does not appear to be present",
								mountPointNode.device));
					}
				}
			}
			break;


#endif
		default:
			BLooper::MessageReceived(message);
			break;
	}
}
Example #2
0
void
AutoMounter::MessageReceived(BMessage* message)
{
	switch (message->what) {
		case kMountVolume:
			_MountVolume(message);
			break;

		case kUnmountVolume:
			_UnmountAndEjectVolume(message);
			break;

		case kSetAutomounterParams:
		{
			bool rescanNow = false;
			message->FindBool("rescanNow", &rescanNow);

			_UpdateSettingsFromMessage(message);
			_GetSettings(&fSettings);
			_WriteSettings();

			if (rescanNow)
				_MountVolumes(fNormalMode, fRemovableMode);
			break;
		}

		case kGetAutomounterParams:
		{
			BMessage reply;
			_GetSettings(&reply);
			message->SendReply(&reply);
			break;
		}

		case kMountAllNow:
			_MountVolumes(kAllVolumes, kAllVolumes);
			break;

		case B_DEVICE_UPDATE:
			int32 event;
			if (message->FindInt32("event", &event) != B_OK
				|| (event != B_DEVICE_MEDIA_CHANGED
					&& event != B_DEVICE_ADDED))
				break;

			partition_id deviceID;
			if (message->FindInt32("id", &deviceID) != B_OK)
				break;

			_MountVolumes(kNoVolumes, fRemovableMode, false, deviceID);
			break;

#if 0
		case B_NODE_MONITOR:
		{
			int32 opcode;
			if (message->FindInt32("opcode", &opcode) != B_OK)
				break;

			switch (opcode) {
				//	The name of a mount point has changed
				case B_ENTRY_MOVED: {
					WRITELOG(("*** Received Mount Point Renamed Notification"));

					const char *newName;
					if (message->FindString("name", &newName) != B_OK) {
						WRITELOG(("ERROR: Couldn't find name field in update "
							"message"));
						PRINT_OBJECT(*message);
						break ;
					}

					//
					// When the node monitor reports a move, it gives the
					// parent device and inode that moved.  The problem is
					// that  the inode is the inode of root *in* the filesystem,
					// which is generally always the same number for every
					// filesystem of a type.
					//
					// What we'd really like is the device that the moved
					// volume is mounted on.  Find this by using the
					// *new* name and directory, and then stat()ing that to
					// find the device.
					//
					dev_t parentDevice;
					if (message->FindInt32("device", &parentDevice) != B_OK) {
						WRITELOG(("ERROR: Couldn't find 'device' field in "
							"update message"));
						PRINT_OBJECT(*message);
						break;
					}

					ino_t toDirectory;
					if (message->FindInt64("to directory", &toDirectory)
						!= B_OK) {
						WRITELOG(("ERROR: Couldn't find 'to directory' field "
							"in update message"));
						PRINT_OBJECT(*message);
						break;
					}

					entry_ref root_entry(parentDevice, toDirectory, newName);

					BNode entryNode(&root_entry);
					if (entryNode.InitCheck() != B_OK) {
						WRITELOG(("ERROR: Couldn't create mount point entry "
							"node: %s/n", strerror(entryNode.InitCheck())));
						break;
					}

					node_ref mountPointNode;
					if (entryNode.GetNodeRef(&mountPointNode) != B_OK) {
						WRITELOG(("ERROR: Couldn't get node ref for new mount "
							"point"));
						break;
					}

					WRITELOG(("Attempt to rename device %li to %s",
						mountPointNode.device, newName));

					Partition *partition = FindPartition(mountPointNode.device);
					if (partition != NULL) {
						WRITELOG(("Found device, changing name."));

						BVolume mountVolume(partition->VolumeDeviceID());
						BDirectory mountDir;
						mountVolume.GetRootDirectory(&mountDir);
						BPath dirPath(&mountDir, 0);

						partition->SetMountedAt(dirPath.Path());
						partition->SetVolumeName(newName);
						break;
					} else {
						WRITELOG(("ERROR: Device %li does not appear to be "
							"present", mountPointNode.device));
					}
				}
			}
			break;
		}
#endif

		default:
			BLooper::MessageReceived(message);
			break;
	}
}