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

« back to all changes in this revision

Viewing changes to clients/upsrw.c

  • Committer: Bazaar Package Importer
  • Author(s): Reinhard Tartler
  • Date: 2005-07-20 19:48:50 UTC
  • mto: (16.1.1 squeeze)
  • mto: This revision was merged to the branch mainline in revision 4.
  • Revision ID: james.westby@ubuntu.com-20050720194850-oo61wjr33rrx2mre
Tags: upstream-2.0.2
ImportĀ upstreamĀ versionĀ 2.0.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
19
19
 
20
20
#include "common.h"
21
21
 
 
22
#include <pwd.h>
22
23
#include <netdb.h>
23
24
#include <netinet/in.h>
24
25
#include <sys/socket.h>
30
31
        struct  list_t  *next;
31
32
};
32
33
 
33
 
static int old_do_enum(UPSCONN *ups, const char *varname)
34
 
{
35
 
        char    out[SMALLBUF], temp[SMALLBUF];
36
 
 
37
 
        snprintf(out, sizeof(out), "ENUM %s\n", varname);
38
 
 
39
 
        if (upscli_sendline(ups, out, strlen(out)) < 0) {
40
 
                fprintf(stderr, "Enumerate %s failed: %s\n", 
41
 
                        varname, upscli_strerror(ups));
42
 
 
43
 
                return -1;      /* failed */
44
 
        }
45
 
 
46
 
        if (upscli_readline(ups, temp, sizeof(temp)) < 0) {
47
 
                fprintf(stderr, "Enumerate %s failed: %s\n",
48
 
                        varname, upscli_strerror(ups));
49
 
 
50
 
                return -1;
51
 
        }
52
 
 
53
 
        if (strncmp(temp, "ENUM", 4) != 0) {
54
 
                fprintf(stderr, "Bogus reply from server for %s\n", varname);
55
 
                return -1;
56
 
        }
57
 
 
58
 
        if (upscli_readline(ups, temp, sizeof(temp)) < 0) {
59
 
                fprintf(stderr, "Can't get next ENUM value: %s\n",
60
 
                        upscli_strerror(ups));
61
 
 
62
 
                return -1;
63
 
        }
64
 
 
65
 
        while (strcmp(temp, "END") != 0) {
66
 
                printf("Option: %s\n", strstr(temp, "\""));
67
 
 
68
 
                if (upscli_readline(ups, temp, sizeof(temp)) < 0) {
69
 
                        fprintf(stderr, "Can't get next ENUM value: %s\n",
70
 
                                upscli_strerror(ups));
71
 
        
72
 
                        return -1;
73
 
                }
74
 
        }
75
 
 
76
 
        return 0;
77
 
}
78
 
 
79
 
static void usage(char *prog)
 
34
static void usage(const char *prog)
80
35
{
81
36
        printf("Network UPS Tools upsrw %s\n\n", UPS_VERSION);
82
 
        printf("usage: %s [-h]\n", prog);
 
37
        printf("usage: %s [-h]\n", prog);
83
38
        printf("       %s [-s <variable>] [-u <username>] [-p <password>] <ups>\n\n", prog);
84
39
        printf("Demo program to set variables within UPS hardware.\n");
85
 
        printf("\n");
86
 
        printf("  -h            display this help text\n");
 
40
        printf("\n");
 
41
        printf("  -h            display this help text\n");
87
42
        printf("  -s <variable> specify variable to be changed\n");
88
43
        printf("                use -s VAR=VALUE to avoid prompting for value\n");
89
 
        printf("  -u <username> set username for command authentication\n");
90
 
        printf("  -p <password> set password for command authentication\n");
91
 
        printf("\n");
92
 
        printf("  <ups>         UPS identifier - myups@localhost, etc.\n");
 
44
        printf("  -u <username> set username for command authentication\n");
 
45
        printf("  -p <password> set password for command authentication\n");
 
46
        printf("\n");
 
47
        printf("  <ups>         UPS identifier - <upsname>@<hostname>[:<port>]\n");
93
48
        printf("\n");
94
49
        printf("Call without -s to show all possible read/write variables.\n");
95
50
 
96
 
        exit(0);
 
51
        exit(EXIT_SUCCESS);
97
52
}
98
53
 
99
54
static void clean_exit(UPSCONN *ups, char *upsname, char *hostname, int code)
109
64
        exit(code);
