The macosxhints Forums

The macosxhints Forums (http://hintsforums.macworld.com/index.php)
-   UNIX - General (http://hintsforums.macworld.com/forumdisplay.php?f=16)
-   -   Launch script when USB device is plugged in (http://hintsforums.macworld.com/showthread.php?t=103742)

ilium007 07-22-2009 11:02 PM

Launch script when USB device is plugged in
 
Hi - I have searched and searched for an answer to this one !

I have a client who uses CrashPlan for onsite backups but also uses a USB 3G HSDPA wireless card for internet access whilst on the road.

I wrote him some scripts to disable the CrashPlan backup so that he did not start pushing out huge amounts of upload data over the USB card. Well of course he forgot to trigger the scripts and ended up with a $700 internet bill for the month.

What I am trying to do is write somethign to trigger my scripts on either the insertion of the USB card or when network interface en2 comes up.

I have searched through the launchd.plist man page and I dont think and of the keys will monitor either of these events.

Does anyone know how to approach this one or where I should start looking first ???

tw 07-23-2009 01:19 AM

you can use launchd to run a loop-check. this script:
Code:

#! /bin/bash

if [[ `netstat -I en2 | grep -c en2 -` -ne 0 ]]; then
        #check to see if CrashPlan is running and kill it;
else
        #check to see if CrashPlan is stopped and run it;
fi

checks if en2 is engaged and kills crashplan (using scripts you will provide), and then restarts crashplan when en2 has no connections. use the following launchd plist to run this script every 60 (or whatever works) seconds.
Code:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
        <key>Label</key>
        <string>my.killscript</string>
        <key>Program</key>
        <string>/path/to/killscript</string>
        </array>
        <key>StartInterval</key>
        <integer>60</integer>
</dict>
</plist>

you might be able to trigger it more elegantly if you can figure out the path to the USB ports (that way you can test directly using the watchpaths key).

ilium007 07-23-2009 06:34 AM

OK - great ! Thanks for the reply. Where do USB devices manifest themselves in the file system ?? I am assuming /dev/xxx somewhere. I will have a look.

tw 07-23-2009 10:20 AM

Quote:

Originally Posted by ilium007 (Post 543873)
Where do USB devices manifest themselves in the file system ?? I am assuming /dev/xxx somewhere. I will have a look.

errr... If I knew that, I wouldn't have told you you needed to figure it out. this isn't a classroom, it's real life. well, sort of. :D

anika123 07-23-2009 02:42 PM

Quote:

Does anyone know how to approach this one or where I should start looking first ???
Its probably something like /volumes/xxx.

ilium007 07-23-2009 04:03 PM

Thanks guys - it's a USB modem so it doesn't appear as a Volume and USB devices don't appear in /dev

tlarkin 07-23-2009 04:10 PM

Use the system_profiler binary to see if it is connected or not

baf 07-23-2009 04:34 PM

Usb devices usually show up in /dev
try doing:
modem not connected
Code:

ls /dev >file1
connect modem and do
Code:

ls /dev >file2
diff file1 file2

now you should see if something has shown up.

tlarkin 07-23-2009 04:38 PM

I just pulled this info from system profiler on my USB flash disk

Code:

$ system_profiler SPUSBDataType
USB:

    USB High-Speed Bus:

      Host Controller Location: Built In USB
      Host Controller Driver: AppleUSBEHCI
      PCI Device ID: 0x27cc
      PCI Revision ID: 0x0002
      PCI Vendor ID: 0x8086
      Bus Number: 0xfd

        Flash Disk:

          Capacity: 967.5 MB
          Removable Media: Yes
          Detachable Drive: Yes
          BSD Name: disk1
          Product ID: 0x1000
          Vendor ID: 0x090c  (Silicon Motion, Inc. - Taiwan)
          Version: 11.00
          Serial Number: AB00090000011207
          Speed: Up to 480 Mb/sec
          Manufacturer: USB 2.0
          Location ID: 0xfd300000
          Current Available (mA): 500
          Current Required (mA): 100
          Mac OS 9 Drivers: No
          Partition Map Type: MBR (Master Boot Record)
          S.M.A.R.T. status: Not Supported
          Volumes:
            LOKI:
              Capacity: 967.5 MB
              Available: 151.4 MB
              Writable: Yes
              File System: MS-DOS FAT32
              BSD Name: disk1s1
              Mount Point: /Volumes/LOKI
          Volumes:
            disk1s1:
              Capacity: 967.5 MB
              Available: 151.4 MB
              Writable: Yes
              File System: MS-DOS FAT32

I am sure with a sed or a cut and a | grep -c you can easily loop the script to see if the device is connected then execute whatever command you want it to do from then on.

tw 07-23-2009 04:52 PM

let me point out that the problem is not finding some way to tell if the device is connected (which he can do with system profiler or netstat or maybe other ways). the problem is finding some way that can be watched by launchd (thus avoiding the need for a loop function that's constantly testing for the device). that means (basically) a file system path that launchd can watch for. if baf's suggestion pans out, that would probably work...

tlarkin 07-23-2009 04:55 PM

I always thought that plug n play devices were dynamically assigned nodes in /dev/whatever, so it would not get the same thing every time?

I was more along the lines thinking to have launchd watch the USB ports and run the script upon any activity. I guess that is what baf was saying though...

Oh well I tried.

tw 07-23-2009 05:01 PM

Quote:

Originally Posted by tlarkin (Post 543971)
I always thought that plug n play devices were dynamically assigned nodes in /dev/whatever, so it would not get the same thing every time?

I was more along the lines thinking to have launchd watch the USB ports and run the script upon any activity. I guess that is what baf was saying though...

Oh well I tried.

no, I think you may be right (at least, the nodes in /dev look pretty generic, and don't seem to have uuids associated with them). personally, I don't see what the problem with using the loop function I offered above is (it's not going to add any appreciable load to the system). but... <shrug>

baf 07-23-2009 05:30 PM

Well to me a loop in a case like this means failure. First it does eat some cpu probably negligible amounts but still... you also get an uncertain amount of delay before it starts. So if possible I try really hard to avoid that kind of loops.
And it's also a matter of style for me. But these are my ideas and not necessarily anything someone else has to care about.

tw 07-23-2009 05:48 PM

Quote:

Originally Posted by baf (Post 543976)
Well to me a loop in a case like this means failure. First it does eat some cpu probably negligible amounts but still... you also get an uncertain amount of delay before it starts. So if possible I try really hard to avoid that kind of loops.
And it's also a matter of style for me. But these are my ideas and not necessarily anything someone else has to care about.

I agree with you actually, but really the difference is only one of elegance. something is running a loop-check - be it a process we write, or a process that apple wrote into launchd (I mean, launchd doesn't magically *know* that so many seconds have passed or that a path has changed). for me it's just a play-off between how pretty the code is and how much I have to bang my head on things to make the code prettier. one can't appreciate art with a headache. :)

I did have one idea, which works the issue from the other end. CrashPlan itself may have a launchd plist or cron job that runs it periodically. change that job to call an intermediary script first (which checks en2 and scuttles the operation if it's engaged) and then you don't need to disable CrashPlan at all, or use any loop-check aside from CrashPlan's own loop. I'd need to know more about CP and its scripts, though.

baf 07-23-2009 06:11 PM

Well at least in linux you don't get a loop. The kernel itself checks all disk access to a watched file/directory and raises a notify when that happens. The caller is blocked until that happens so no idle wait at all.
See this man page for inotifywait as a reference.
In osx you have kqueue(2), kevent(2) functions which provide the same mechanism.

tlarkin 07-23-2009 07:03 PM

Well could you watch the path of the usbkext files are located (the built in drivers for usb devices) and if there is any activity with that file could it not execute said script?

baf 07-23-2009 07:16 PM

tlarkin good idea but even better would be to watch the drivers for this device. It looks to me as if they are extras and it ought to be possible to use launchd to watch them.

ilium007 07-23-2009 10:09 PM

Will definitely look into all of these suggestions guys. I certainly don't want to run a loop 24/7 so I will look further into the launchd path monitoring.

ilium007 07-23-2009 10:12 PM

Quote:

Originally Posted by baf (Post 543966)
Usb devices usually show up in /dev
try doing:
modem not connected
Code:

ls /dev >file1
connect modem and do
Code:

ls /dev >file2
diff file1 file2

now you should see if something has shown up.

Thanks for the info, but nothing shows up in /dev - I even tried with another device ( iPhone via USB )

ilium007 07-23-2009 10:16 PM

Quote:

Originally Posted by baf (Post 543992)
tlarkin good idea but even better would be to watch the drivers for this device. It looks to me as if they are extras and it ought to be possible to use launchd to watch them.

Do you know where I start looking in the OSX filesystem for driver files ?

tw 07-24-2009 12:38 AM

ok, I think I've found a promising direction for this (plus I learned something cool in the process). I got thinking about baf's comment about Linux and inotifywait and started checking man pages about notifications; what I found was notifyd and notifyutil. notifyd is the notifications server for the system - it sends out all the notifications of system events for other applications to pick up. notifyutil is a tool for interacting with notifyd. you can use it to register apps to receive particular notifications, and even to send notifications of your own out to the rest of the system. this article gives an overview, and tells you how to put notifyd into debug mode so you can log notifications and figure out what they are; this one is developer-level documentation on the notifications system.

you ought to be able to use this to catch the 'mount device' event, though (since I don't have your device) I can't help you figure out what the notification key is.


All times are GMT -5. The time now is 05:31 PM.

Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2014, vBulletin Solutions, Inc.
Site design © IDG Consumer & SMB; individuals retain copyright of their postings
but consent to the possible use of their material in other areas of IDG Consumer & SMB.