~ubuntu-branches/ubuntu/saucy/nut/saucy

« back to all changes in this revision

Viewing changes to models/multilink.c

  • Committer: Bazaar Package Importer
  • Author(s): Arnaud Quette
  • Date: 2004-05-28 13:10:01 UTC
  • mto: (16.1.1 squeeze)
  • mto: This revision was merged to the branch mainline in revision 3.
  • Revision ID: james.westby@ubuntu.com-20040528131001-yj2m9qcez4ya2w14
Tags: upstream-1.4.2
ImportĀ upstreamĀ versionĀ 1.4.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* multilink.c - support for Liebert UPS models via MultiLink cable.
2
 
 
3
 
   Copyright (C) 2001  Rick Lyons <rick@powerup.com.au>
4
 
   Copyright (C) 1999  Russell Kroll <rkroll@exploits.org>
5
 
 
6
 
   This program is free software; you can redistribute it and/or modify
7
 
   it under the terms of the GNU General Public License as published by
8
 
   the Free Software Foundation; either version 2 of the License, or
9
 
   (at your option) any later version.
10
 
 
11
 
   This program is distributed in the hope that it will be useful,
12
 
   but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 
   GNU General Public License for more details.
15
 
 
16
 
   You should have received a copy of the GNU General Public License
17
 
   along with this program; if not, write to the Free Software
18
 
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
 
*/
20
 
 
21
 
#include <errno.h>
22
 
#include <fcntl.h>
23
 
#include <stdio.h>
24
 
#include <signal.h>
25
 
#include <stdlib.h>
26
 
#include <string.h>
27
 
#include <unistd.h>
28
 
#include <sys/file.h>
29
 
#include <sys/stat.h>
30
 
#include <sys/types.h>
31
 
#include <sys/ioctl.h>
32
 
#include <sys/termios.h>
33
 
 
34
 
#define INFO_MAX 8
35
 
 
36
 
#include "config.h"
37
 
#include "proto.h"
38
 
#include "shared.h"
39
 
#include "version.h"
40
 
#include "upscommon.h"
41
 
#include "common.h"
42
 
 
43
 
#define ML_ONBATTERY    0x55
44
 
 
45
 
        int     shmok = 1;
46
 
extern  char    *pidfn;
47
 
 
48
 
void initinfo (void)
49
 
{
50
 
        create_info(INFO_MAX, shmok);
51
 
 
52
 
        /* setup the basics */
53
 
 
54
 
        addinfo (INFO_MFR,"Liebert", FLAG_STRING, 0);
55
 
        addinfo (INFO_MODEL,"MultiLink", FLAG_STRING, 0);
56
 
        addinfo (INFO_STATUS, "", 0, 0);
57
 
}
58
 
 
59
 
/* normal idle loop - keep up with the current state of the UPS */
60
 
void updateinfo (void)
61
 
{
62
 
        int     flags, ob, bl, ret;
63
 
        char    temp[VALSIZE];
64
 
        char    c;
65
 
 
66
 
        ob = 0;
67
 
 
68
 
        c = ML_ONBATTERY;
69
 
        write(upsfd, &c, 1);
70
 
        if (read(upsfd, &c, 1) == 1) {
71
 
                while (read(upsfd, &c, 1) == 1)
72
 
                        continue;
73
 
                if (c == ML_ONBATTERY)
74
 
                        ob = 1;
75
 
        }
76
 
        
77
 
        ret = ioctl (upsfd, TIOCMGET, &flags);
78
 
 
79
 
        if (ret != 0) {
80
 
                upslog(LOG_INFO, "ioctl failed");
81
 
                return;
82
 
        }
83
 
 
84
 
        bl = (flags & TIOCM_CD);
85
 
 
86
 
        strcpy (temp, "");
87
 
 
88
 
        if (bl)
89
 
                strcat (temp, "LB ");   /* low battery */
90
 
 
91
 
        if (ob)
92
 
                strcat (temp, "OB");    /* on battery */
93
 
        else
94
 
                strcat (temp, "OL");    /* on line */
95
 
 
96
 
        setinfo(INFO_STATUS, "%s", temp);
97
 
 
98
 
        writeinfo();
99
 
}
100
 
 
101
 
/* install pointers to functions for msg handlers called from msgparse */
102
 
void setuphandlers(void)
103
 
{
104
 
        /* TODO: future */
105
 
}
106
 
 
107
 
void usage(char *prog)
108
 
{
109
 
        printf ("usage: %s [-h] [-m <model>] [-M <mfr>] <device>\n", prog);
110
 
        printf ("Example: %s /dev/ttyS0\n", prog);
111
 
}
112
 
 
113
 
void help(char *prog)
114
 