110
65
}
111
66
 
112
 
static int old_set(UPSCONN *ups, const char *upsname, const char *varname, 
113
 
        const char *newval)
114
 
{
115
 
        char    temp[SMALLBUF];
116
 
 
117
 
        if (upsname)
118
 
                snprintf(temp, sizeof(temp), "SET %s@%s %s\n", 
119
 
                        varname, upsname, newval);
120
 
        else
121
 
                snprintf(temp, sizeof(temp), "SET %s %s\n", varname, newval);
122
 
 
123
 
        if (upscli_sendline(ups, temp, strlen(temp)) < 0) {
124
 
                fprintf(stderr, "Can't set variable: %s\n", 
125
 
                        upscli_strerror(ups));
126
 
 
127
 
                return 1;
128
 
        }
129
 
 
130
 
        if (upscli_readline(ups, temp, sizeof(temp)) < 0) {
131
 
                fprintf(stderr, "Set variable failed: %s\n", 
132
 
                        upscli_strerror(ups));
133
 
 
134
 
                return 1;
135
 
        }
136
 
 
137
 
        return 0;
138
 
}
139
 
 
140
 
static int new_set(UPSCONN *ups, const char *upsname, const char *varname, 
 
67
static int do_set(UPSCONN *ups, const char *upsname, const char *varname, 
141
68
        const char *newval)
142
69
{
143
70
        char    buf[SMALLBUF], enc[SMALLBUF];
149
76
                fprintf(stderr, "Can't set variable: %s\n", 
150
77
                        upscli_strerror(ups));
151
78
 
152
 
                return 1;
 
79
                return EXIT_FAILURE;
153
80
        }
154
81
 
155
82
        if (upscli_readline(ups, buf, sizeof(buf)) < 0) {
156
83
                fprintf(stderr, "Set variable failed: %s\n", 
157
84
                        upscli_strerror(ups));
158
85
 
159
 
                return 1;
 
86
                return EXIT_FAILURE;
160
87
        }
161
88
 
162
89
        /* FUTURE: status cookies will tie in here */
163
90
        if (strncmp(buf, "OK", 2) != 0) {
164
91
                printf("Unexpected response from upsd: %s\n", buf);
165
 
                return 1;
 
92
                return EXIT_FAILURE;
166
93
        }
167
94
 
168
 
        return 0;
 
95
        return EXIT_SUCCESS;
169
96
}
170
97
 
171
98
static int do_setvar(UPSCONN *ups, const char *varname, char *uin,
172
99
                const char *pass, char *upsname, char *hostname)
173
100
{
174
101
        char    newval[SMALLBUF], temp[SMALLBUF], user[SMALLBUF], *ptr;
 
102
        struct  passwd  *pw;
175
103
 
176
104
        if (uin) {
177
105
                snprintf(user, sizeof(user), "%s", uin);
178
106
        } else {
179
 
 
180
 
                printf("Username: ");
 
107
                memset(user, sizeof(user), '\0');
 
108
 
 
109
                pw = getpwuid(getuid());
 
110
 
 
111
                if (pw)
 
112
                        printf("Username (%s): ", pw->pw_name);
 
113
                else
 
114
                        printf("Username: ");
 
115
 
181
116
                fgets(user, sizeof(user), stdin);
182
117
 
183
118
                /* deal with that pesky newline */
184
119
                if (strlen(user) > 1)
185
120
                        user[strlen(user) - 1] = '\0';
 
121
                else {
 
122
                        if (!pw)
 
123
                                fatalx("No username available - even tried getpwuid");
 
124
        
 
125
                        snprintf(user, sizeof(user), "%s", pw->pw_name);
 
126
                }
186
127
        }
187
128
 
188
129
        /* leaks - use -p when running in valgrind */
192
133
                if (!pass) {
193
134
                        fprintf(stderr, "getpass failed: %s\n", 
194
135
                                strerror(errno));
195
 
                        return 1;
 
136
 
 
137
                        return EXIT_FAILURE;
196
138
                }
197
139
        }
198
140
 
213
155
                fprintf(stderr, "Can't set username: %s\n", 
214
156
                        upscli_strerror(ups));
215
157
 
216
 
                return 1;
 
158
                return EXIT_FAILURE;
217
159
        }
218
160
 
