1 /*-
2 * Copyright (c) 1995-2006 Ederson de Moura <ederbs@ederbs.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 */
27
28 #include <stdio.h> /* Standard input/output definitions */
29 #include <string.h> /* String function definitions */
30 #include <unistd.h> /* UNIX standard function definitions */
31 #include <fcntl.h> /* File control definitions */
32 #include <errno.h> /* Error number definitions */
33 #include <termios.h> /* POSIX terminal control definitions */
34 #include <syslog.h> /* Definitions for system error logging */
35 #include <stdlib.h> /* exit() definition */
36
37 #define PROG " UpsDaemon"
38 #define VERSION " 1.0"
39
40 #ifndef PLATFORM
41 #define PLARFORM "Unix"
42 #endif
43
44 #define WAIT 5*60
45 #define PORT "/dev/cuad0"
46 #define PID "/var/run/upsdaemon.pid"
47
48 #define SH_BATTERY "/usr/local/libexec/upsdaemon/upsdaemon-alerts -battery"
49 #define SH_DOWN "/usr/local/libexec/upsdaemon/upsdaemon-alerts -down"
50 #define SH_FAILED "/usr/local/libexec/upsdaemon/upsdaemon-alerts -failed"
51 #define SH_RECOVERY "/usr/local/libexec/upsdaemon/upsdaemon-alerts -recovery"
52
53 int makepid(char *s);
54 static void runcommand();
55
main(int argc,char ** argv)56 int main(int argc, char **argv)
57 {
58 int fd;
59 int lstatus;
60
61 int rts_bit = TIOCM_RTS;
62 int dtr_bit = TIOCM_DTR;
63 int pfail = 0;
64
65 int pfcount = 0;
66 int prcount = 0;
67 int blcount = 0;
68
69 char *port = PORT;
70
71 char *down = SH_DOWN;
72 char *battery = SH_BATTERY;
73 char *failed = SH_FAILED;
74 char *recovery = SH_RECOVERY;
75
76
77 if(argc > 2) {
78 errx(1,"Usage: upsdaemon <port serial open>: %s\n", strerror(errno));
79 }
80 if(argc == 2) {
81 port = argv[1];
82 }
83
84 /*
85 *
86 * SGI Pinouts:
87 *
88 * \ o o o o o /
89 * \ o o o o /
90 *
91 * Table SGI 9-Pin DSUB Signals
92 * -----------------------------------------------------------------
93 * | 1 -> Earth Ground | 6 -> DSR - Data Set Ready |
94 * | 2 -> TXD - Transmitted Data | 7 -> GND - Logic Ground |
95 * | 3 -> RXD - Received Data | 8 -> DCD - Data Carrier Detect |
96 * | 4 -> RTS - Request To Send | 9 -> DTR - Data Terminal Ready |
97 * | 5 -> CTS - Clear To Send | |
98 * -----------------------------------------------------------------
99 *
100 */
101 if((fd = open(port, O_RDWR | O_NOCTTY | O_NDELAY)) < 0) {
102 perror("Uspdaemon Error: Unable to open " PORT);
103 exit(1);
104 }
105
106 ioctl(fd, TIOCMBIC, &rts_bit);
107 ioctl(fd, TIOCMBIS, &dtr_bit);
108
109 if(daemon(1,1) < 0) {
110 syslog(LOG_ERR, "Alert: It was not possible to be daemon: %m");
111 exit(1);
112 }
113
114 /* Set PID */
115 (void)makepid(PID);
116
117 while(1) {
118 ioctl(fd, TIOCMBIC, &rts_bit);
119 ioctl(fd, TIOCMBIC, &dtr_bit);
120 ioctl(fd, TIOCMBIS, &dtr_bit);
121 ioctl(fd, TIOCMGET, &lstatus);
122
123 if(!(lstatus & TIOCM_CAR)) {
124
125 ++blcount;
126 if(blcount == 6) {
127
128 syslog(LOG_ALERT, "Alert: Without contact with Ups.", PROG VERSION);
129
130 ioctl(fd, TIOCMBIC, &dtr_bit);
131 ioctl(fd, TIOCMBIS, &dtr_bit);
132 ioctl(fd, TIOCMGET, &lstatus);
133
134 if(!(lstatus & TIOCM_CTS)) {
135
136 ioctl(fd, TIOCMBIC, &dtr_bit);
137 ioctl(fd, TIOCMBIS, &dtr_bit);
138 ioctl(fd, TIOCMBIS, &rts_bit);
139
140 /* It fell in the battery Ups */
141 runcommand(battery);
142 sleep(100);
143 }
144 }
145 }
146 else if(!(lstatus & TIOCM_CTS)) {
147 ++pfcount;
148 prcount = 0;
149 blcount = 0;
150 if(pfcount == 3) {
151
152 syslog(LOG_WARNING, "Alert: Failed in the communication with the Ups.", PROG VERSION);
153
154 /* Run failed communication Ups */
155 runcommand(failed);
156 pfail = 1;
157 }
158
159 /* Time (wait - 5) minutes defined */
160 if(pfcount == WAIT) {
161
162 syslog(LOG_ALERT, "Alert: Failed down server.", PROG VERSION);
163
164 ioctl(fd, TIOCMBIC, &dtr_bit);
165 ioctl(fd, TIOCMBIS, &dtr_bit);
166 ioctl(fd, TIOCMBIS, &rts_bit);
167
168 /* Run shutdown server, now */
169 runcommand(down);
170
171 sleep(100);
172 }
173 }
174 else if(pfail == 1) {
175
176 ++prcount;
177 pfcount = 0;
178 if(prcount == 3) {
179
180 /* Run recovery energy */
181 runcommand(recovery);
182
183 pfail = 0;
184 blcount = 0;
185 ioctl(fd, TIOCMBIC, &rts_bit);
186 ioctl(fd, TIOCMBIC, &dtr_bit);
187 ioctl(fd, TIOCMBIS, &dtr_bit);
188 }
189 else blcount = 0;
190 }
191 sleep(1);
192 }
193 }
194
195 /*
196 * Check Routines Shell
197 */
runcommand(shell_script)198 void runcommand(shell_script)
199 char *shell_script;
200 {
201 switch(fork()) {
202 case 0:
203 system(shell_script);
204 exit(0);
205 case -1:
206 errx(1, "Error: Not found the routine: %s", strerror(errno));
207 break;
208 default:
209 break;
210 }
211 }
212
213 /*
214 * To Create PID
215 */
makepid(s)216 int makepid(s)
217 char *s;
218 {
219 FILE *fp;
220 pid_t pid;
221
222 pid = getpid();
223 if((fp = fopen(s, "w")) == NULL)
224 return -1;
225 fprintf(fp, "%lu\n", (u_long)pid);
226 fclose(fp);
227 return 0;
228 }
229