configure.ac: add libusb/libusbx support (for xpp)
[dahdi/tools.git] / xpp / astribank_is_starting.c
1 #include "../autoconfig.h"
2 #include <sys/types.h>
3 #include <sys/ipc.h>
4 #include <sys/sem.h>
5 #include <errno.h>
6 #include <getopt.h>
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include <time.h>
11
12 static char             *progname;
13 static const key_t      key_astribanks = 0xAB11A0;
14 static int              debug;
15 static int              verbose;
16 static int              timeout_seconds = 60;
17
18 /* If libc provides no timeout variant: try to do without it: */
19 #ifndef HAVE_SEMTIMEDOP
20 #define  semtimedop(sem, ops, n, timeout)    semop(sem, ops, n)
21 #endif
22
23 static void usage(void)
24 {
25         fprintf(stderr, "Usage: %s [-d] [-t <seconds>] [-a|-r|-w]\n", progname);
26         exit(1);
27 }
28
29 static int absem_get(int createit)
30 {
31         int     flags = (createit) ? IPC_CREAT | 0644 : 0;
32         int     absem;
33
34         if((absem = semget(key_astribanks, 1, flags)) < 0)
35                 absem = -errno;
36         return absem;
37 }
38
39 static int absem_touch(void)
40 {
41         int             absem;
42
43         if((absem = absem_get(1)) < 0) {
44                 perror(__FUNCTION__);
45                 return absem;
46         }
47         if(semctl(absem, 0, SETVAL, 0) < 0) {
48                 perror("SETVAL");
49                 return -errno;
50         }
51         if(debug)
52                 fprintf(stderr, "%s: touched absem\n", progname);
53         if(verbose)
54                 printf("Astribanks initialization is starting\n");
55         return 0;
56 }
57
58 static int absem_remove(void)
59 {
60         int     absem;
61
62         if((absem = absem_get(0)) < 0) {
63                 if(absem == -ENOENT) {
64                         if(debug)
65                                 fprintf(stderr, "%s: absem already removed\n", progname);
66                         return 0;
67                 }
68                 perror(__FUNCTION__);
69                 return absem;
70         }
71         if(semctl(absem, 0, IPC_RMID, 0) < 0) {
72                 perror("RMID");
73                 return -errno;
74         }
75         if(debug)
76                 fprintf(stderr, "%s: removed absem\n", progname);
77         if(verbose)
78                 printf("Astribanks initialization is done\n");
79         return 0;
80 }
81
82 static int absem_wait(void)
83 {
84         int             absem;
85         struct sembuf   sops;
86         long            now;
87         long            start_wait;
88         struct timespec timeout;
89
90         if((absem = absem_get(0)) < 0) {
91                 perror(__FUNCTION__);
92                 return absem;
93         }
94         sops.sem_num = 0;
95         sops.sem_op = -1;
96         sops.sem_flg = 0;
97         start_wait = time(NULL);
98         timeout.tv_sec = timeout_seconds;
99         timeout.tv_nsec = 0;
100         if(semtimedop(absem, &sops, 1, &timeout) < 0) {
101                 switch(errno) {
102                 case EIDRM:     /* Removed -- OK */
103                         break;
104                 case EAGAIN:    /* Timeout -- Report */
105                         fprintf(stderr, "Astribanks waiting timed out\n");
106                         return -errno;
107                 default:        /* Unexpected errors */
108                         perror("semop");
109                         return -errno;
110                 }
111                 /* fall-thgough */
112         }
113         now = time(NULL);
114         if(debug)
115                 fprintf(stderr, "%s: waited on absem %ld seconds\n", progname, now - start_wait);
116         if(verbose)
117                 printf("Finished after %ld seconds\n", now - start_wait);
118         return 0;
119 }
120
121 static int absem_detected(void)
122 {
123         int     absem;
124
125         if((absem = absem_get(0)) < 0) {
126                 if(debug)
127                         fprintf(stderr, "%s: absem does not exist\n", progname);
128                 if(verbose)
129                         printf("No Astribanks are initializing\n");
130                 return absem;
131         }
132         if(debug)
133                 fprintf(stderr, "%s: absem exists\n", progname);
134         if(verbose)
135                 printf("Astribanks are initializing...\n");
136         return 0;
137 }
138
139 int main(int argc, char *argv[])
140 {
141         const char      options[] = "dvarwt:h";
142         int             val;
143
144         progname = argv[0];
145         while (1) {
146                 int     c;
147                 int     t;
148
149                 c = getopt (argc, argv, options);
150                 if (c == -1)
151                         break;
152
153                 switch (c) {
154                         case 'd':
155                                 debug++;
156                                 break;
157                         case 'v':
158                                 verbose++;
159                                 break;
160                         case 't':
161                                 t = atoi(optarg);
162                                 if(t <= 0) {
163                                         fprintf(stderr,
164                                                 "%s: -t expect a positive number of seconds: '%s'\n",
165                                                 progname, optarg);
166                                         usage();
167                                 }
168                                 timeout_seconds = t;
169                                 break;
170                         case 'a':
171                                 if((val = absem_touch()) < 0) {
172                                         fprintf(stderr, "%s: Add failed: %d\n", progname, val);
173                                         return 1;
174                                 }
175                                 return 0;
176                         case 'r':
177                                 if((val = absem_remove()) < 0) {
178                                         fprintf(stderr, "%s: Remove failed: %d\n", progname, val);
179                                         return 1;
180                                 }
181                                 return 0;
182                         case 'w':
183                                 if((val = absem_wait()) < 0) {
184                                         fprintf(stderr, "%s: Wait failed: %d\n", progname, val);
185                                         return 1;
186                                 }
187                                 return 0;
188                         case 'h':
189                         default:
190                                 fprintf(stderr, "Unknown option '%c'\n", c);
191                                 usage();
192                 }
193         }
194         val = absem_detected();
195         return (val == 0) ? 0 : 1;
196 }