{
115
 
        printf ("usage: %s [-h] [-m <model>] [-M <mfr>] <device>\n", prog);
116
 
        printf ("\n");
117
 
        printf ("-h         - display this help\n");
118
 
        printf ("-m <model> - set model name to <model>\n");
119
 
        printf ("-M <mfr>   - set manufacturer name to <mfr>\n");
120
 
        printf ("<device>   - /dev entry corresponding to UPS port\n");
121
 
}
122
 
 
123
 
/*  Open the serial port.  The upscommon routines aren't used because
124
 
    they lose bits off the MCR required to make TX/RX work, and we
125
 
    set up the port to make use of VMIN/VTIME.
126
 
*/
127
 
void
128
 
open_serial_ml(char *port)
129
 
{
130
 
        int     flags;
131
 
        struct termios tio;
132
 
 
133
 
        signal(SIGALRM, openfail);
134
 
        alarm(3);
135
 
 
136
 
        if ((upsfd = open(port, O_RDWR)) == -1)
137
 
                fatal("Unable to open %s", port);
138
 
 
139
 
        alarm(0);
140
 
 
141
 
        lockport(upsfd, port);
142
 
 
143
 
        if (ioctl(upsfd, TIOCMGET, &flags))
144
 
                fatal("get ioctl");
145
 
        flags |= TIOCM_RTS;
146
 
        if (ioctl(upsfd, TIOCMSET, &flags))
147
 
                fatal("set ioctl");
148
 
 
149
 
        tcgetattr(upsfd, &tio);
150
 
        cfmakeraw(&tio);
151
 
        tio.c_cc[VMIN] = 0;
152
 
        tio.c_cc[VTIME] = 1;
153
 
        tcsetattr(upsfd, TCSANOW, &tio);
154
 
}
155
 
 
156
 
int main (int argc, char **argv)
157
 
{
158
 
        char    *portname, *prog, *forcemodel = NULL, *forcemfr = NULL;
159
 
        int     i;
160
 
 
161
 
        printf ("Network UPS Tools - Liebert MultiLink UPS driver 1.0 (%s)\n", UPS_VERSION);
162
 
        openlog ("multilink", LOG_PID, LOG_FACILITY);
163
 
        prog = argv[0];
164
 
        
165
 
        while ((i = getopt(argc, argv, "+hm:M:")) != EOF) {
166
 
                switch (i) {
167
 
                        case 'h':
168
 
                                help (prog);
169
 
                                exit (1);
170
 
                                break;
171
 
                        case 'm':
172
 
                                forcemodel = optarg;
173
 
                                break;
174
 
                        case 'M':
175
 
                                forcemfr = optarg;
176
 
                                break;
177
 
                        default:
178
 
                                usage (prog);
179
 
                                break;
180
 
                }
181
 
        }
182
 
 
183
 
        argc -= optind;
184
 
        argv += optind;
185
 
 
186
 
        if (argc != 1) {
187
 
                help (prog);
188
 
                exit (1);
189
 
        }
190
 
 
191
 
        droproot();
192
 
 
193
 
        portname = NULL;
194
 
        for (i = strlen(argv[0]); i >= 0; i--)
195
 
                if (argv[0][i] == '/') {
196
 
                        portname = &argv[0][i+1];
197
 
                        break;
198
 
                }
199
 
 
200
 
        if (portname == NULL) {
201
 
                printf ("Unable to abbreviate %s\n", argv[0]);
202
 
                exit (1);
203
 
        }
204
 
 
205
 
        snprintf (statefn, sizeof(statefn), "%s/multilink-%s", STATEPATH,
206
 
                  portname);
207
 
        open_serial_ml(argv[0]);
208
 
 
209
 
        initinfo();
210
 
 
211
 
        /* replace model/mfr info if specified on command line */
212
 
        if (forcemfr)
213
 
                setinfo(INFO_MFR, "%s", forcemfr);
214
 
 
215
 
        if (forcemodel)
216
 
                setinfo(INFO_MODEL, "%s", forcemodel);
217
 
 
218
 
        createmsgq();   /* try to create IPC message queue */
219
 
 
220
 
        setuphandlers();
221
 
 
222
 
        background();
223
 
 
224
 
        pidfn = xmalloc(SMALLBUF);
225
 
        snprintf(pidfn, sizeof(pidfn), "multilink-%s", portname);
226
 
        writepid(pidfn);
227
 
 
228
 
        for (;;) {
229
 
                updateinfo();
230
 
 
231
 
                /* wait up to 2 seconds for a message from the upsd */
232
 
 
233
 
                if (getupsmsg(2))
234
 
                        upslogx(LOG_INFO, "Received a message from upsd");
235
 
        }
236
 
}