219
161
        if (upscli_readline(ups, temp, sizeof(temp)) < 0) {
224
166
 
225
167
                        fprintf(stderr, "You probably need to upgrade upsd.\n");
226
168
 
227
 
                        clean_exit(ups, upsname, hostname, 1);
 
169
                        clean_exit(ups, upsname, hostname, EXIT_FAILURE);
228
170
                }
229
171
 
230
172
                fprintf(stderr, "Set username failed: %s\n",
231
173
                        upscli_strerror(ups));
232
174
 
233
 
                return 1;
 
175
                return EXIT_FAILURE;
234
176
        }
235
177
 
236
178
        snprintf(temp, sizeof(temp), "PASSWORD %s\n", pass);
239
181
                fprintf(stderr, "Can't set password: %s\n", 
240
182
                        upscli_strerror(ups));
241
183
 
242
 
                return 1;
 
184
                return EXIT_FAILURE;
243
185
        }
244
186
 
245
187
        if (upscli_readline(ups, temp, sizeof(temp)) < 0) {
246
188
                fprintf(stderr, "Set password failed: %s\n", 
247
189
                        upscli_strerror(ups));
248
190
 
249
 
                return 1;
250
 
        }
251
 
 
252
 
        /* no upsname = fallback until 2.0 */
253
 
        if (!upsname)
254
 
                return old_set(ups, upsname, varname, newval);
255
 
 
256
 
        /* also fallback for old variable names */
257
 
        if (!strchr(varname, '.'))
258
 
                return old_set(ups, upsname, varname, newval);
259
 
 
260
 
        return new_set(ups, upsname, varname, newval);
 
191
                return EXIT_FAILURE;
 
192
        }
 
193
 
 
194
        /* no upsname means die */
 
195
        if (!upsname) {
 
196
                fprintf(stderr, "Error: a UPS name must be specified (upsname@hostname)\n");
 
197
                return EXIT_FAILURE;
 
198
        }
 
199
 
 
200
        /* old variable names are no longer supported */
 
201
        if (!strchr(varname, '.')) {
 
202
                fprintf(stderr, "Error: old variable names are not supported\n");
 
203
                return EXIT_FAILURE;
 
204
        }
 
205
 
 
206
        return do_set(ups, upsname, varname, newval);
261
207
}       
262
208
 
263
 
static int old_print_rwlist(UPSCONN *ups, char *upsname, char *hostname)
264
 
