123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167 |
- REM (c) Copyright Barry Kauler, June 2013, bkhome.org
- REM License GPL3 (refer: /usr/share/doc/legal)
- REM libc ref: http://www.gnu.org/software/libc/manual/html_node/Function-Index.html#Function-Index
- REM this little daemon reads kernel uevents.
- REM vovchik: compile like this, reduces executable 34K to 9K...
- REM bacon -o -s -o -Os -o -fdata-sections -o -ffunction-sections -o -Wl,--gc-sections -d /tmp $myfile
- REM 130614 forgot to detect sr0/sr1 devices.
- REM 130629 support clients in new pup_event IPC mechanism.
- REM initialization script... note, RETVAL has exit status.
- SYSTEM "/usr/local/pup_event/frontend_startup"
- IF RETVAL!=0 THEN END 9
- '130629 for reading contents of /tmp/pup_event_ipc...
- PROTO opendir, readdir
- DECLARE dir1 TYPE DIR*
- DECLARE ent1 TYPE struct dirent*
- REM from linux/netlink.h...
- CONST NETLINK_KOBJECT_UEVENT=15
- REM linux/poll.h, only includes asm/poll.h, which only includes asm-generic/poll.h...
- CONST POLLIN=1
- REM C functions, in libc.so. note, I originally used IMPORT, but PROTO is simpler...
- PROTO getpid, socket, bind, poll, recv, printf, strlen, strcmp
- REM struct sockaddr_nl, defined in linux/netlink.h...
- RECORD nls
- LOCAL nl_family TYPE unsigned short
- LOCAL nl_pad TYPE unsigned short
- LOCAL nl_pid TYPE unsigned int
- LOCAL nl_groups TYPE unsigned int
- END RECORD
- REM struct pollfd, defined in asm-generic/poll.h...
- RECORD pfd
- LOCAL fd TYPE int
- LOCAL events TYPE short
- LOCAL revents TYPE short
- END RECORD
- DECLARE buf TYPE char ARRAY 512
- DECLARE eventstatus TYPE int
- DECLARE bufin TYPE char*
- size_char=SIZEOF(char)
- size_buf=size_char*512
- size_us=SIZEOF(unsigned short)
- size_ui=SIZEOF(unsigned int)
- size_nls=(2*size_us)+(2*size_ui)
- REM initialise the nls structure...
- nls.nl_family = AF_NETLINK
- nls.nl_pad = 0
- nls.nl_pid = getpid()
- nls.nl_groups = -1
- REM Open hotplug event netlink socket...
- pfd.events = POLLIN
- pfd.fd = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT)
- IF pfd.fd == -1 THEN END 1
- REM listen to netlink socket...
- retval=bind(pfd.fd, (void *)&nls.nl_family, size_nls)
- IF retval==-1 THEN END 2
- cnt=0
- devevents$=""
- WHILE TRUE DO
- REM 2 second timeout... note, -1 is wait indefinitely.
- eventstatus=poll(&pfd.fd, 1, 1000)
- IF eventstatus==-1 THEN END 3
-
- IF eventstatus==0 THEN
- REM one-second timeout.
- REM graceful exit if shutdown X (see /usr/bin/restartwm,wmreboot,wmpoweroff)...
- IF FILEEXISTS("/tmp/wmexitmode.txt")==1 THEN END 8
- IF devevents$!="" THEN
- exe_change$=CONCAT$("/usr/local/pup_event/frontend_change ",devevents$)
- SYSTEM exe_change$
- '130629 also post block-drive events to any ipc client...
- 'look for any files named /tmp/pup_event_ipc/block_* ...
- dir1=opendir("/tmp/pup_event_ipc")
- IF dir1!=NULL THEN
- WHILE TRUE DO
- ent1=readdir(dir1)
- IF ent1==NULL THEN BREAK
- off1=INSTR((*ent1).d_name,"block_")
- IF off1!=0 THEN
- clientfile$=CONCAT$("/tmp/pup_event_ipc/",(*ent1).d_name)
- outmsg$=CONCAT$(devevents$,"\n")
- USEC
- #define O_WRONLY 00000001
- #define O_APPEND 00002000
- int clientdescr;
- clientdescr=open(clientfile$, O_WRONLY | O_APPEND);
- if (clientdescr>0) {
- int wr=write(clientdescr,outmsg$,strlen(outmsg$));
- close(clientdescr);
- }
- END USEC
- ENDIF
- WEND
- ENDIF
-
- devevents$=""
- ELSE
- REM want to call a pup_event script every four seconds...
- INCR cnt
- IF cnt>=4 THEN
- SYSTEM "/usr/local/pup_event/frontend_timeout"
- cnt=0
- ENDIF
- END IF
- CONTINUE
- END IF
-
- REM get the uevent...
- len = recv(pfd.fd, buf, size_buf, MSG_DONTWAIT)
- IF len==-1 THEN END 4
-
- REM process the uevent...
- REM only add@, remove@, change@ uevents...
- devevent$=""
- IF buf[0]=='a' THEN
- IF buf[1]=='d' THEN
- IF buf[2]=='d' THEN devevent$="add:"
- END IF
- END IF
- IF buf[0]=='r' THEN
- IF buf[1]=='e' THEN
- IF buf[2]=='m' THEN devevent$="rem:"
- END IF
- END IF
- IF buf[0]=='c' THEN
- IF buf[1]=='h' THEN
- IF buf[2]=='a' THEN devevent$="cha:"
- END IF
- END IF
- IF devevent$=="" THEN CONTINUE
-
- REM want uevents that have "SUBSYSTEM=block"...
- REM buf has a sequence of zero-delimited strings...
- i=0
- flag_block=0
- devname$=""
- WHILE i<len DO
- bufin=buf+i
- IF flag_block==1 THEN
- REM ex: DEVNAME=sdc DEVTYPE=disk ex2: DEVNAME=sdc1 DEVTYPE=partition
- IF INSTR(bufin,"DEVNAME")!=0 THEN
- devname$=EXTRACT$(bufin,"DEVNAME=")
- REM ignore loop or ram devices... 130614 fix...
- IF REGEX(devname$,"^sd|^hd|^mmc|^sr")==0 THEN CONTINUE 2
- devevents$=CONCAT$(devevents$,devevent$,devname$," ")
- END IF
- ELSE
- IF strcmp(bufin,"SUBSYSTEM=block")==0 THEN flag_block=1
- END IF
- i = i+strlen(bufin)+1
- WEND
- WEND
|