]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blob - src/hwinfo/hwscand.c
Signierten GPG-Schluessel importiert.
[people/pmueller/ipfire-2.x.git] / src / hwinfo / hwscand.c
1
2 /* hwscan front end
3 Copyright 2004 by SUSE (<adrian@suse.de>) */
4
5 #include <sys/types.h>
6 #include <sys/ipc.h>
7 #include <sys/msg.h>
8 #include <sys/types.h>
9 #include <sys/stat.h>
10 #include <time.h>
11 #include <unistd.h>
12 #include <fcntl.h>
13 #include <stdlib.h>
14 #include <string.h>
15 #include <stdio.h>
16
17 #include "init_message.h"
18
19 #define TIMEOUT 2
20 #define LONG_TIMEOUT 0
21 #define BUFFERS 1024
22
23 int main( int argc, char **argv )
24 {
25 int ret, i;
26 key_t key = KEY;
27 int msgid;
28 int mode = 0;
29 int dev_nr = 0;
30 int lines = 0;
31 int block, usb, firewire, pci;
32 int dev_last_state[BUFFERS];
33 int dev_counter[BUFFERS];
34 char * command_device[NR_COMMANDS][BUFFERS];
35 time_t command_device_last[NR_COMMANDS][BUFFERS];
36 time_t last;
37 char **commands;
38 char **devices;
39 char buffer[32];
40 message m;
41
42 // are we running already, maybe ?
43 {
44 do {
45 ssize_t r;
46 char b[1024];
47 char link[1024];
48 int fd = open( PID_FILE, O_RDONLY );
49 if ( fd >= 0 && (r=read(fd,b,1023)) > 0 ){
50 close(fd);
51 b[r]='\0';
52 snprintf(link, 1023, "/proc/%s/exe", b);
53 if ( (r=readlink( link, b, 1023 )) > 0 ){
54 b[r]='\0';
55 if ( r<8 )
56 unlink(PID_FILE);
57 else if ( strcmp("/hwscand", b+strlen(b)-8) )
58 unlink(PID_FILE);
59 else
60 exit(1);
61 }else
62 unlink(PID_FILE);
63 }else if ( fd >= 0 )
64 unlink(PID_FILE);
65 } while ( 0 > (ret = open( PID_FILE, O_WRONLY|O_CREAT|O_EXCL, S_IRUSR|S_IWUSR ) ) );
66 sprintf(buffer, "%d", getpid());
67 if ( ret < 0 || write(ret,buffer,strlen(buffer)) <= 0 ){
68 perror("hwscand: unable to write pid file "PID_FILE);
69 exit(1);
70 }
71 close(ret);
72 }
73
74 // initialize ...
75 for ( i=0; i<NR_COMMANDS; i++ ){
76 command_device[i][0] = 0;
77 command_device_last[i][0] = 1;
78 }
79
80 last=block=usb=firewire=pci=0;
81 commands = (char**) malloc( BUFFERS * sizeof(char*) );
82 devices = (char**) malloc( BUFFERS * sizeof(char*) );
83
84 msgid = msgget(key, IPC_CREAT | 0600);
85 if (msgid < 0) {
86 perror("msgget");
87 exit(1);
88 }
89
90 while (1) {
91 if ( last || dev_nr )
92 mode = IPC_NOWAIT;
93 else
94 mode = 0;
95
96 if( msgrcv(msgid, &m, MESSAGE_BUFFER, 1, mode) >= 0 ){
97 char *p = m.mtext;
98
99 if ( p == 0 ){
100 fprintf( stderr, "hwscand: error, zero sized message\n" );
101 }else{
102 if ( p[0] == 'S' && strlen(p) > 1 ){
103 // scan calls
104 char z[2];
105 int c;
106 z[0] = *(p+1);
107 z[1] = '\0';
108 c = atoi(z);
109 if ( c < NR_COMMANDS ){
110 if ( ! command_with_device[c] ){
111 last = time(0L);
112 if ( LONG_TIMEOUT+command_device_last[c][0] < time(0L) )
113 command_device_last[c][0] = 0;
114 }else
115 for ( i=0; i<BUFFERS; i++ ){
116 if ( !command_device[c][i] ){
117 last = time(0L);
118 command_device[c][i] = strdup(p+2);
119 command_device[c][i+1] = 0;
120 command_device_last[c][i] = 0;
121 break;
122 }else if ( !strcmp(command_device[c][i], p+2) ){
123 last = time(0L);
124 if ( LONG_TIMEOUT+command_device_last[c][i] < time(0L) )
125 command_device_last[c][i] = 0;
126 break;
127 }
128 }
129 }
130 }
131 if ( p[0] == 'C' && lines < BUFFERS ){
132 last = time(0L);
133 // config calls
134 commands[lines] = strdup(p+1);
135 lines++;
136 }
137 if ( p[0] == 'A' && dev_nr < BUFFERS ){
138 // add scan devices
139 devices[dev_nr] = strdup(p+1);
140 dev_last_state[dev_nr] = 0;
141 dev_counter[dev_nr] = 0;
142 dev_nr++;
143 }
144 if ( p[0] == 'R' && dev_nr < BUFFERS ){
145 for ( i=0; i<dev_nr; i++ ){
146 if ( !strcmp(p+1, devices[i]) ){
147 int j;
148 free(devices[i]);
149 for ( j=i; j+1<dev_nr; j++ ){
150 devices[j] = devices[j+1];
151 dev_last_state[j] = dev_last_state[j+1];
152 dev_counter[j] = dev_counter[j+1];
153 }
154 dev_nr--;
155 }
156 }
157 }
158 }
159 #if DEBUG
160 printf("CALL RECEIVED %s\n", p);
161 #endif
162 }else{
163 // we do this only in scanning mode ...
164
165 sleep(1);
166 for ( i=0; i<dev_nr; i++ ){
167 if (dev_counter[i]<0) continue;
168 dev_counter[i]++;
169 if ( dev_counter[i] > 5 ){
170 int fd;
171 char buf[MESSAGE_BUFFER];
172 dev_counter[i] = 0;
173 fd = open( devices[i], O_RDONLY );
174 strcpy( buf, "/sbin/hwscan --fast --partition --only=");
175 strcat( buf, devices[i] );
176 if ( fd < 0 ){
177 if ( dev_last_state[i] )
178 system(buf);
179 dev_last_state[i] = 0;
180 }else{
181 if ( dev_last_state[i] == 0)
182 system(buf);
183 dev_last_state[i] = 1;
184 close(fd);
185 }
186 }
187 }
188 }
189
190 if ( last && (last+TIMEOUT <= time(0L)) ){
191 char buf[MESSAGE_BUFFER * NR_COMMANDS];
192 int run_really = 0;
193
194 last=0;
195 strcpy( buf, "/sbin/hwscan --fast --boot --silent" );
196 for ( i=0; i<NR_COMMANDS; i++ ){
197 if ( command_with_device[i] == 0 &&
198 command_device_last[i][0] == 0 ){
199 command_device_last[i][0] = time(0L);
200 strcat( buf, " --");
201 strcat( buf, command_args[i] );
202 run_really = 1;
203 } else {
204 int j;
205 int commappended = 0;
206
207 for ( j=0; j<BUFFERS; j++ ){
208 if ( !command_device[i][j] )
209 break;
210 if ( command_device_last[i][j] == 0 ){
211 if (!commappended) {
212 strcat( buf, " --");
213 strcat( buf, command_args[i] );
214 commappended = 1;
215 }
216 strcat( buf, " --only=" );
217 strcat( buf, command_device[i][j] );
218 command_device_last[i][j] = time(0L);
219 run_really = 1;
220 if (strlen(buf) > sizeof(buf) - MESSAGE_BUFFER)
221 break;
222 }
223 }
224 }
225 if (strlen(buf) > sizeof(buf) - MESSAGE_BUFFER) {
226 last = time(0L); /* call me again */
227 break;
228 }
229 }
230
231 if ( run_really ){
232 #if DEBUG
233 printf("RUN %s\n", buf);
234 #endif
235 system(buf);
236 #if DEBUG
237 printf("RUN quit %s\n", buf);
238 #endif
239 }
240 if ( lines ){
241 for (i=0; i<lines; i++){
242 #if DEBUG
243 printf("CALL DIRECT %s\n", commands[i]);
244 #endif
245 system(commands[i]);
246 #if DEBUG
247 printf("CALL quit %s\n", commands[i]);
248 #endif
249 free(commands[i]);
250 }
251 lines=0;
252 }
253 }
254 }
255
256 return 0;
257 }