{
265
 
        int     typelen;
266
 
        char    *v, *sp, *ptr, vars[SMALLBUF], out[SMALLBUF], temp[SMALLBUF],
267
 
                *type;
268
 
 
269
 
        printf("host: %s\n", hostname);
270
 
 
271
 
        if (upscli_getlist(ups, upsname, UPSCLI_LIST_RW, vars, 
272
 
                sizeof(vars)) < 0) {
273
 
                fprintf(stderr, "Unable to get variable list - %s\n",
274
 
                       upscli_strerror(ups));
275
 
 
276
 
                return 1;
277
 
        }
278
 
 
279
 
        if (strlen(vars) == 0) {
280
 
                fprintf(stderr, "Error: no read/write variables available\n");
281
 
                return 1;
282
 
        }
283
 
 
284
 
        v = vars;
285
 
        ptr = strchr(v, ' ');
286
 
        if (!ptr) {
287
 
                fprintf(stderr, "Broken string from server: %s\n", vars);
288
 
                return 1;
289
 
        }
290
 
 
291
 
        while (v != NULL) {
292
 
                ptr = strchr(v, ' ');
293
 
                if (ptr)
294
 
                        *ptr++ = '\0';
295
 
 
296
 
                /* get description */
297
 
                snprintf(out, sizeof(out), "VARDESC %s\n", v);
298
 
 
299
 
                if (upscli_sendline(ups, out, strlen(out)) < 0) {
300
 
                        fprintf(stderr, "Can't get description of %s: %s\n",
301
 
                                v, upscli_strerror(ups));
302
 
                        return 1;
303
 
                }
304
 
 
305
 
                if (upscli_readline(ups, temp, sizeof(temp)) < 0) {
306
 
                        fprintf(stderr, "Can't get description of %s: %s\n",
307
 
                                v, upscli_strerror(ups));
308
 
                        return 1;
309
 
                }
310
 
 
311
 
                printf("[%s] %s ", v, strstr(temp, "\""));
312
 
 
313
 
                /* now get type */
314
 
                snprintf(out, sizeof(out),
315
 
                        (upsname ? "VARTYPE %s@%s\n" : "VARTYPE %s\n"), v, upsname);
316
 
 
317
 
                if (upscli_sendline(ups, out, strlen(out)) < 0) {
318
 
                        fprintf(stderr, "Can't get type of %s: %s\n",
319
 
                                v, upscli_strerror(ups));
320
 
                        return 1;
321
 
                }
322
 
 
323
 
                if (upscli_readline(ups, temp, sizeof(temp)) < 0) {
324
 
                        fprintf(stderr, "Can't get type of %s: %s\n",
325
 
                                v, upscli_strerror(ups));
326
 
 
327
 
                        return 1;
328
 
                }
329
 
 
330
 
                /* TYPE (ENUM|STRING) <num> */
331
 
 
332
 
                sp = strchr(temp, ' ');
333
 
                if ((!sp) || (strncmp(temp, "TYPE ", 5) != 0)) {
334
 
                        fprintf(stderr, "Unexpected response from server [%s]\n",
335
 
                                temp);
336
 
 
337
 
                        return 1;
338
 
                }
339
 
 
340
 
                *sp++ = '\0';
341
 
 
342
 
                type = sp;
343
 
 
344
 
                /* now make sure we can handle this vartype */
345
 
 
346
 
                sp = strchr(type, ' ');
347
 
 
348
 
                if (!sp) {
349
 
                        fprintf(stderr, "Unexpected vartype from server [%s]\n",
350
 
                                ptr);
351
 
 
352
 
                        return 1;
353
 
                }
354
 
                
355
 
                *sp++ = '\0';
356
 
 
357
 
                typelen = strtol(sp, (char **) NULL, 10);
358
 
 
359
 
                printf("(%s:%d)\n", type, typelen);
360
 
 
361
 
                if (!strcmp(type, "ENUM"))
362
 
                        if (old_do_enum(ups, v) != 0)
363
 
                                return 1;
364
 
 
365
 
                if (!strcmp(type, "STRING")) {
366
 
                        if (upscli_getvar(ups, upsname, v, temp, 
367
 
                                sizeof(temp)) < 0) {
368
 
 
369
 
                                fprintf(stderr, "Can't get value of %s: %s\n",
370
 
                                        temp, upscli_strerror(ups));
371
 
 
372
 
                                return 1;
373
 
                        }
374
 
                                
375
 
                        printf("Value: %s\n", temp);
376
 
                }
377
 
                
378
 
                v = ptr;
379
 
 
380
 
        }
381
 
 
382
 
        return 0;
383
 
}
384
 
 
385
209
static const char *get_data(const char *type, UPSCONN *ups, 
386
210
        const char *upsname, const char *varname)
387
211
{
388
 
        int     ret, numq, numa;
 
212
        int     ret;
 
213
        unsigned int    numq, numa;
389
214
        char    **answer;
390
215
        const   char    *query[4];
391
216
 
419
244
        printf("Value: %s\n", val);
420
245
}
421
246
 
422
 
static void new_do_enum(UPSCONN *ups, const char *upsname, const char *varname)
 
