Some "C" Language Codes
back to : William Emmanuel S. Yu (at CE 150 page)
wyu home page

1. System Presentation
2. Software :     __pdf version__         __html version__    
3. Paper :     __pdf version__         __html version__    

4. Acknowledgments
5. "C" Language Codes

back to CE150

Note : Some documents are not posted yet - THC



Section : CONFIG.C
Section : CONTROL.C
Section : MAIN.C
Section : MODULE.C
Section : PAM.C
Section : PASSWD.C
Section : UTIL.C
Section : SCADAD.H


TOP
        
Section : CONFIG.C
/* $Id: config.c,v 1.7 2001/09/24 00:59:02 wyy Exp $ */ /* * config.c * * Remote Sensory Control and Data Acquisition Daemon * * William Emmanuel S. YU * Ateneo de Manila University, Philippines * * See README for more information. */ #include "scadad.h" /** * scada_generic_config () - reading configuration generic settings **/ int scada_generic_config (const char *configfile) { FILE *confd; char buf[BUFSIZE]; char sendpath[MAXLINE]; char number[MAXLINE]; int semid; struct scadadstruct *scadad; char *temp; /* open config file */ if ((confd = fopen(configfile, "r")) == NULL) { printf ("SCADA error: could not open config filename: %s\n", configfile); return -1; } /* read data from config file */ while (fgets (buf, BUFSIZE, confd) != NULL) { /* grab module directory line first */ if ( strncmp (buf, "smssendpath", 11) == 0) { sscanf (buf, "smssendpath %s", sendpath); if (( temp = (char*) malloc (strlen (sendpath) + 1) ) == NULL) { printf ("SCADA error: memory allocation error\n"); exithandl (1); } strcpy (temp, sendpath); /* set the controlpid member of the control structure */ semid = sem_open (SEMKEY); sem_wait (semid); scadad = shm_read (SHMKEY); scadad->sms.sendpath = temp; scadad->sms.status = SERVICE_ON; sem_signal (semid); } /* grab module directory line first */ if ( strncmp (buf, "smsnumber", 9) == 0) { sscanf (buf, "smsnumber %s", number); if (( temp = (char*) malloc (strlen (number) + 1) ) == NULL) { printf ("SCADA error: memory allocation error\n"); exithandl (1); } strcpy (temp, number); /* set the controlpid member of the control structure */ semid = sem_open (SEMKEY); sem_wait (semid); scadad = shm_read (SHMKEY); scadad->sms.number = temp; scadad->sms.status = SERVICE_ON; sem_signal (semid); } } fclose (confd); return 0; } /* scada_generic_config */ /** * * scada_module_config () - read config file settings. the mood configuration * settings are stored in a linked list and the pointer to the head * is returned. * */ struct modulelist *scada_module_config (const char *configfile) { FILE *confd; char buf[BUFSIZE]; struct modulelist *head; struct modulelist *curr; struct modulelist *tempstruct; char *temp; char *temp2; char name[BUFSIZE]; char path[BUFSIZE]; char fullpath[BUFSIZE]; head = curr = tempstruct = NULL; /* open config file */ if ((confd = fopen(configfile, "r")) == NULL) { printf ("SCADA error: could not open config filename: %s\n", configfile); return NULL; } /* read data from config file */ while (fgets (buf, BUFSIZE, confd) != NULL) { /* grab module directory line first */ if ( strncmp (buf, "modpath", 7) == 0) { sscanf (buf, "modpath %s", fullpath); } /* module settings */ if ( strncmp (buf, "module", 6) == 0) { sscanf (buf, "module %s %s", name, path); if (( temp = (char *) malloc (strlen (name) + 1) ) == NULL) { printf ("SCADA error: memory allocation error\n"); } strcpy (temp, name); if (( temp2 = (char *) malloc (strlen (path) + strlen (fullpath) + 2) ) == NULL) { printf ("SCADA error: memory allocation error\n"); } strcpy (temp2, fullpath); strcat (temp2, "/"); strcat (temp2, path); if (( tempstruct = (struct modulelist *) malloc ( sizeof (struct modulelist)) ) == NULL) { printf ("SCADA error: memory allocation error\n"); exithandl (1); } tempstruct->name = temp; tempstruct->path = temp2; if ( head == NULL ) { head = tempstruct; curr = tempstruct; tempstruct->next = NULL; } else { curr->next = tempstruct; tempstruct->next = NULL; curr = tempstruct; } } } fclose (confd); return head; } /* scada_module_config */ /** * * scada_mood_config() - read config file settings. the mood configuration * settings are stored in a linked list and the pointer to the head * is returned. * */ struct moodstruct *scada_mood_config (const char *configfile) { FILE *confd; char buf[BUFSIZE]; struct moodstruct *head; struct moodstruct *curr; struct moodstruct *tempstruct; char *temp; char moodname[BUFSIZE]; int moodnum, lightlvl, templvl, playlist; head = curr = tempstruct = NULL; /* open config file */ if ((confd = fopen(configfile, "r")) == NULL) { printf ("SCADA error: could not open config filename: %s\n", configfile); return NULL; } /* read data from config file */ while (fgets (buf, BUFSIZE, confd) != NULL) { /* mood settings */ if ( strncmp (buf, "mood", 4) == 0) { sscanf (buf, "mood %s %d %d %d %d", moodname, &moodnum, &lightlvl, &templvl, &playlist); if (( temp = (char *) malloc (strlen (moodname) + 1) ) == NULL) { printf ("SCADA error: memory allocation error\n"); } strcpy (temp, moodname); if (( tempstruct = (struct moodstruct *) malloc ( sizeof (struct moodstruct)) ) == NULL) { printf ("SCADA error: memory allocation error\n"); exithandl (1); } tempstruct->moodname = temp; tempstruct->moodnum = moodnum; tempstruct->lightlvl = lightlvl; tempstruct->templvl = templvl; tempstruct->playlist = playlist; if ( head == NULL ) { head = tempstruct; curr = tempstruct; tempstruct->next = NULL; } else { curr->next = tempstruct; tempstruct->next = NULL; curr = tempstruct; } } } fclose (confd); return head; } /* scada_mood_config */ /** * * scada_play_config() - read config file settings. the mood configuration * settings are stored in a linked list and the pointer to the head * is returned. * */ struct playlist *scada_play_config (const char *configfile) { FILE *confd; char buf[BUFSIZE]; struct playlist *head; struct playlist *curr; struct playlist *prev; struct playlist *tempstruct; struct playlist_node *temp_node; struct playlist_node *curr_node; char *temp; char song[BUFSIZE]; int listnum, found; head = curr = tempstruct = NULL; /* open config file */ if ((confd = fopen(configfile, "r")) == NULL) { printf ("SCADA error: could not open config filename: %s\n", configfile); return NULL; } /* read data from config file */ while (fgets (buf, BUFSIZE, confd) != NULL) { /* playlist settings */ if ( strncmp (buf, "playlist", 8) == 0) { sscanf (buf, "playlist %d %s", &listnum, song); if (( temp = (char *) malloc (strlen (song) + 1) ) == NULL) { printf ("SCADA error: memory allocation error\n"); exithandl (1); } strcpy (temp, song); /* generate song entry */ if (( temp_node = (struct playlist_node *) malloc ( sizeof (struct playlist_node)) ) == NULL) { printf ("SCADA error: memory allocation error\n"); exithandl (1); } temp_node->song = temp; temp_node->next = NULL; /* adding entry */ if ( head == NULL ) { /* generate new playlist list */ if (( tempstruct = (struct playlist *) malloc ( sizeof (struct playlist)) ) == NULL) { printf ("SCADA error: memory allocation error\n"); exithandl (1); } tempstruct->id = listnum; tempstruct->list = temp_node; tempstruct->next = NULL; head = tempstruct; curr = tempstruct; } else { /* use existing playlist list */ /* check playlist for playlist existing id */ found = 0; prev = curr = head; while (curr != NULL) { if (curr->id == listnum) { found = 1; break; } prev = curr; curr = curr->next; } /* is play list found? */ if (found == 0) { /* playlist not found in playlist list. generate one. */ if (( tempstruct = (struct playlist *) malloc ( sizeof (struct playlist)) ) == NULL) { printf ("SCADA error: memory allocation error\n"); exithandl (1); } prev->next = tempstruct; tempstruct->id = listnum; tempstruct->list = temp_node; tempstruct->next = NULL; } else { /* playlist found in list */ curr_node = curr->list; while (curr_node->next != NULL) { curr_node = curr_node->next; } curr_node->next = temp_node; } } } } /* while */ fclose (confd); return head; } /* scada_playlist_config() */ /** * * scada_cleanup () - this function does all the housekeeping related * chores such as clearing up memory. * */ void scada_cleanup (struct moodstruct *mood, struct playlist *play, struct modulelist *modules) { struct moodstruct *temp; struct modulelist *tempm; struct playlist *temp2; struct playlist_node *temp3; struct playlist_node *curr; /* walk the moods */ while (mood != NULL) { free (mood->moodname); temp = mood->next; free (mood); mood = temp; } /* walk all the modules */ while (modules != NULL) { free (modules->name); free (modules->path); tempm = modules->next; free (modules); modules = tempm; } /* walk the playlists */ while (play != NULL) { /* move through the songs within playlist */ curr = play->list; while (curr != NULL) { free (curr->song); temp3 = curr->next; free (curr); curr = temp3; } temp2 = play->next; free (play); play = temp2; } } /* scada_cleanup () */ TOP
Section : CONTROL.C
/* $Id: control.c,v 1.11 2001/09/25 16:46:06 wyy Exp $ */ /** * * control.c * * Remote Sensory Control and Data Acquisition Daemon * * William Emmanuel S. YU * Ateneo de Manila University, Philippines * * See README for more information. * **/ #include "scadad.h" #include "libscada/libscada.h" /** * * scada_control() - main interactive portion of the SCADA daemon * **/ int scada_control (register int newsockfd, int semid) { char line[MAXLINE]; char str_operand[BUFSIZE]; char number[BUFSIZE]; char mesg[BUFSIZE]; char inst[BUFSIZE]; int retval, operand, operand2; struct playlist *playlist; struct moodstruct *moodlist; struct scadadstruct *scadad; /* read the input from the user */ *line = 0; readnf (newsockfd, line); /* first do a system synchronization */ if ( system_sync ()) { syslog (LOG_ERR, "SCADA sync error: synchronization error"); } /* grab data from memory mapped segment */ sem_wait (semid); if ( (scadad = shm_read (SHMKEY)) == NULL) { syslog (LOG_ERR, "SCADA shm error: error reading shared memory"); } sem_signal (semid); playlist = scadad->playlist; moodlist = scadad->moodstruct; /* define shutdown command */ if ( strncmp (line, "shutdown", 8) == 0) { sem_wait (semid); scadad = shm_read (SHMKEY); sem_signal (semid); kill (scadad->scadapid, SIGTERM); exit (0); } /* define the send command */ if ( strncmp (line, "send", 4) == 0) { if ( sscanf (line, "send %" OPERAND_LEN "s %" OPERAND_LEN "s", number, mesg) != 2) { writenf (newsockfd, "400 syntax error in send\r\n"); return 1; } send_sms (newsockfd, number, mesg); return 1; } /* define the echo command */ if ( strncmp (line, "echo", 4) == 0) { if ( sscanf (line, "echo %" OPERAND_LEN "s", str_operand) != 1) { writenf (newsockfd, "400 syntax error in echo\r\n"); return 1; } if ( strcmp(str_operand,"") == 0 ) writenf (newsockfd, "400 operand required.\r\n"); else { #ifdef DEBUG syslog (LOG_ERR, "SCADA (echo): %s", str_operand); #endif writenf (newsockfd, "200 %s\r\n", str_operand); } return 1; } /* define the show command */ if ( strncmp (line, "show", 4) == 0) { if ( sscanf (line, "show %" OPERAND_LEN "s", str_operand) != 1) { writenf (newsockfd, "400 syntax error in show\r\n"); return 1; } /* show system command */ if ( strcmp (str_operand, "system") == 0 ) { if ( status (newsockfd) ) { writenf (newsockfd, "400 command error.\r\n"); } return 1; } /* if command is not a default command check modules */ if ( exec_show_module (newsockfd, str_operand, &operand, &operand2) ) { writenf (newsockfd, "300 %s is %s at %d\r\n", str_operand, (operand!=SERVICE_ON)?((operand==SERVICE_OFF) ?"DEACTIVATED":"ERROR"):"ACTIVATED", operand2); return 1; } /* unrecoginzed show command */ writenf (newsockfd, "400 unrecognized show command\r\n"); return 1; } /* define the stop command */ if ( strncmp (line, "stop", 4) == 0) { if ( sscanf (line, "stop %" OPERAND_LEN "s", str_operand) != 1) { writenf (newsockfd, "400 syntax error in stop\r\n"); return 1; } /* stop sound command */ if ( strcmp (str_operand, "play") == 0 ) { if ( scadad->soundstat != SERVICE_ON ) { writenf (newsockfd, "400 No Audio Device in Use.\r\n"); return 1; } if ( play_songlist (newsockfd, 0) ) { writenf (newsockfd, "400 command error.\r\n"); } return 1; } /* stop aircon */ if ( strcmp (str_operand, "aircon") == 0 ) { if ( aircon_stop (newsockfd) ) { writenf (newsockfd, "400 command error.\r\n"); } return 1; } /* if command is not a default command check modules */ if ( exec_set_module (newsockfd, inst, 0, 0) ) { return 1; } /* unrecoginzed stop command */ writenf (newsockfd, "400 unrecognized stop command\r\n"); return 1; } /* define the set command */ if ( strncmp (line, "set", 3) == 0) { retval = sscanf (line, "set %s %d %d", inst, &operand, &operand2); if (( retval != 2 ) && ( retval !=3 )) { writenf (newsockfd, "400 syntax error in set\r\n"); return 1; } /* define the set play command */ if ( strcmp (inst, "play") == 0) { #ifdef DEBUG syslog (LOG_ERR, "DEBUG play: %d", operand); #endif if ( play_songlist (newsockfd, operand) ) { writenf (newsockfd, "400 command error.\r\n"); } return 1; } /* set volume command */ if ( strcmp (inst, "volume") == 0 ) { if ( mixeradj (newsockfd, SOUND_MIXER_VOLUME, operand, operand2 ) ) { writenf (newsockfd, "400 command error.\r\n"); } return 1; } /* set aircon */ if ( strcmp (inst, "aircon") == 0 ) { if ( aircon_start (newsockfd) ) { writenf (newsockfd, "400 command error.\r\n"); } return 1; } /* set mood command */ if ( strcmp (inst, "mood") == 0 ) { #ifdef DEBUG syslog (LOG_ERR, "DEBUG mood: %d", operand); #endif if ( mood (newsockfd, operand ) ) { writenf (newsockfd, "400 command error.\r\n"); } return 1; } /* if command is not a default command check modules */ if ( exec_set_module (newsockfd, inst, operand, operand2) ) { writenf (newsockfd, "300 %s is %s at %d\r\n", inst, (operand!=SERVICE_ON)?((operand==SERVICE_OFF) ?"DEACTIVATED":"ERROR"):"ACTIVATED", operand2); return 1; } /* unrecoginzed set command */ writenf (newsockfd, "400 unrecognized set command\r\n"); return 1; } /* get help information */ if ((strncmp (line, "help", 4) == 0) || (strncmp (line, "?", 1) == 0) ) { writenf (newsockfd, "300 SCADAD v%s.\r\n",VERSION); writenf (newsockfd, "300 ----------------------------\r\n"); writenf (newsockfd, "300 help - displays this message\r\n"); writenf (newsockfd, "300 set lights [1/0] [intensity]\r\n"); writenf (newsockfd, "300 set temp [1/0] [intensity]\r\n"); writenf (newsockfd, "300 set mood [n]\r\n"); writenf (newsockfd, "300 set play [play list number]\r\n"); writenf (newsockfd, "300 set aircon 1\r\n"); writenf (newsockfd, "300 show system\r\n"); writenf (newsockfd, "300 stop play\r\n"); writenf (newsockfd, "300 stop lights\r\n"); writenf (newsockfd, "300 stop temp\r\n"); writenf (newsockfd, "300 stop aircon\r\n"); writenf (newsockfd, "300 quit - exits daemon\r\n"); writenf (newsockfd, "300 ----------------------------.\r\n"); return 1; } /* exiting the daemon */ if ((strncmp (line, "quit", 4) == 0) || (strncmp (line, "exit", 4) == 0) || (strncmp (line, "bye", 3) == 0) ) { return 0; } /* error if unrecognized command */ writenf (newsockfd, "400 unrecognized command\r\n"); return 1; } /* scada_control() */ TOP
Section : MAIN.C
/* $Id: main.c,v 1.26 2001/09/27 08:24:57 wyy Exp $ */ /* * main.c * * Remote Sensory Control and Data Acquisition Daemon * * William Emmanuel S. YU * Ateneo de Manila University, Philippines * * See README for more information. */ #include "scadad.h" #include "libparport/libparport.h" #include "libscada/libscada.h" /* main function */ int main (int argc, char *argv[]) { extern char *optarg; char line[MAXLINE]; char* pidfile; char* configfile; int sockfd, newsockfd, clilen, childpid, opt; int semid, newsemid, scadadconpid, sempp; int on = 1; struct scadadstruct *scadad; struct sockaddr_in cli_addr, serv_addr; struct moodstruct *moodtable; struct modulelist *modulelist; struct playlist *playlist; char user[BUFSIZE]; char pass[BUFSIZE]; /* check command line options */ if (argc <= 1) { usage(); return(0); } /* process the command line options */ while ((opt = getopt(argc, argv, "f:p:vh")) != -1) switch (opt) { case 'v': printf ("SCADAD v%s Copyright 2001 William Emmanuel S. Yu\n", VERSION); return (0); break; case 'f': configfile = optarg; break; case 'p': pidfile = optarg; break; default: case 'h': usage (); return (0); break; } /* initialize semaphore locking mechanism for shared memory access */ if ( (semid = sem_create (SEMKEY, 1)) < 0) { syslog (LOG_ERR,"SCADA error: can't open semaphore"); exit (1); } /* initialize semaphore locking mechanism for parallel port access */ if ( (sempp = sem_create (LPTKEY, 1)) < 0) { syslog (LOG_ERR,"SCADA error: can't open semaphore"); exit (1); } /* create shared memory segment */ sem_wait (semid); scadad = shm_create (SHMKEY); /* initialization routines */ /* set the default values of the control structure */ scadad->soundstat = SERVICE_OFF; scadad->lightstat = SERVICE_OFF; scadad->tempstat = SERVICE_OFF; scadad->airconstat = SERVICE_OFF; scadad->blink = SERVICE_OFF; scadad->aircon.status = SERVICE_OFF; scadad->aircon.main = SERVICE_OFF; scadad->aircon.compressor = SERVICE_OFF; scadad->aircon.ready = SERVICE_OFF; scadad->sms.status = SERVICE_OFF; scadad->sms.sendpath = NULL; scadad->env.blink = SERVICE_OFF; scadad->env.templevel = -1; scadad->env.tempstat = SERVICE_OFF; scadad->env.lightlevel = -1; scadad->env.lightstat = SERVICE_OFF; scadad->env.lightdevstat = SERVICE_OFF; scadad->playlistnum = 0; scadad->moodlevel = 0; scadad->lightlevel = 50; scadad->templevel = 25; scadad->audiopid = 0; scadad->songindex = 0; /** * routines for reading the configuration files. this is not * the most efficient method since the configuration file is * read three times. however, this is done because i have * plans of splitting the configuration file in the future * the system below makes it easy to do so. **/ if ( (modulelist = scada_module_config (configfile)) == NULL ) { printf ("SCADA error: Module Configuration Error.\n"); exithandl (1); } if ( (moodtable = scada_mood_config (configfile)) == NULL ) { printf ("SCADA error: Mood Configuration Error.\n"); exithandl (1); } if ( (playlist = scada_play_config (configfile)) == NULL ) { printf ("SCADA error: Playlist Configuration Error.\n"); exithandl (1); } /* set scada structure after configuration */ scadad->modulelist = modulelist; scadad->moodstruct = moodtable; scadad->playlist = playlist; sem_signal (semid); /* generic configs are read here to prevent loops */ if ( scada_generic_config (configfile) == -1) { printf ("SCADA error: Generic Configuration Error.\n"); exithandl (1); } /* detach daemon and write pid file */ daemon_detach (); daemon_writePID (pidfile); /* initialize string pointers */ *user = *pass = 0; /* before anything else got to catch the exit signals */ (void) signal (SIGHUP, exithandl); (void) signal (SIGINT, exithandl); (void) signal (SIGTERM, exithandl); (void) signal (SIGQUIT, exithandl); /* the SIGCHLD is caught to clean up zombies */ (void) signal (SIGCHLD, sig_child); /* openning syslog for logging writing initial message */ openlog ("scadad", LOG_PID, LOG_LOCAL4); /* openning a tcp socket */ if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { syslog (LOG_ERR, "SCADA error: cannot open stream socket"); close (sockfd); exit (1); } /** * bind ourselves to our local address so that client can * sent messeges to us **/ bzero ((char*) &serv_addr, sizeof (serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = htonl (INADDR_ANY); serv_addr.sin_port = htons (SERV_TCP_PORT); /** * set the socket to reuse the address * i am not very sure about the consequences of using this * function to allow immediate reconnects. it seems to block * existing requests gracefully. **/ setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); /* actual bind command */ if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) { syslog (LOG_ERR, "SCADA error: unable to bind to port"); close (sockfd); exit (1); } /* get the socket file descriptor and pid for proper system shutdown */ sem_wait(semid); scadad->sockfd = sockfd; scadad->scadapid = getpid (); sem_signal(semid); /** * create a daemon control process. this code was written to * allow for unattended hardware software interaction. this * process can be killed by sending a SIGHUP. **/ if ( (scadadconpid = fork ()) < 0) { syslog (LOG_ERR, "SCADA error: unable to spawn control process"); } else if (scadadconpid == 0) { /* restore signals to default values */ (void) signal (SIGHUP, exit); (void) signal (SIGINT, exit); (void) signal (SIGTERM, exit); (void) signal (SIGQUIT, exit); (void) signal (SIGCHLD, SIG_IGN); /* set the controlpid member of the control structure */ semid = sem_open (SEMKEY); sempp = sem_open (LPTKEY); sem_wait (semid); scadad = shm_read (SHMKEY); scadad->controlpid = getpid(); sem_signal (semid); /* get control of the parallel port */ sem_wait (sempp); if ( pin_init_user(LPT1) ) { syslog (LOG_ERR, "SCADA error: unable to access parallel port"); sem_wait (semid); scadad = shm_read (SHMKEY); sem_signal (semid); kill (scadad->scadapid, SIGTERM); exit (0); } /* configure parallel port */ pin_output_mode ( LP_PIN14 | LP_PIN16 | LP_PIN17 ); /* clear data pins by default */ pin_set_data (0, LP_DATA_PINS, 0, 1, 1); sem_signal (sempp); #ifdef DEBUG syslog (LOG_ERR, "DEBUG (control-out): Clearing Output Pins"); #endif /* place control routines here */ while (1) { int status, tmplevel, userlevel, temp, devstat, eblink, blink; int delay = POLLDELAY; int amain, compressor, lever, ready, lightstat; /** * place routines for polling devices * temperature and light sensors must * be read here. scada structure is * set after reading. check sensors here. **/ sem_wait (sempp); /** * temperature sensor code. sends the 100 code to the * control lines of the parallel port to signal and input. * a small delay is placed to prevent a race condition. **/ /* setting temperature sensors */ tmplevel = pin_get_data ( 1, 0, 0 ); tmplevel = ((tmplevel * 50) / 255); if ((tmplevel < 5) || (tmplevel > 45)) { /* retain previous values if error occurs */ sem_wait (semid); tmplevel = scadad->env.templevel; sem_signal (semid); status = SERVICE_ERR; } else status = SERVICE_ON; /* store in scadad structure */ semid = sem_open (SEMKEY); sem_wait (semid); scadad = shm_read (SHMKEY); scadad->env.templevel = tmplevel; scadad->env.tempstat = status; userlevel = scadad->templevel; lever = scadad->airconstat; ready = scadad->aircon.ready; compressor = scadad->aircon.compressor; sem_signal (semid); /** * adjust compressor settings for temperature variations from * the preconfigured temperature. delay is set in the header * file. if temperature is below user defined level then the * compressor is switched on. if the temperature is above the * user defined level then the compressor is switched off. * this routine does not recognize time delays between the * compressors switch on and off. this should be trapped by * hardware. signals should be ignored if not within threshold. **/ if ((tmplevel < userlevel - TEMPVARIATION) && (status != SERVICE_ERR) && (lever == SERVICE_ON) && (ready == SERVICE_ON) && (compressor == SERVICE_ON)) aircon_set (1, 0); if ((tmplevel > userlevel + TEMPVARIATION) && (status != SERVICE_ERR) && (lever == SERVICE_ON) && (ready == SERVICE_ON) && (compressor == SERVICE_OFF)) aircon_set (1, 1); /** * light sensor code. sends the 001 code to the * control lines of the parallel port to signal and input. * a small delay is placed to prevent a race condition. **/ /* setting light sensors */ tmplevel = pin_get_data ( 0, 0, 0 ); tmplevel = ((tmplevel * 50) / 255); if ((tmplevel > 49)) { /* retain previous values if error occurs */ sem_wait (semid); tmplevel = scadad->env.lightlevel; sem_signal (semid); status = SERVICE_ERR; } else status = SERVICE_ON; /* store in scadad structure */ semid = sem_open (SEMKEY); sem_wait (semid); scadad = shm_read (SHMKEY); scadad->env.lightlevel = tmplevel; scadad->env.lightstat = status; userlevel = scadad->lightlevel; lightstat = scadad->lightstat; devstat = scadad->env.lightdevstat; sem_signal (semid); /** * code for controlling the light sensivity. right now the range * of the light values if 6 bits therefore we have level of 0 to 64 * that can be utilized to setting light levels. since, the code * utilized a base of 50 then 64 is normalized to 50. **/ /* turn off the lights */ if ((lightstat == SERVICE_OFF) && (devstat == SERVICE_ON)) { pin_set_level (0, 0, 1, 1); sem_wait (semid); scadad = shm_read (SHMKEY); scadad->env.lightdevstat = SERVICE_OFF; devstat = SERVICE_OFF; sem_signal (semid); #ifdef DEBUG syslog (LOG_ERR, "DEBUG (control-lights): turn off %d %d ", lightstat, devstat); #endif } /* light adjustment code */ if ((tmplevel < userlevel - LIGHTVARIATION) && (tmplevel > userlevel + LIGHTVARIATION) && (status == SERVICE_ON) && (devstat == SERVICE_ON)) { #ifdef DEBUG syslog (LOG_ERR, "DEBUG (control-lights): adjusting %d %d", tmplevel, userlevel); #endif temp = (tmplevel * 63) / 50; pin_set_level (temp, 0, 1, 1); } /* turn on the lights */ if ((lightstat == SERVICE_ON) && (devstat == SERVICE_OFF)) { temp = (userlevel * 63) / 50; pin_set_level (temp, 0, 1, 1); sem_wait (semid); scadad = shm_read (SHMKEY); scadad->env.lightdevstat = SERVICE_ON; devstat = SERVICE_ON; sem_signal (semid); #ifdef DEBUG syslog (LOG_ERR, "DEBUG (control-lights): turn on %d %d - %d", lightstat, devstat, temp); #endif } /** * blinker code **/ sem_wait (semid); scadad = shm_read (SHMKEY); eblink = scadad->env.blink; blink = scadad->blink; sem_signal (semid); if ((eblink == SERVICE_ON) && (blink == SERVICE_ON)) { #ifdef DEBUG syslog (LOG_ERR, "DEBUG (control-lights): blink off"); #endif pin_set_level (userlevel, 0, 1, 1); sem_wait (semid); scadad = shm_read (SHMKEY); scadad->env.blink = SERVICE_OFF; sem_signal (semid); } if ((eblink == SERVICE_OFF) && (blink == SERVICE_ON)) { #ifdef DEBUG syslog (LOG_ERR, "DEBUG (control-lights): blink on"); #endif pin_set_level (0, 0, 1, 1); sem_wait (semid); scadad = shm_read (SHMKEY); scadad->env.blink = SERVICE_ON; sem_signal (semid); } /** * routine for starting the aircon if still off * the next routine is to check if the aircon is on **/ semid = sem_open (SEMKEY); sem_wait (semid); scadad = shm_read (SHMKEY); amain = scadad->aircon.main; status = scadad->airconstat; ready = scadad->aircon.ready; sem_signal (semid); if ((amain == SERVICE_OFF) && (status == SERVICE_ON)) { low_aircon_start(); delay = 0; } if ((amain == SERVICE_ON) && (status == SERVICE_OFF)) { low_aircon_stop(); delay = 0; } sem_signal (sempp); sleep(delay); sem_wait (sempp); /** * blinker code **/ sem_wait (semid); scadad = shm_read (SHMKEY); eblink = scadad->env.blink; blink = scadad->blink; sem_signal (semid); if ((eblink == SERVICE_ON) && (blink == SERVICE_ON)) { #ifdef DEBUG syslog (LOG_ERR, "DEBUG (control-lights): blink off"); #endif pin_set_level (userlevel, 0, 1, 1); sem_wait (semid); scadad = shm_read (SHMKEY); scadad->env.blink = SERVICE_OFF; sem_signal (semid); } if ((eblink == SERVICE_OFF) && (blink == SERVICE_ON)) { #ifdef DEBUG syslog (LOG_ERR, "DEBUG (control-lights): blink on"); #endif pin_set_level (0, 0, 1, 1); sem_wait (semid); scadad = shm_read (SHMKEY); scadad->env.blink = SERVICE_ON; sem_signal (semid); } sem_signal (sempp); } exit(0); } /* end daemon control process */ syslog (LOG_INFO, "SCADA v%s Daemon Started", VERSION); /* let our daemon listen for incoming connections */ listen(sockfd, 5); for ( ; ; ) { /* wait for a connection */ clilen = sizeof (cli_addr); newsockfd = accept (sockfd, (struct sockaddr *) &cli_addr, &clilen); newsemid = sem_open (SEMKEY); /* error getting connection */ if (newsockfd < 0) syslog (LOG_ERR, "SCADA error: accept error"); /* spawn new process for connection */ if ( (childpid = fork ()) < 0) syslog (LOG_ERR, "SCADA error: server fork error"); else if (childpid == 0) { /* close parent's socket and reset child signals */ close (sockfd); (void) signal (SIGCHLD, SIG_IGN); (void) signal (SIGHUP, exit); (void) signal (SIGINT, exit); (void) signal (SIGTERM, exit); (void) signal (SIGQUIT, exit); /* display welcome message */ writenf (newsockfd, "100 SCADAD v%s.\r\n", VERSION); /** * authentication portion of the system. authenticaion * is defined during compile time. there are a few available * authentication modules with this system. replace * the code for the authentication module with the desired * code. sorry no time to make it modular. **/ /* get username */ readnf (newsockfd, line); sscanf (line, "user %" MAX_LEN_USERNAME "s", user) ; if (strlen (user) == 0) { writenf (newsockfd, "400 Username required\r\n"); writenf (newsockfd, "200 Bye.\r\n"); exit (1); } /* get password */ writenf (newsockfd, "Enter Password.\r\n"); readnf (newsockfd, line); sscanf (line, "pass %" MAX_LEN_PASS "s", pass); if ((strlen(pass) > 126) || (strlen(pass) == 0) ) { writenf (newsockfd, "500 Password required\r\n"); writenf (newsockfd, "200 Bye.\r\n"); exit (1); } /* authentication section */ if (scada_authenticate(newsockfd, user, pass) == 0 ) { /* interactive section of the program */ *line = 0; /** * this is the main scada interaction routine. this * will exit when the user desires to quite or * terminate the system **/ while ( scada_control (newsockfd, newsemid) ); } else { writenf (newsockfd, "500 Authentication Failure.\r\n"); } writenf (newsockfd, "200 Bye.\r\n"); /* added to remote waiting children */ close (newsockfd); exit (0); } /* mother process has no need for the client file descriptor */ close (newsockfd); } /* clean up functions */ exithandl (0); } TOP
Section : MODULE.C
/* $Id: module.c,v 1.5 2001/09/23 14:43:46 wyy Exp $ */ /* * module.c * * Remote Sensory Control and Data Acquisition Daemon * * William Emmanuel S. YU * Ateneo de Manila University, Philippines * * See README for more information. */ #include "scadad.h" #include "dlfcn.h" #include "libscada/libscada.h" /* function declaration for dynamically loadable function */ typedef int (*dynfunc_t) (int, int); typedef int (*dynfunc2_t) (int*, int*); /** * * exec_sys_module () - code used to show loadable modules status * **/ int exec_sys_module (char* inst, int *oper, int *oper2){ struct scadadstruct *scadad; struct modulelist *modulelist; int semid; char function[BUFSIZE]; char *libname; void *ptr = NULL; dynfunc2_t func = NULL; /* grab data from memory mapped segment */ semid = sem_open (SEMKEY); sem_wait (semid); scadad = shm_read (SHMKEY); modulelist = scadad->modulelist; sem_signal (semid); /* which module */ while ( (modulelist != NULL) && (strcmp (modulelist->name,inst) ) ) { modulelist = modulelist->next; } if (modulelist != NULL) { strcpy(function,"sys"); strcat(function, modulelist->name); libname = modulelist->path; /* dynamically load library */ if ((ptr=dlopen(libname, RTLD_LAZY))==NULL){ syslog (LOG_ERR, "400 dlopen(%s)->%s\r\n", libname, dlerror()); return 1; } /* dynamically load function */ if ((func = (dynfunc2_t)dlsym(ptr, function))==NULL){ syslog (LOG_ERR, "400 dlopen(%s)->%s\r\n", function, dlerror()); return 1; } /* execute the module */ if ( (*func) (oper, oper2 ) ) { syslog (LOG_ERR, "SCADA error: critical system %s error", inst); return 1; } dlclose (ptr); sem_wait(semid); modulelist->status = *oper; modulelist->level = *oper2; sem_signal(semid); return 1; } return 0; } /** * * exec_show_module () - code used to show loadable modules status * **/ int exec_show_module (register int newsockfd, char* inst, int *oper, int *oper2){ struct scadadstruct *scadad; struct modulelist *modulelist; int semid; char function[BUFSIZE]; char *libname; void *ptr = NULL; dynfunc2_t func = NULL; /* grab data from memory mapped segment */ semid = sem_open (SEMKEY); sem_wait (semid); scadad = shm_read (SHMKEY); modulelist = scadad->modulelist; sem_signal (semid); /* which module */ while ( (modulelist != NULL) && (strcmp (modulelist->name,inst) ) ) { modulelist = modulelist->next; } if (modulelist != NULL) { strcpy(function,"s"); strcat(function, modulelist->name); libname = modulelist->path; /* dynamically load library */ if ((ptr=dlopen(libname, RTLD_LAZY))==NULL){ writenf (newsockfd, "400 dlopen(%s)->%s\r\n", libname, dlerror()); return 1; } /* dynamically load function */ if ((func = (dynfunc2_t)dlsym(ptr, function))==NULL){ writenf (newsockfd, "400 dlopen(%s)->%s\r\n", function, dlerror()); return 1; } /* execute the module */ if ( (*func) (oper, oper2 ) ) { writenf (newsockfd, "400 %s command error.\r\n", inst); return 1; } #ifdef DEBUG syslog (LOG_ERR, "DEBUG %s: %d %d", inst, *oper, *oper2); #endif dlclose (ptr); sem_wait(semid); modulelist->status = *oper; modulelist->level = *oper2; sem_signal(semid); return 1; } return 0; } /** * * exec_set_module () - code used to execute loadable modules * **/ int exec_set_module (register int newsockfd, char* inst, int oper, int oper2){ struct scadadstruct *scadad; struct modulelist *modulelist; int semid; char *function; char *libname; void *ptr = NULL; dynfunc_t func = NULL; /* grab data from memory mapped segment */ semid = sem_open (SEMKEY); sem_wait (semid); scadad = shm_read (SHMKEY); modulelist = scadad->modulelist; sem_signal (semid); /* which module */ while ( (modulelist != NULL) && (strcmp (modulelist->name,inst) ) ) { modulelist = modulelist->next; } if (modulelist != NULL) { function = modulelist->name; libname = modulelist->path; /* dynamically load library */ if ((ptr=dlopen(libname, RTLD_LAZY))==NULL){ writenf (newsockfd, "400 dlopen(%s)->%s\r\n", libname, dlerror()); return 1; } /* dynamically load function */ if ((func = (dynfunc_t)dlsym(ptr, function))==NULL){ writenf (newsockfd, "400 dlopen(%s)->%s\r\n", function, dlerror()); return 1; } /* execute the module */ #ifdef DEBUG syslog (LOG_ERR, "DEBUG %s: %d %d", inst, oper, oper2); #endif if ( (*func) (oper, oper2 ) ) { writenf (newsockfd, "400 %s command error.\r\n", inst); dlclose (ptr); return 1; } dlclose (ptr); return 1; } return 0; } TOP
Section : PAM.C
/* $Id: pam.c,v 1.2 2001/09/11 08:41:27 wyy Exp $ */ /* * pam.c * * Remote Sensory Control and Data Acquisition Daemon * * William Emmanuel S. YU * Ateneo de Manila University, Philippines * * See README for more information. */ #include "scadad.h" #include #include /* function declaration */ int scada_conv (int, const struct pam_message **, struct pam_response **, void *); int scada_pam_auth (void *); /** * * scada_authenticate() - function call to authenticate scada daemon using * linux password authentication modules * */ int scada_authenticate (register int newsockfd, char* user, char* pass) { struct pam_data *app_data; int retval; /* initialize and load values to the app_data structure */ app_data = (struct pam_data *) malloc (sizeof(struct pam_data)); bzero (app_data, sizeof (struct pam_data)); app_data->user = user; app_data->pass = pass; app_data->fd = newsockfd; retval = scada_pam_auth ( (void *)app_data ); free(app_data); return retval; } /* scada_authenticate() */ /** * * scada_pam_auth() - actual authentication function * */ int scada_pam_auth (void *app_data) { pam_handle_t *pamh=NULL; int retval; int sockfd; /* converstation structure */ struct pam_conv conv = { scada_conv, app_data }; sockfd = ((struct pam_data *)app_data)->fd; retval = pam_start("scadad", ((struct pam_data *)app_data)->user, &conv, &pamh); if (retval == PAM_SUCCESS) retval = pam_authenticate(pamh, 0); /* This is where we have been authorized or not. */ if (retval == PAM_SUCCESS) { writenf (sockfd, "200 Authenticated.\r\n"); } else { writenf (sockfd, "500 Not Authenticated.\r\n"); } if (pam_end(pamh,retval) != PAM_SUCCESS) { /* close Linux-PAM */ pamh = NULL; writenf (sockfd, "500 Failed to release authenticator\n"); exit(1); } return ( retval == PAM_SUCCESS ? 0:1 ); /* indicate success */ } /* scada_pam_auth() */ /** * * scada_conv() - scada conversation function for interacting with PAM * libraries * */ int scada_conv (int num_msg, const struct pam_message **msg, struct pam_response **resp, void *appdata_ptr) { int i; struct pam_response *r = calloc(num_msg, sizeof(struct pam_response)); #ifdef DEBUG syslog (LOG_ERR, "DEBUG (PAM) message: %d", msg[0]->msg_style); #endif if (num_msg <= 0) return(PAM_CONV_ERR); if (r == NULL) return(PAM_CONV_ERR); for(i=0; i < num_msg; i++) { if(msg[i]->msg_style == PAM_ERROR_MSG) { syslog(LOG_ERR, "SCADA PAM error: %s", msg[i]->msg); syslog(LOG_ERR, "Failed attempt to change password for %s", ((struct pam_data *)appdata_ptr)->user); exit(1); } r[i].resp_retcode = 0; if(msg[i]->msg_style == PAM_PROMPT_ECHO_OFF || msg[i]->msg_style == PAM_PROMPT_ECHO_ON) { r[i].resp = strdup( ((struct pam_data *)appdata_ptr)->pass); } else { r[i].resp = strdup(""); } } #ifdef DEBUG syslog (LOG_ERR, "DEBUG (PAM) response: %d", r[i].resp_retcode); #endif *resp = r; return PAM_SUCCESS; } /* scada_conv() */ TOP
Section : PASSWD.C
/* $Id: passwd.c,v 1.2 2001/09/11 08:41:27 wyy Exp $ */ /* * passwd.c * * Remote Sensory Control and Data Acquisition Daemon * * William Emmanuel S. YU * Ateneo de Manila University, Philippines * * See README for more information. */ #include "scadad.h" #define _XOPEN_SOURCE #include #include #include /** * * scada_authenticate() - function call to authenticate scada daemon using * linux password authentication modules * */ int scada_authenticate (register int newsockfd, char* user, char* pass) { struct passwd *pwd; if ( (pwd = getpwnam(user)) == NULL) { syslog (LOG_ERR, "SCADA passwd error: auth error for user %s", user); writenf (newsockfd, "500 Not Authenticated.\r\n"); return 1; } #ifdef DEBUG syslog (LOG_ERR, "DEBUG (passwd): %s %s", user, pass); syslog (LOG_ERR, "DEBUG (passwd): %s %s", pwd->pw_passwd, (char *) crypt (pass, pwd->pw_passwd) ); #endif if ( strcmp( pwd->pw_passwd, (char *) crypt (pass, pwd->pw_passwd) ) ) { writenf (newsockfd, "500 Authenticated.\r\n"); return 0; } syslog (LOG_ERR, "SCADA passwd error: auth error for user %s", user); writenf (newsockfd, "500 Not Authenticated.\r\n"); return 1; } /* scada_authenticate() */ TOP
Section : UTIL.C
/* $Id: util.c,v 1.4 2001/09/20 09:44:10 wyy Exp $ */ /* * util.c * * Remote Sensory Control and Data Acquisition Daemon * * William Emmanuel S. YU * Ateneo de Manila University, Philippines * * See README for more information. */ #include "scadad.h" #include "libscada/libscada.h" #include /** * usage() - displays help file */ void usage() { printf ("SCADAD v%s Copyright 2001 William Emmanuel S. Yu\n", VERSION); printf("Usage: scadad [options]\n"); printf("-f \t\tset location of config file\n"); printf("-p \t\tset location of pid file\n"); printf("-v\t\t\tdisplays version information\n"); printf("-h\t\t\tdisplays this help info\n"); printf("\n"); printf("For bugs email: william.s.yu@ieee.org\n"); } /* usage() */ /** * exithandl() - function that is called when a kill signal is received */ void exithandl(int sgn) { int semid, stat; struct scadadstruct* scadad; (void) signal (SIGCHLD, SIG_IGN); semid = sem_open (SEMKEY); sem_wait (semid); if ( (scadad = shm_read (SHMKEY)) == NULL) { syslog (LOG_ERR, "SCADA shm error: error reading shared memory"); } sem_signal (semid); /* kill audio process is alive */ if ( scadad->soundstat == SERVICE_ON ) { kill (scadad->audiopid, SIGHUP); } /* kill aircon is still open */ if (scadad->aircon.main == SERVICE_ON) { low_aircon_stop(); } /* clean-up configuration structures */ scada_cleanup (scadad->moodstruct, scadad->playlist, scadad->modulelist); /* kill control process */ kill (scadad->controlpid, SIGHUP); wait (&stat); /* release socket */ close (scadad->sockfd); /* releasing shared memory space */ /* add delay to prevent race condition */ sleep(1); sem_wait(semid); if ( shm_remove (SHMKEY) ) { syslog (LOG_ERR, "SCADA shm error: error releasing shared memory"); } sem_signal(semid); sem_rm (semid); semid = sem_open (LPTKEY); sem_rm (semid); syslog (LOG_INFO, "SCADA v%s Daemon Stopped", VERSION); closelog (); exit (sgn); } /** * sig_child() - signal handlers for catching dead children processes */ void sig_child(int sgn) { int stat, errno_save; pid_t pid; errno_save = errno; if ( (pid = waitpid(0, &stat, 0)) <= 0) { syslog (LOG_ERR, "SCADA signal error: waitpid error"); } errno = errno_save; return; } /* sig_child() */ /** * daemon_detach() - helper functions to detach daemon from controlling * terminal */ void daemon_detach() { int x; int pgrp; chdir ("/"); /* parent quits; error quits; child continues: */ x = fork (); if ( x > 0 ) exit (0); else if ( x == -1 ) { syslog (LOG_ERR, "SCADA error: server fork error"); exit (-1); } /* Make sure we don't prevent any directory removals or filesystem unmounts. */ chdir ("/"); pgrp = setsid (); if (pgrp == -1) { syslog (LOG_ERR, "SCADA error: cannot detach from controlling terminal"); exit (-2); } } /* * daemon_writePID() - lets the daemon write its PID file * */ void daemon_writePID(const char *pidFilePath) { FILE *pidf; pidf = fopen(pidFilePath,"w"); if( pidf==NULL ) syslog (LOG_INFO,"Could not open PID file %s",pidFilePath); else { fprintf(pidf,"%ld\n",(long)getpid()); fclose(pidf); } syslog (LOG_INFO,"Server running in PID %ld",(long)(getpid())); } /* * writenf() - write to a file descriptor but a little smarter */ void writenf (register int fd, const char* fmt, ...) { char line[MAXLINE], *ptr; int n; va_list args; ptr = line; va_start (args, fmt); vsprintf (ptr, fmt, args); ptr += strlen (ptr); va_end (args); n = strlen (line); if (n >= MAXLINE) n = MAXLINE; writen(fd, line, n); } /* * readnf() - reading from a file descriptor but a bit smarter */ void readnf (register int fd, char *line) { int n; n = readline(fd, line, MAXLINE); if (n == 0) return; else if (n < 0) syslog(LOG_ERR, "str_echo: readline error"); } /* * readn() - reads nbytes of characters from file descriptor fd and * stores then to a location pointed to by ptr. replacement for read(). * returns the number of bytes read. if not returns -1. */ int readn (register int fd, register char *ptr, register int nbytes) { int nleft, nread; nleft = nbytes; while (nleft > 0) { nread = read (fd, ptr, nleft); if (nread < 0) return (nread); else if (nread==0) break; nleft -= nread; ptr += nread; } return (nbytes - nleft); } /* readn() */ /* * writen() - writes nbytes to a location pointed to by a file descriptor * fd. replacement for write(). function returns the length of bytes written * if successful if not it returns -1. */ int writen (register int fd, register char *ptr, register int nbytes) { int nleft, nwritten; nleft = nbytes; while (nleft > 0) { nwritten = write (fd, ptr, nleft); if (nwritten <= 0) return (nwritten); nleft -= nwritten; ptr += nwritten; } return (nbytes - nleft); } /* writen() */ /* * readline() - read an entire line from a file descriptor until a newline. * functions returns the number of characters read but not including the * null character. */ int readline(register int fd, register char *ptr, register int maxlen) { int n, rc; char c; for (n = 1; n < maxlen; n++) { if ((rc = read(fd, &c, 1)) == 1) { *ptr++ = c; if (c == '\n') break; } else if (rc == 0) { if (n == 1) return (0); else break; } else return (-1); } *ptr=0; return (n); } /* readline() */ /* * str_echo() - reads a stream sockets one line at a time, and * writes each line back to the sender. */ void str_echo(int sockfd) { int n; char line[MAXLINE]; for ( ; ; ) { n = readline(sockfd, line, MAXLINE); if (n == 0) return; else if (n < 0) syslog(LOG_ERR, "str_echo: readline error"); if (writen(sockfd, line, n) != n) syslog(LOG_ERR, "str_echo: writen error"); } } /* str_echo() */ TOP
Section : SCADAD.H
/* $Id: scadad.h,v 1.23 2001/09/30 14:23:44 wyy Exp $ */ /* * scadad.h * * Remote Sensory Control and Data Acquisition Daemon * * William Emmanuel S. YU * Ateneo de Manila University, Philippines * * See README for more information. */ /* common defines */ #define VERSION "1.0BETA135-5" #define MIXER_DEVICE "/dev/mixer" #define AIRCONDELAY 10 /* must be set to three minutes delay for switching on and off aircon. maybe damage unit. */ #define POLLDELAY 9 /* set polling delay for control subsystem to 30 seconds */ #define TEMPVARIATION 1 /* temperature is allowed to make a one degree variation */ #define LIGHTVARIATION 5 /* lights are allowed to make a five level variation */ #define MAXLINE 512 #define SERV_UDP_PORT 6543 #define SERV_TCP_PORT 6543 #define BUFSIZE 128 #define OPERAND_LEN "126" #define MAX_LEN_USERNAME "16" #define MAX_LEN_PASS "126" #define SEMKEY ((key_t) 11980L) #define SHMKEY ((key_t) 18911L) #define LPTKEY ((key_t) 18188L) #define AIRKEY ((key_t) 22299L) /* some SCADAD defines */ #define SERVICE_UNDEF -1 #define SERVICE_ON 1 #define SERVICE_OFF 0 #define SERVICE_ERR -2 /* common include files */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "libunix/semaph.h" #include "libunix/shm.h" /* pam structure declaration */ struct pam_data { char *user; char *pass; int fd; }; /* scadad status and control structure */ struct dipole { short int left; short int right; }; struct airconstruct { short int status; short int compressor; short int main; short int ready; int temp; }; struct env { int templevel; int lightlevel; short int lightstat; short int lightdevstat; short int tempstat; short int blink; }; struct sms { int status; char *sendpath; char *number; }; struct scadadstruct { int scadapid; int audiopid; int controlpid; int sockfd; short int soundstat; short int lightstat; short int tempstat; short int airconstat; short int blink; int playlistnum; int moodlevel; int lightlevel; int templevel; struct airconstruct aircon; struct env env; struct sms sms; struct dipole mixer[SOUND_MIXER_NRDEVICES]; struct moodstruct *moodstruct; struct playlist *playlist; struct modulelist *modulelist; int songindex; }; /* mood structure */ struct moodstruct { char *moodname; int moodnum; int lightlvl; int templvl; int playlist; struct moodstruct *next; }; /* playlist structure */ struct playlist { int id; struct playlist_node* list; struct playlist *next; }; /* pluggable modules */ struct modulelist { char *name; char *path; int status; int level; struct modulelist *next; }; /* playlist_node structure */ struct playlist_node { char *song; struct playlist_node* next; }; /* function declaration section */ /* signal handling functions */ void exithandl (int); void sig_child (int); /* config file related functions */ int scada_generic_config (const char *); struct moodstruct *scada_mood_config (const char *); struct playlist *scada_play_config (const char *); struct modulelist *scada_module_config (const char *); void scada_cleanup (struct moodstruct *, struct playlist *, struct modulelist *); /* daemon helper functions */ void daemon_detach (); void daemon_writePID (const char*); /* network helper functions */ int readn (register int, register char *, register int); int writen (register int, register char *, register int); int readline(register int, register char *, register int); void str_echo(int); void readnf (register int, char*); void writenf (register int, const char*, ...); /* authentication function */ int scada_authenticate(register int, char*, char*); /* control and interaction functions */ int scada_control (register int, int); int exec_set_module (register int, char*, int, int); int exec_show_module (register int, char*, int*, int*); int exec_sys_module (char*, int*, int*); /* misc helper functions */ void usage ();