#include #ifndef lint #if 0 static char yysccsid[] = "@(#)yaccpar 1.9 (Berkeley) 02/21/93"; #else __IDSTRING(yyrcsid, "$NetBSD: skeleton.c,v 1.14 1997/10/20 03:41:16 lukem Exp $"); #endif #endif #include #define YYBYACC 1 #define YYMAJOR 1 #define YYMINOR 9 #define YYLEX yylex() #define YYEMPTY -1 #define yyclearin (yychar=(YYEMPTY)) #define yyerrok (yyerrflag=0) #define YYRECOVERING (yyerrflag!=0) #define YYPREFIX "yy" #line 2 "config.y" /* * $Id: config.y,v 2.0.1.5 1996/06/26 18:39:38 alexis Exp alexis $ * * UPS Daemon * The Wild Wind Communications, 1995, 1996 * * See file LICENSE for the distribution terms of this software. */ #include "upsd.h" #include "apc.h" #include static FILE *config; static char *input; static char *pathname; static char *token; static int lineno; struct keyword { char *keyword; int len; int token; }; #line 30 "config.y" typedef union { char *string; double number; struct ups_reg *ups_reg; struct ups_trig *ups_trig; struct event *event; struct action *action; struct when *when; } YYSTYPE; #line 57 "config.c" #define STRING 257 #define NUMBER 258 #define ERROR 259 #define AFTER 260 #define BLOCK 261 #define DELAY 262 #define DEVICE 263 #define DROP 264 #define EQUAL 265 #define EVERY 266 #define EXEC 267 #define FOR 268 #define LESS 269 #define LOG 270 #define MORE 271 #define NOT 272 #define ON 273 #define POLL 274 #define PROTO 275 #define QUEUE 276 #define RAISE 277 #define READ 278 #define SIZE 279 #define SLEEP 280 #define SPEED 281 #define THAN 282 #define TIMEOUT 283 #define TO 284 #define TUNE 285 #define UPS 286 #define WRITE 287 #define LEMERG 288 #define LALERT 289 #define LCRIT 290 #define LERR 291 #define LWARNING 292 #define LNOTICE 293 #define LINFO 294 #define LDEBUG 295 #define NOP 296 #define YYERRCODE 256 short yylhs[] = { -1, 0, 13, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 9, 9, 8, 8, 8, 8, 1, 1, 1, 1, 16, 16, 16, 17, 17, 17, 18, 18, 18, 19, 19, 19, 12, 2, 2, 4, 4, 3, 3, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 11, 10, 5, 5, 5, 5, 5, 5, 5, 5, 5, }; short yylen[] = { 2, 2, 10, 1, 2, 0, 2, 2, 6, 4, 6, 6, 4, 1, 2, 6, 8, 8, 4, 1, 1, 1, 1, 1, 2, 1, 1, 2, 1, 1, 2, 2, 2, 3, 2, 3, 0, 2, 0, 2, 0, 2, 1, 2, 2, 2, 2, 2, 3, 3, 3, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, }; short yydefred[] = { 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 37, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 25, 28, 0, 0, 0, 19, 20, 21, 22, 39, 0, 35, 0, 0, 0, 0, 0, 0, 0, 52, 42, 0, 53, 0, 0, 30, 27, 24, 0, 31, 34, 0, 0, 41, 55, 44, 45, 56, 57, 58, 59, 60, 61, 62, 63, 0, 54, 47, 46, 51, 0, 18, 43, 0, 0, 33, 0, 0, 50, 48, 49, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 17, 16, 6, 0, 0, 7, 0, 2, 4, 0, 0, 0, 12, 0, 0, 0, 0, 0, 8, 11, 10, }; short yydgoto[] = { 2, 30, 7, 37, 17, 71, 46, 47, 48, 9, 14, 15, 10, 3, 99, 100, 31, 32, 33, 34, }; short yysindex[] = { -265, -227, 0, -249, -2, -222, -215, -209, 0, -249, -79, -212, 0, 0, -200, -28, -192, -186, 0, -205, 40, -40, -199, -198, -196, -178, 0, 0, 27, 28, -208, 0, 0, 0, 0, 0, -166, 0, -164, -163, -276, -162, -164, -161, -162, 0, 0, -123, 0, -177, -205, 0, 0, 0, -188, 0, 0, -200, -200, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -158, 0, 0, 0, 0, -194, 0, 0, -157, -121, 0, -22, -20, 0, 0, 0, -19, 0, -205, -205, -220, -90, -88, -155, 60, 61, -151, 63, -118, 0, 0, 0, 0, -170, -173, 0, -150, 0, 0, -146, -145, 69, 0, 70, -253, -143, -141, -140, 0, 0, 0, }; short yyrindex[] = { 0, 0, 0, -101, 0, 0, 0, -120, 0, 1, 0, 0, 0, -33, -101, 0, 0, -3, 0, -101, 0, 0, -187, -184, -181, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -138, 0, 0, 0, 0, 0, 0, -101, 0, 0, -101, 0, 0, 0, -179, 0, 0, -101, -101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -101, 0, 0, 0, 0, 0, 0, 0, 0, -101, -101, 2, -101, -101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -85, 0, 0, 0, 0, 0, 0, 0, }; short yygindex[] = { 0, 0, 0, 0, 0, 0, -41, -42, 22, 0, 3, -21, -4, 0, 0, 23, 0, 0, 0, 0, }; #define YYTABLESIZE 269 short yytable[] = { 54, 1, 77, 38, 88, 29, 78, 108, 80, 117, 21, 5, 63, 64, 65, 66, 67, 68, 69, 70, 73, 1, 36, 76, 6, 8, 118, 54, 54, 54, 4, 18, 27, 28, 26, 101, 12, 102, 11, 78, 9, 61, 13, 94, 19, 74, 20, 92, 93, 57, 58, 78, 78, 82, 83, 5, 95, 16, 96, 38, 5, 97, 39, 85, 86, 40, 35, 98, 6, 41, 29, 29, 42, 26, 26, 43, 23, 23, 32, 32, 44, 49, 36, 50, 52, 51, 53, 54, 55, 56, 55, 45, 59, 60, 62, 72, 81, 75, 79, 84, 87, 89, 103, 90, 91, 104, 105, 106, 107, 110, 111, 112, 113, 114, 115, 119, 116, 120, 121, 64, 40, 0, 109, 0, 36, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 5, 0, 38, 0, 38, 39, 94, 39, 40, 38, 40, 6, 41, 6, 41, 42, 0, 42, 43, 95, 43, 96, 0, 44, 97, 44, 36, 0, 36, 0, 98, 5, 0, 5, 45, 38, 45, 38, 39, 9, 39, 40, 0, 40, 6, 41, 6, 41, 42, 0, 42, 43, 9, 43, 9, 0, 44, 9, 44, 0, 0, 0, 0, 9, 0, 0, 0, 45, 0, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 0, 0, 54, 55, 0, 55, 54, 22, 54, 54, 0, 23, 0, 24, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 0, 36, }; short yycheck[] = { 33, 0, 125, 123, 125, 33, 47, 125, 50, 262, 14, 260, 288, 289, 290, 291, 292, 293, 294, 295, 41, 286, 123, 44, 273, 3, 279, 60, 61, 62, 257, 9, 60, 61, 62, 125, 258, 125, 40, 80, 125, 38, 257, 263, 123, 42, 258, 89, 90, 257, 258, 92, 93, 57, 58, 260, 276, 266, 278, 264, 260, 281, 267, 257, 258, 270, 258, 287, 273, 274, 257, 258, 277, 257, 258, 280, 257, 258, 257, 258, 285, 41, 268, 123, 282, 284, 282, 265, 61, 61, 123, 296, 258, 257, 257, 257, 284, 258, 275, 257, 257, 123, 257, 123, 123, 45, 45, 258, 45, 279, 283, 261, 258, 258, 45, 258, 46, 258, 258, 257, 123, -1, 99, -1, 123, -1, -1, 125, -1, -1, -1, -1, -1, -1, -1, -1, -1, 260, -1, 260, -1, 264, -1, 264, 267, 263, 267, 270, 268, 270, 273, 274, 273, 274, 277, -1, 277, 280, 276, 280, 278, -1, 285, 281, 285, 266, -1, 268, -1, 287, 260, -1, 260, 296, 264, 296, 264, 267, 263, 267, 270, -1, 270, 273, 274, 273, 274, 277, -1, 277, 280, 276, 280, 278, -1, 285, 281, 285, -1, -1, -1, -1, 287, -1, -1, -1, 296, -1, 296, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 260, -1, -1, -1, -1, 265, 266, -1, 268, 269, 265, 271, 272, -1, 269, -1, 271, 272, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 266, -1, 268, }; #define YYFINAL 2 #ifndef YYDEBUG #define YYDEBUG 0 #endif #define YYMAXTOKEN 296 #if YYDEBUG char *yyname[] = { "end-of-file",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, "'!'",0,0,0,0,0,0,"'('","')'",0,0,0,"'-'","'.'",0,0,0,0,0,0,0,0,0,0,0,0,0,"'<'", "'='","'>'",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"'{'",0,"'}'",0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,"STRING","NUMBER","ERROR","AFTER","BLOCK","DELAY","DEVICE","DROP", "EQUAL","EVERY","EXEC","FOR","LESS","LOG","MORE","NOT","ON","POLL","PROTO", "QUEUE","RAISE","READ","SIZE","SLEEP","SPEED","THAN","TIMEOUT","TO","TUNE", "UPS","WRITE","LEMERG","LALERT","LCRIT","LERR","LWARNING","LNOTICE","LINFO", "LDEBUG","NOP", }; char *yyrule[] = { "$accept : config", "config : ups events", "ups : UPS STRING '(' NUMBER ')' PROTO STRING '{' port_settings '}'", "port_settings : port_setting", "port_settings : port_settings port_setting", "port_setting :", "port_setting : DEVICE STRING", "port_setting : SPEED NUMBER", "port_setting : READ '-' TIMEOUT NUMBER '.' NUMBER", "port_setting : READ '-' TIMEOUT NUMBER", "port_setting : WRITE '-' BLOCK '-' SIZE NUMBER", "port_setting : WRITE '-' BLOCK '-' DELAY NUMBER", "port_setting : QUEUE '-' SIZE NUMBER", "events : event", "events : events event", "event : ON trigger when '{' actions '}'", "event : ON register condition NUMBER when '{' actions '}'", "event : ON register condition STRING when '{' actions '}'", "event : when '{' actions '}'", "condition : morethan", "condition : lessthan", "condition : equalto", "condition : nequalto", "morethan : MORE", "morethan : MORE THAN", "morethan : '>'", "lessthan : LESS", "lessthan : LESS THAN", "lessthan : '<'", "equalto : EQUAL", "equalto : EQUAL TO", "equalto : '=' '='", "nequalto : NOT EQUAL", "nequalto : NOT EQUAL TO", "nequalto : '!' '='", "when : after every for", "after :", "after : AFTER NUMBER", "every :", "every : EVERY NUMBER", "for :", "for : FOR NUMBER", "actions : action", "actions : actions action", "action : DROP trigger", "action : EXEC STRING", "action : RAISE trigger", "action : POLL register", "action : TUNE register STRING", "action : TUNE register NUMBER", "action : LOG priority STRING", "action : SLEEP NUMBER", "action : NOP", "action : event", "register : STRING", "trigger : STRING", "priority : LEMERG", "priority : LALERT", "priority : LCRIT", "priority : LERR", "priority : LWARNING", "priority : LNOTICE", "priority : LINFO", "priority : LDEBUG", "priority :", }; #endif #ifdef YYSTACKSIZE #undef YYMAXDEPTH #define YYMAXDEPTH YYSTACKSIZE #else #ifdef YYMAXDEPTH #define YYSTACKSIZE YYMAXDEPTH #else #define YYSTACKSIZE 10000 #define YYMAXDEPTH 10000 #endif #endif #define YYINITSTACKSIZE 200 int yydebug; int yynerrs; int yyerrflag; int yychar; short *yyssp; YYSTYPE *yyvsp; YYSTYPE yyval; YYSTYPE yylval; short *yyss; short *yysslim; YYSTYPE *yyvs; int yystacksize; #line 374 "config.y" static struct keyword keywords[] = { {"after", 5, AFTER}, {"alert", 5, LALERT}, {"block", 5, BLOCK}, {"crit", 4, LCRIT}, {"debug", 5, LDEBUG}, {"delay", 5, DELAY}, {"device", 6, DEVICE}, {"drop", 4, DROP}, {"emerg", 5, LEMERG}, {"equal", 5, EQUAL}, {"err", 3, LERR}, {"every", 5, EVERY}, {"exec", 4, EXEC}, {"for", 3, FOR}, {"info", 4, LINFO}, {"less", 4, LESS}, {"log", 3, LOG}, {"more", 4, MORE}, {"nop", 3, NOP}, {"notice", 6, LNOTICE}, {"not", 3, NOT}, {"on", 2, ON}, {"poll", 4, POLL}, {"proto", 5, PROTO}, {"queue", 5, QUEUE}, {"raise", 5, RAISE}, {"read", 4, READ}, {"size", 4, SIZE}, {"sleep", 5, SLEEP}, {"speed", 5, SPEED}, {"than", 4, THAN}, {"timeout", 7, TIMEOUT}, {"to", 2, TO}, {"tune", 4, TUNE}, {"ups", 3, UPS}, {"warning", 7, LWARNING}, {"write", 5, WRITE}, {NULL, 0, 0} }; /* * This is the actual lexical parser. */ int yylex(void) { char *t; struct keyword *k; for(;;) { if((token == NULL) || (*token == '\0')) { lineno++; if((token = fgets(input, MAXINPUTLEN, config)) == NULL) { return 0; } if((t = index(token, '\n')) != NULL) { *t = '\0'; /* Chop the line. */ } } while(isspace(*token)) { /* Skip spaces. */ token++; } if(*token == '#' || *token == '\n' || *token == '\0') { token = NULL; continue; /* Keep reading the file. */ } if(*token == '"') { /* Is it a string? */ token++; if((t = index(token, '"')) == NULL) { /* An unterminated string is treated as */ /* a single double quote character. */ return *(token-1); } *t++ = '\0'; if((yylval.string = xstrdup(token)) == NULL) { return ERROR; } token = t; return STRING; } if(isdigit(*token)) { /* Is it a number? */ yylval.number = strtod(token, &t); token = t; return NUMBER; } for(k = keywords; k->keyword; k++) { if(!strncasecmp(token, k->keyword, k->len)) { token += k->len; return k->token; } } /* Let's return a character. */ t = token++; return *t; } } /* * Error reporting routine. */ void yyerror(string) char *string; { syslog(LOG_ERR, "parse error: %s in file %s, line %d", string, pathname, lineno); } /* * Main function. */ int configure(config_pathname) char *config_pathname; { extern int yyparse(); lineno = 0; pathname = config_pathname; token = NULL; if((input = xalloc(MAXINPUTLEN)) == NULL) { return -1; } if((config = fopen(pathname, "r")) == NULL) { syslog(LOG_ERR, "configure: cannot open %s: %m", pathname); return -1; }; if(yyparse()) { syslog(LOG_ERR, "configure: cannot parse configuration file %s", pathname); return -1; }; fclose(config); xfree(input); return 0; } /* * Allocates space for a new event and fills it according to the * arguments. Returns the pointer onto this newly allocated area * or NULL if failed. */ struct event * newevent(trigger, value, condition, when, actions) struct ups_trig *trigger; struct ups_val *value; int condition; struct when *when; struct action *actions; { register struct event *ep; if((ep = (struct event*) xalloc(sizeof(struct event))) == NULL) { return NULL; } bzero(ep, sizeof(struct event)); if(trigger != NULL) { ep->trigger = trigger->id; } else { ep->trigger = 0; } if(value == NULL && condition != 0) { return NULL; /* Already reported in newval(). */ } ep->v = value; ep->condition = condition; ep->when = when; ep->acts = actions; return ep; } /* * Allocates space for a new action and fills it according to the * arguments. Returns the pointer onto this newly allocated area * or NULL if failed. */ struct action * newaction(type, action) int type; void *action; { register struct action *ap; if((ap = (struct action*)xalloc(sizeof(struct action))) == NULL) { return NULL; } bzero(ap, sizeof(struct action)); ap->type = type; ap->action = action; return ap; } /* * Allocates space for a new value and fills it according to the * arguments. Returns the pointer onto the new value or NULL if * failed. */ struct ups_val * newval(reg, value, type) struct ups_reg *reg; void *value; int type; { register struct ups_val *vp; if(type != reg->type) { yyerror("incorrect value type for this register"); return NULL; } if((vp = xalloc(sizeof(struct ups_val))) == NULL) { return NULL; } bzero(vp, sizeof(struct ups_val)); vp->id = reg->id; if(value == NULL) { return vp; } switch((reg->type & T_TYPE)) { case T_BINARY: bcopy(value, (void *)&vp->val, sizeof(void *)); break; case T_NUMBER: bcopy(value, (void *)&vp->val, sizeof(double)); break; } return vp; } /* * Checks if the value is legal for this UPS. Zero is returned * if legal, non-zero otherwise. -1 is returned upon error. */ int illval(val, reg) struct ups_val *val; struct ups_reg *reg; { register struct ups_val *v; if(reg->id != val->id) { syslog(LOG_ERR, "illval: illegal register supplied for the value"); return -1; } for(v = upsp->model->values; v->id != 0; v++) { if(v->id == reg->id) { switch(reg->type & T_TYPE) { case T_NUMBER: if(val->val.number == v->val.number) { return 0; } break; case T_BINARY: if(v->val.binary == NULL) { return 0; } else if(!bcmp(val->val.binary, v->val.binary, reg->size - reg->prec)) { return 0; } break; default: syslog(LOG_ERR, "illval: incorrect type of legal value"); return -1; } } } return 1; } #line 622 "config.c" /* allocate initial stack or double stack size, up to YYMAXDEPTH */ int yyparse __P((void)); static int yygrowstack __P((void)); static int yygrowstack() { int newsize, i; short *newss; YYSTYPE *newvs; if ((newsize = yystacksize) == 0) newsize = YYINITSTACKSIZE; else if (newsize >= YYMAXDEPTH) return -1; else if ((newsize *= 2) > YYMAXDEPTH) newsize = YYMAXDEPTH; i = yyssp - yyss; if ((newss = (short *)realloc(yyss, newsize * sizeof *newss)) == NULL) return -1; yyss = newss; yyssp = newss + i; if ((newvs = (YYSTYPE *)realloc(yyvs, newsize * sizeof *newvs)) == NULL) return -1; yyvs = newvs; yyvsp = newvs + i; yystacksize = newsize; yysslim = yyss + newsize - 1; return 0; } #define YYABORT goto yyabort #define YYREJECT goto yyabort #define YYACCEPT goto yyaccept #define YYERROR goto yyerrlab int yyparse() { int yym, yyn, yystate; #if YYDEBUG char *yys; if ((yys = getenv("YYDEBUG")) != NULL) { yyn = *yys; if (yyn >= '0' && yyn <= '9') yydebug = yyn - '0'; } #endif yynerrs = 0; yyerrflag = 0; yychar = (-1); if (yyss == NULL && yygrowstack()) goto yyoverflow; yyssp = yyss; yyvsp = yyvs; *yyssp = yystate = 0; yyloop: if ((yyn = yydefred[yystate]) != 0) goto yyreduce; if (yychar < 0) { if ((yychar = yylex()) < 0) yychar = 0; #if YYDEBUG if (yydebug) { yys = 0; if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; if (!yys) yys = "illegal-symbol"; printf("%sdebug: state %d, reading %d (%s)\n", YYPREFIX, yystate, yychar, yys); } #endif } if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 && yyn <= YYTABLESIZE && yycheck[yyn] == yychar) { #if YYDEBUG if (yydebug) printf("%sdebug: state %d, shifting to state %d\n", YYPREFIX, yystate, yytable[yyn]); #endif if (yyssp >= yysslim && yygrowstack()) { goto yyoverflow; } *++yyssp = yystate = yytable[yyn]; *++yyvsp = yylval; yychar = (-1); if (yyerrflag > 0) --yyerrflag; goto yyloop; } if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 && yyn <= YYTABLESIZE && yycheck[yyn] == yychar) { yyn = yytable[yyn]; goto yyreduce; } if (yyerrflag) goto yyinrecovery; goto yynewerror; yynewerror: yyerror("syntax error"); goto yyerrlab; yyerrlab: ++yynerrs; yyinrecovery: if (yyerrflag < 3) { yyerrflag = 3; for (;;) { if ((yyn = yysindex[*yyssp]) && (yyn += YYERRCODE) >= 0 && yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE) { #if YYDEBUG if (yydebug) printf("%sdebug: state %d, error recovery shifting\ to state %d\n", YYPREFIX, *yyssp, yytable[yyn]); #endif if (yyssp >= yysslim && yygrowstack()) { goto yyoverflow; } *++yyssp = yystate = yytable[yyn]; *++yyvsp = yylval; goto yyloop; } else { #if YYDEBUG if (yydebug) printf("%sdebug: error recovery discarding state %d\n", YYPREFIX, *yyssp); #endif if (yyssp <= yyss) goto yyabort; --yyssp; --yyvsp; } } } else { if (yychar == 0) goto yyabort; #if YYDEBUG if (yydebug) { yys = 0; if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; if (!yys) yys = "illegal-symbol"; printf("%sdebug: state %d, error recovery discards token %d (%s)\n", YYPREFIX, yystate, yychar, yys); } #endif yychar = (-1); goto yyloop; } yyreduce: #if YYDEBUG if (yydebug) printf("%sdebug: state %d, reducing by rule %d (%s)\n", YYPREFIX, yystate, yyn, yyrule[yyn]); #endif yym = yylen[yyn]; yyval = yyvsp[1-yym]; switch (yyn) { case 1: #line 65 "config.y" { upsp->eventv = yyvsp[0].event; } break; case 2: #line 73 "config.y" { register struct ups_model **mp; register struct ups_reg *rp; register struct ups_val *vp; for(mp = upslist; *mp != NULL; mp++) { if(!strcmp((*mp)->type, yyvsp[-8].string) && ((*mp)->voltage == (int)yyvsp[-6].number) && !strcmp((*mp)->protocol, yyvsp[-3].string)) { break; } } if(*mp == NULL) { yyerror("uknown ups specification"); YYERROR; } upsp->model = *mp; xfree(yyvsp[-8].string); xfree(yyvsp[-3].string); if((zero_trig = TRIGGERID(0)) == NULL) { yyerror("cannot find the terminating trigger"); YYERROR; } /* Fill up upsp->state. */ if((upsp->state = xalloc((upsp->model->nregs) * sizeof(struct ups_val))) == NULL) { YYERROR; } bzero(upsp->state, sizeof(struct ups_val) * upsp->model->nregs); for(rp = upsp->model->registers, vp = upsp->state; rp->id; rp++, vp++) { vp->id = rp->id; if((rp->type & T_TYPE) == T_BINARY) { if((vp->val.binary = xalloc(rp->size)) == NULL) { YYERROR; } } } } break; case 6: #line 121 "config.y" { if((upsp->port.device = yyvsp[0].string) == NULL) { YYERROR; } } break; case 7: #line 126 "config.y" { upsp->port.ntty.c_ispeed = upsp->port.ntty.c_ospeed = (speed_t) yyvsp[0].number; } break; case 8: #line 130 "config.y" { upsp->port.timeout.tv_sec = (long) yyvsp[-2].number; upsp->port.timeout.tv_usec = (long) yyvsp[0].number; } break; case 9: #line 134 "config.y" { upsp->port.timeout.tv_sec = (long) yyvsp[0].number; upsp->port.timeout.tv_usec = 0; } break; case 10: #line 138 "config.y" { upsp->port.writeblksz = (int) yyvsp[0].number; } break; case 11: #line 141 "config.y" { upsp->port.writedelay.tv_sec = 0; upsp->port.writedelay.tv_usec = (long) yyvsp[0].number; } break; case 12: #line 145 "config.y" { upsp->port.queue.size = (int) yyvsp[0].number; } break; case 13: #line 152 "config.y" { yyval.event = yyvsp[0].event; yyvsp[0].event->next = NULL; } break; case 14: #line 156 "config.y" { register struct event *ep; for(ep = yyvsp[-1].event; ep->next != NULL; ep = ep->next); ep->next = yyvsp[0].event; yyvsp[0].event->next = NULL; yyval.event = yyvsp[-1].event; } break; case 15: #line 166 "config.y" { if((yyval.event = newevent(yyvsp[-4].ups_trig, NULL, 0, yyvsp[-3].when, yyvsp[-1].action)) == NULL) { YYERROR; } } break; case 16: #line 171 "config.y" { if((yyval.event = newevent(NULL, newval(yyvsp[-6].ups_reg, &(yyvsp[-4].number), T_NUMBER), (int) yyvsp[-5].number, yyvsp[-3].when, yyvsp[-1].action)) == NULL) { YYERROR; } } break; case 17: #line 177 "config.y" { if((yyval.event = newevent(NULL, newval(yyvsp[-6].ups_reg, &(yyvsp[-4].string), T_BINARY), ((int) yyvsp[-5].number | C_STRING), yyvsp[-3].when, yyvsp[-1].action)) == NULL) { YYERROR; } } break; case 18: #line 183 "config.y" { if((yyval.event = newevent(NULL, NULL, 0, yyvsp[-3].when, yyvsp[-1].action)) == NULL) { YYERROR; } } break; case 19: #line 191 "config.y" { yyval.number = C_MORE; } break; case 20: #line 192 "config.y" { yyval.number = C_LESS; } break; case 21: #line 193 "config.y" { yyval.number = C_EQUAL; } break; case 22: #line 194 "config.y" { yyval.number = C_NEQUAL; } break; case 35: #line 222 "config.y" { if((yyval.when = xalloc(sizeof(struct when))) == NULL) { YYERROR; } yyval.when->act_after = (time_t) yyvsp[-2].number; yyval.when->act_every = (time_t) yyvsp[-1].number; yyval.when->act_for = (time_t) yyvsp[0].number; } break; case 36: #line 233 "config.y" { yyval.number = 0; } break; case 37: #line 234 "config.y" { yyval.number = yyvsp[0].number; } break; case 38: #line 238 "config.y" { yyval.number = 0; } break; case 39: #line 239 "config.y" { yyval.number = yyvsp[0].number; } break; case 40: #line 243 "config.y" { yyval.number = 0; } break; case 41: #line 244 "config.y" { yyval.number = yyvsp[0].number; } break; case 42: #line 249 "config.y" { yyval.action = yyvsp[0].action; yyvsp[0].action->next = NULL; } break; case 43: #line 253 "config.y" { register struct action *ap; for(ap = yyvsp[-1].action; ap->next != NULL; ap = ap->next); ap->next = yyvsp[0].action; yyvsp[0].action->next = NULL; yyval.action = yyvsp[-1].action; } break; case 44: #line 263 "config.y" { if((yyval.action = newaction(A_DROP, yyvsp[0].ups_trig)) == NULL) { YYERROR; } } break; case 45: #line 268 "config.y" { if((yyval.action = newaction(A_EXEC, yyvsp[0].string)) == NULL) { YYERROR; } } break; case 46: #line 273 "config.y" { if((yyval.action = newaction(A_RAISE, yyvsp[0].ups_trig)) == NULL) { YYERROR; } } break; case 47: #line 278 "config.y" { if((yyval.action = newaction(A_POLL, VALUEID(yyvsp[0].ups_reg->id))) == NULL) { YYERROR; } } break; case 48: #line 283 "config.y" { register struct ups_val *val; if((val = newval(yyvsp[-1].ups_reg, &(yyvsp[0].string), T_BINARY)) == NULL) { YYERROR; } if(illval(val, yyvsp[-1].ups_reg)) { yyerror("illegal value for this ups model"); YYERROR; } if((yyval.action = newaction(A_TUNE, val)) == NULL) { YYERROR; } } break; case 49: #line 296 "config.y" { register struct ups_val *val; if((val = newval(yyvsp[-1].ups_reg, &(yyvsp[0].number), T_NUMBER)) == NULL) { YYERROR; } if(illval(val, yyvsp[-1].ups_reg)) { yyerror("illegal value for this ups model"); YYERROR; } if((yyval.action = newaction(A_TUNE, val)) == NULL) { YYERROR; } } break; case 50: #line 309 "config.y" { register struct message *m; if((m = xalloc(sizeof(struct message))) == NULL) { YYERROR; } m->priority = (int) yyvsp[-1].number; m->message = yyvsp[0].string; if((yyval.action = newaction(A_LOG, m)) == NULL) { YYERROR; } } break; case 51: #line 320 "config.y" { register struct timeval *t; if((t = xalloc(sizeof(struct timeval))) == NULL) { YYERROR; } t->tv_sec = (int) yyvsp[0].number; t->tv_usec = 0; if((yyval.action = newaction(A_SLEEP, t)) == NULL) { YYERROR; } } break; case 52: #line 331 "config.y" { if((yyval.action= newaction(A_NONE, NULL)) == NULL) { YYERROR; } } break; case 53: #line 336 "config.y" { if((yyval.action = newaction(A_EVENT, yyvsp[0].event)) == NULL) { YYERROR; } } break; case 54: #line 344 "config.y" { if((yyval.ups_reg = REGISTERNAME(yyvsp[0].string)) == NULL) { yyerror("incorrect register for this ups"); YYERROR; } } break; case 55: #line 353 "config.y" { if((yyval.ups_trig = TRIGGERNAME(yyvsp[0].string)) == NULL) { yyerror("incorrect trigger for this ups"); YYERROR; } } break; case 56: #line 362 "config.y" { yyval.number = LOG_EMERG; } break; case 57: #line 363 "config.y" { yyval.number = LOG_ALERT; } break; case 58: #line 364 "config.y" { yyval.number = LOG_CRIT; } break; case 59: #line 365 "config.y" { yyval.number = LOG_ERR; } break; case 60: #line 366 "config.y" { yyval.number = LOG_WARNING; } break; case 61: #line 367 "config.y" { yyval.number = LOG_NOTICE; } break; case 62: #line 368 "config.y" { yyval.number = LOG_INFO; } break; case 63: #line 369 "config.y" { yyval.number = LOG_DEBUG; } break; case 64: #line 370 "config.y" { yyval.number = DEFAULT_LOG_PRIORITY; } break; #line 1164 "config.c" } yyssp -= yym; yystate = *yyssp; yyvsp -= yym; yym = yylhs[yyn]; if (yystate == 0 && yym == 0) { #if YYDEBUG if (yydebug) printf("%sdebug: after reduction, shifting from state 0 to\ state %d\n", YYPREFIX, YYFINAL); #endif yystate = YYFINAL; *++yyssp = YYFINAL; *++yyvsp = yyval; if (yychar < 0) { if ((yychar = yylex()) < 0) yychar = 0; #if YYDEBUG if (yydebug) { yys = 0; if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; if (!yys) yys = "illegal-symbol"; printf("%sdebug: state %d, reading %d (%s)\n", YYPREFIX, YYFINAL, yychar, yys); } #endif } if (yychar == 0) goto yyaccept; goto yyloop; } if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 && yyn <= YYTABLESIZE && yycheck[yyn] == yystate) yystate = yytable[yyn]; else yystate = yydgoto[yym]; #if YYDEBUG if (yydebug) printf("%sdebug: after reduction, shifting from state %d \ to state %d\n", YYPREFIX, *yyssp, yystate); #endif if (yyssp >= yysslim && yygrowstack()) { goto yyoverflow; } *++yyssp = yystate; *++yyvsp = yyval; goto yyloop; yyoverflow: yyerror("yacc stack overflow"); yyabort: return (1); yyaccept: return (0); }