247
static void do_enum(UPSCONN *ups, const char *upsname, const char *varname)
423
248
{
424
 
        int     ret, numq, numa;
 
249
        int     ret;
 
250
        unsigned int    numq, numa;
425
251
        char    **answer, *val;
426
252
        const   char    *query[4], *tmp;
427
253
 
480
306
 
481
307
static void do_type(UPSCONN *ups, const char *upsname, const char *varname)
482
308
{
483
 
        int     i, ret, numq, numa;
 
309
        int     ret;
 
310
        unsigned int    i, numq, numa;
484
311
        char    **answer;
485
312
        const   char    *query[4];
486
313
 
500
327
        for (i = 3; i < numa; i++) {
501
328
 
502
329
                if (!strcasecmp(answer[i], "ENUM")) {
503
 
                        new_do_enum(ups, upsname, varname);
 
330
                        do_enum(ups, upsname, varname);
504
331
                        return;
505
332
                }
506
333
 
536
363
        printf("\n");
537
364
}       
538
365
 
539
 
static int new_print_rwlist(UPSCONN *ups, char *upsname, char *hostname)
 
366
static int print_rwlist(UPSCONN *ups, const char *upsname)
540
367
{
541
 
        int     ret, numq, numa;
 
368
        int     ret;
 
369
        unsigned int    numq, numa;
542
370
        const   char    *query[2];
543
371
        char    **answer;
544
372
        struct  list_t  *lhead, *llast, *ltmp, *lnext;
545
373
 
 
374
        /* the upsname is now required */
 
375
        if (!upsname) {
 
376
                fprintf(stderr, "Error: a UPS name must be specified (upsname@hostname)\n");
 
377
                return EXIT_FAILURE;
 
378
        }
 
379
 
546
380
        llast = lhead = NULL;
547
381
 
548
382
        query[0] = "RW";
554
388
        if (ret < 0) {
555
389
 
556
390
                /* old upsd --> fall back on old LISTRW technique */
557
 
                if (upscli_upserror(ups) == UPSCLI_ERR_UNKCOMMAND)
558
 
                        return old_print_rwlist(ups, upsname, hostname);
 
391
                if (upscli_upserror(ups) == UPSCLI_ERR_UNKCOMMAND) {
 
392
                        fprintf(stderr, "Error: upsd is too old to support this query\n");
 
393
                        return EXIT_FAILURE;
 
394
                }
559
395
 
560
396
                fprintf(stderr, "Error: %s\n", upscli_strerror(ups));
561
 
                return 1;
 
397
                return EXIT_FAILURE;
562
398
        }
563
399
 
564
400
        ret = upscli_list_next(ups, numq, query, &numa, &answer);
569
405
                if (numa < 4) {
570
406
                        fprintf(stderr, "Error: insufficient data "
571
407
                                "(got %d args, need at least 4)\n", numa);
572
 
                        return 1;
 
408
                        return EXIT_FAILURE;
573
409
                }
574
410
 
575
411
                /* sock this entry away for later */
602
438
                ltmp = lnext;
603
439
        }
604
440
 
605
 
        return 0;
 
441
        return EXIT_SUCCESS;
606
442
}
607
443
 
608
 
static int print_rwlist(UPSCONN *ups, char *upsname, char *hostname)
 
444
static void check_upsdef(const char *ups)
609
445
{
610
 
        /* no upsname = fall back on old methods until 2.0 */
611
 
        if (!upsname)
612
 
                return old_print_rwlist(ups, upsname, hostname);
613
 
 
614
 
        return new_print_rwlist(ups, upsname, hostname);
 
446
        char    *ptr;
 
447
 
 
448
        ptr = strchr(ups, '@');
 
449
 
 
450
        if (ptr)
 
451
                return;
 
452
 
 
453
        fprintf(stderr, "Error: invalid UPS definition.  Required format: upsname@hostname[:port]\n");
 
454
 
 
455
        exit(EXIT_FAILURE);
615
456
}
616
457
 
617
458
int main(int argc, char **argv)
637
478
                        break;
638
479
                case 'V':
639
480
                        printf("Network UPS Tools upsrw %s\n", UPS_VERSION);
640
 
                        exit(0);
 
481
                        exit(EXIT_SUCCESS);
641
482
                default:
642
483
                        usage(prog);
643
484
                        break;
650
491
        if (argc < 1)
651
492
                usage(prog);
652
493
 
653
 
        upscli_splitname(argv[0], &upsname, &hostname, &port);
 
494
        check_upsdef(argv[0]);
 
495
 
 
496
        upsname = hostname = NULL;
 
497
 
 
498
        if (upscli_splitname(argv[0], &upsname, &hostname, &port) != 0)
 
499
                clean_exit(&ups, upsname, hostname, EXIT_FAILURE);
654
500
 
655
501
        if (upscli_connect(&ups, hostname, port, 0) < 0) {
656
502
                fprintf(stderr, "Can't connect: %s\n", upscli_strerror(&ups));
657
 
                clean_exit(&ups, upsname, hostname, 1);
 
503
                clean_exit(&ups, upsname, hostname, EXIT_FAILURE);
658
504
        }
659
505
 
660
506
        /* setting a variable? */
666
512
        }
667
513
 
668
514
        /* if not, get the list of supported read/write variables */
669
 
        ret = print_rwlist(&ups, upsname, hostname);
 
515
        ret = print_rwlist(&ups, upsname);
670
516
 
671
517
        clean_exit(&ups, upsname, hostname, ret);
672
518
 
673
519
        /* NOTREACHED */
674
 
        return 0;
 
520
        exit(EXIT_FAILURE);
675
521
}