03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * CDDL HEADER START
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * The contents of this file are subject to the terms of the
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Common Development and Distribution License, Version 1.0 only
03831d35f7499c87d51205817c93e9a8d42c4baestevel * (the "License"). You may not use this file except in compliance
03831d35f7499c87d51205817c93e9a8d42c4baestevel * with the License.
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
03831d35f7499c87d51205817c93e9a8d42c4baestevel * or http://www.opensolaris.org/os/licensing.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * See the License for the specific language governing permissions
03831d35f7499c87d51205817c93e9a8d42c4baestevel * and limitations under the License.
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * When distributing Covered Code, include this CDDL HEADER in each
03831d35f7499c87d51205817c93e9a8d42c4baestevel * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * If applicable, add the following below this CDDL HEADER, with the
03831d35f7499c87d51205817c93e9a8d42c4baestevel * fields enclosed by brackets "[]" replaced with your own identifying
03831d35f7499c87d51205817c93e9a8d42c4baestevel * information: Portions Copyright [yyyy] [name of copyright owner]
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * CDDL HEADER END
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Use is subject to license terms.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel#pragma ident "%Z%%M% %I% %E% SMI"
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * modem_setup.c: support for the scadm modem_setup option (access to the
03831d35f7499c87d51205817c93e9a8d42c4baestevel * service processor modem - if present)
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <curses.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <libintl.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <pthread.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <signal.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <stdio.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <string.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <time.h> /* required by librsc.h */
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <unistd.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include "librsc.h"
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include "adm.h"
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelextern char *ADM_Get_Var(char *Variable);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic void ADM_Send_Char(char C);
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic void ADM_Modem_Listen();
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic void cleanup();
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baesteveltypedef enum {ST_RESET, ST_IDLE, ST_TILDA} ADM_state_t;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int ADM_Continue;
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int winOn = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic pthread_t modemListen;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelvoid
03831d35f7499c87d51205817c93e9a8d42c4baestevelADM_Process_modem_setup()
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel rscp_msg_t msg;
03831d35f7499c87d51205817c93e9a8d42c4baestevel struct timespec timeout;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel int Input;
03831d35f7499c87d51205817c93e9a8d42c4baestevel ADM_state_t State;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int exitLoop = 1;
03831d35f7499c87d51205817c93e9a8d42c4baestevel char rsc_escape[2];
03831d35f7499c87d51205817c93e9a8d42c4baestevel char string[40];
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel ADM_Start();
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel msg.type = DP_MODEM_CONNECT;
03831d35f7499c87d51205817c93e9a8d42c4baestevel msg.len = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel msg.data = NULL;
03831d35f7499c87d51205817c93e9a8d42c4baestevel ADM_Send(&msg);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel timeout.tv_nsec = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel timeout.tv_sec = ADM_TIMEOUT;
03831d35f7499c87d51205817c93e9a8d42c4baestevel ADM_Recv(&msg, &timeout, DP_MODEM_CONNECT_R,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (dp_modem_connect_r_t));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (*(int *)msg.data != DP_MODEM_PASS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) fprintf(stderr, "\n%s\n\n",
03831d35f7499c87d51205817c93e9a8d42c4baestevel gettext("scadm: could not connect to modem"));
03831d35f7499c87d51205817c93e9a8d42c4baestevel exit(-1);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel ADM_Free(&msg);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* Get the escape char BEFORE starting up the "listen" thread */
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) strcpy(rsc_escape, ADM_Get_Var("escape_char"));
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* Create Listening Thread */
03831d35f7499c87d51205817c93e9a8d42c4baestevel ADM_Continue = 1;
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (pthread_create(&modemListen, NULL,
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void * (*)(void *))ADM_Modem_Listen, (void *)NULL) != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) fprintf(stderr, "\n%s\n\n",
03831d35f7499c87d51205817c93e9a8d42c4baestevel gettext("scadm: couldn't create thread"));
03831d35f7499c87d51205817c93e9a8d42c4baestevel exit(-1);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (signal(SIGINT, cleanup) == SIG_ERR) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) fprintf(stderr, "\n%s\n\n",
03831d35f7499c87d51205817c93e9a8d42c4baestevel gettext("scadm: cleanup() registration failed"));
03831d35f7499c87d51205817c93e9a8d42c4baestevel ADM_Continue = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel exit(-1);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) sprintf(string, gettext("... Type %s. to return to prompt ..."),
03831d35f7499c87d51205817c93e9a8d42c4baestevel rsc_escape);
03831d35f7499c87d51205817c93e9a8d42c4baestevel Input = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel State = ST_RESET;
03831d35f7499c87d51205817c93e9a8d42c4baestevel winOn = 1;
03831d35f7499c87d51205817c93e9a8d42c4baestevel initscr();
03831d35f7499c87d51205817c93e9a8d42c4baestevel noecho();
03831d35f7499c87d51205817c93e9a8d42c4baestevel printw("\n%s\n\n", string);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel while (exitLoop) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel while ((Input = getch()) == ERR);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (Input == 10) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel State = ST_RESET;
03831d35f7499c87d51205817c93e9a8d42c4baestevel ADM_Send_Char('\n');
03831d35f7499c87d51205817c93e9a8d42c4baestevel ADM_Send_Char('\r');
03831d35f7499c87d51205817c93e9a8d42c4baestevel continue;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel switch (State) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel case ST_RESET:
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((char)Input == rsc_escape[0]) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel State = ST_TILDA;
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else {
03831d35f7499c87d51205817c93e9a8d42c4baestevel State = ST_IDLE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel ADM_Send_Char((char)Input);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel case ST_IDLE:
03831d35f7499c87d51205817c93e9a8d42c4baestevel ADM_Send_Char((char)Input);
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel case ST_TILDA:
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((char)Input == '.') {
03831d35f7499c87d51205817c93e9a8d42c4baestevel ADM_Send_Char('~');
03831d35f7499c87d51205817c93e9a8d42c4baestevel ADM_Send_Char('.');
03831d35f7499c87d51205817c93e9a8d42c4baestevel exitLoop = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else {
03831d35f7499c87d51205817c93e9a8d42c4baestevel State = ST_IDLE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel ADM_Send_Char((char)Input);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel default:
03831d35f7499c87d51205817c93e9a8d42c4baestevel State = ST_IDLE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel ADM_Send_Char((char)Input);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel endwin();
03831d35f7499c87d51205817c93e9a8d42c4baestevel winOn = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* Terminate Thread */
03831d35f7499c87d51205817c93e9a8d42c4baestevel ADM_Continue = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) sleep(3); /* Make sure thread has time to 'see' */
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* termination */
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel msg.type = DP_MODEM_DISCONNECT;
03831d35f7499c87d51205817c93e9a8d42c4baestevel msg.len = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel msg.data = NULL;
03831d35f7499c87d51205817c93e9a8d42c4baestevel ADM_Send(&msg);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel timeout.tv_nsec = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel timeout.tv_sec = ADM_TIMEOUT;
03831d35f7499c87d51205817c93e9a8d42c4baestevel ADM_Recv(&msg, &timeout, DP_MODEM_DISCONNECT_R,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (dp_modem_disconnect_r_t));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (*(int *)msg.data != DP_MODEM_PASS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) fprintf(stderr, "\n%s\n\n",
03831d35f7499c87d51205817c93e9a8d42c4baestevel gettext("scadm: could not disconnect from modem"));
03831d35f7499c87d51205817c93e9a8d42c4baestevel ADM_Continue = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel exit(-1);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel ADM_Free(&msg);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel pthread_join(modemListen, NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic void
03831d35f7499c87d51205817c93e9a8d42c4baestevelADM_Send_Char(char C)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel rscp_msg_t Message;
03831d35f7499c87d51205817c93e9a8d42c4baestevel char Data[2];
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel Data[0] = C;
03831d35f7499c87d51205817c93e9a8d42c4baestevel Data[1] = 0x0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel Message.type = DP_MODEM_DATA;
03831d35f7499c87d51205817c93e9a8d42c4baestevel Message.len = 2;
03831d35f7499c87d51205817c93e9a8d42c4baestevel Message.data = Data;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (rscp_send(&Message) != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) fprintf(stderr, "\n%s\n\n",
03831d35f7499c87d51205817c93e9a8d42c4baestevel gettext("scadm: Unable to send modem data to SC"));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (winOn)
03831d35f7499c87d51205817c93e9a8d42c4baestevel endwin();
03831d35f7499c87d51205817c93e9a8d42c4baestevel ADM_Continue = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel exit(-1);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic void
03831d35f7499c87d51205817c93e9a8d42c4baestevelADM_Modem_Listen()
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel rscp_msg_t Message;
03831d35f7499c87d51205817c93e9a8d42c4baestevel struct timespec Timeout;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel while (ADM_Continue) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel Timeout.tv_nsec = 500000000;
03831d35f7499c87d51205817c93e9a8d42c4baestevel Timeout.tv_sec = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (rscp_recv(&Message, &Timeout) != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel continue;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (Message.type != DP_MODEM_DATA) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) fprintf(stderr, "\n%s: 0x%08x:0x%08lx\n\n",
03831d35f7499c87d51205817c93e9a8d42c4baestevel gettext("scadm: SC returned garbage"),
03831d35f7499c87d51205817c93e9a8d42c4baestevel Message.type, Message.len);
03831d35f7499c87d51205817c93e9a8d42c4baestevel exit(-1);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) printf("%s", (char *)Message.data);
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) fflush(stdout);
03831d35f7499c87d51205817c93e9a8d42c4baestevel ADM_Free(&Message);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic void
03831d35f7499c87d51205817c93e9a8d42c4baestevelcleanup()
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel rscp_msg_t msg;
03831d35f7499c87d51205817c93e9a8d42c4baestevel struct timespec timeout;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (winOn)
03831d35f7499c87d51205817c93e9a8d42c4baestevel endwin();
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* Terminate Thread */
03831d35f7499c87d51205817c93e9a8d42c4baestevel ADM_Continue = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel msg.type = DP_MODEM_DISCONNECT;
03831d35f7499c87d51205817c93e9a8d42c4baestevel msg.len = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel msg.data = NULL;
03831d35f7499c87d51205817c93e9a8d42c4baestevel ADM_Send(&msg);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel timeout.tv_nsec = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel timeout.tv_sec = ADM_TIMEOUT;
03831d35f7499c87d51205817c93e9a8d42c4baestevel ADM_Recv(&msg, &timeout, DP_MODEM_DISCONNECT_R,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (dp_modem_disconnect_r_t));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (*(int *)msg.data != DP_MODEM_PASS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) fprintf(stderr, "\n%s\n\n",
03831d35f7499c87d51205817c93e9a8d42c4baestevel gettext("scadm: could not disconnect from modem"));
03831d35f7499c87d51205817c93e9a8d42c4baestevel exit(-1);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel ADM_Free(&msg);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel pthread_join(modemListen, NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel exit(-1);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}