/* close down the given driver and restart */ void shutdownDvr (DvrInfo *dp, int restart) { Msg *mp; /* make sure it's dead, reclaim resources */ if (dp->pid == REMOTEDVR) { /* socket connection */ shutdown (dp->wfd, SHUT_RDWR); close (dp->wfd); /* same as rfd */ } else { /* local pipe connection */ kill (dp->pid, SIGKILL); /* we've insured there are no zombies */ close (dp->wfd); close (dp->rfd); close (dp->efd); } #ifdef OSX_EMBEDED_MODE fprintf(stderr, "STOPPED \"%s\"\n", dp->name); fflush(stderr); #endif /* free memory */ free (dp->sprops); free(dp->dev); delLilXML (dp->lp); /* ok now to recycle */ dp->active = 0; dp->ndev = 0; /* decrement and possibly free any unsent messages for this client */ while ((mp = (Msg*) popFQ(dp->msgq)) != NULL) if (--mp->count == 0) freeMsg (mp); delFQ (dp->msgq); if (restart) { fprintf (stderr, "%s: Driver %s: restart #%d\n", indi_tstamp(NULL), dp->name, ++dp->restarts); startDvr (dp); } }
/* close down the given driver and restart if not too many already */ static void restartDvr (DvrInfo *dp) { /* make sure it's dead, reclaim resources */ kill (dp->pid, SIGKILL); fclose (dp->wfp); close (dp->rfd); delLilXML (dp->lp); /* restart unless too many already */ if (++dp->restarts > maxdrs) { fprintf (stderr, "Driver %s: died after %d restarts\n", dp->name, maxdrs); exit(1); } fprintf (stderr, "Driver %s: restart #%d\n", dp->name, dp->restarts); startDvr (dp); }
int main (int ac, char *av[]) { /* save our name */ me = av[0]; /* crack args */ while ((--ac > 0) && ((*++av)[0] == '-')) { char *s; for (s = av[0]+1; *s != '\0'; s++) switch (*s) { case 'p': if (ac < 2) usage(); port = atoi(*++av); ac--; break; case 'r': if (ac < 2) usage(); maxdrs = atoi(*++av); ac--; break; case 'v': verbose++; break; default: usage(); } } /* at this point there are ac args in av[] to name our drivers */ if (ac == 0) usage(); /* take care of some unixisms */ noZombies(); noSIGPIPE(); /* init mutexes and condition variables */ pthread_mutex_init(&client_m, NULL); pthread_cond_init (&client_c, NULL); pthread_mutex_init(&malloc_m, NULL); /* install our locked heap functions */ indi_xmlMalloc (mymalloc, myrealloc, myfree); setMemFuncsFQ (mymalloc, myrealloc, myfree); /* seed client info array so we can always use realloc */ clinfo = (ClInfo *) mymalloc (1); nclinfo = 0; /* create driver info array all at once so size never has to change */ ndvrinfo = ac; dvrinfo = (DvrInfo *) mymalloc (ndvrinfo * sizeof(DvrInfo)); memset (dvrinfo, 0, ndvrinfo * sizeof(DvrInfo)); /* start each driver, malloc name once and keep it */ while (ac-- > 0) { dvrinfo[ac].name = strcpy (mymalloc(strlen(*av)+1), *av); startDvr (&dvrinfo[ac]); av++; } /* announce we are online */ indiListen(); /* handle new clients and all reading */ while (1) indiRun(); /* whoa! */ fprintf (stderr, "%s: unexpected return from main\n", me); return (1); }
/* Read commands from FIFO and process them. Start/stop drivers accordingly */ void newFIFO(void) { //char line[MAXRBUF], tDriver[MAXRBUF], tConfig[MAXRBUF], tDev[MAXRBUF], tSkel[MAXRBUF], envDev[MAXRBUF], envConfig[MAXRBUF], envSkel[MAXR]; char line[MAXRBUF]; DvrInfo *dp = NULL; int startCmd=0, i=0; while (i < MAXRBUF) { if (read(fifo.fd, line+i, 1) <= 0) { // Reset FIFO now, otherwise select will always return with no data from FIFO. indiFIFO(); return; } if (line[i] == '\n') { line[i] = '\0'; i=0; } else { i++; continue; } if (verbose) fprintf(stderr, "FIFO: %s\n", line); char cmd[MAXSBUF], arg[4][1], var[4][MAXSBUF], tDriver[MAXSBUF], tName[MAXSBUF], envDev[MAXSBUF], envConfig[MAXSBUF], envSkel[MAXSBUF], envPrefix[MAXSBUF]; memset(&tDriver[0], 0, sizeof(MAXSBUF)); memset(&tName[0], 0, sizeof(MAXSBUF)); memset(&envDev[0], 0, sizeof(MAXSBUF)); memset(&envConfig[0], 0, sizeof(MAXSBUF)); memset(&envSkel[0], 0, sizeof(MAXSBUF)); memset(&envPrefix[0], 0, sizeof(MAXSBUF)); int n = sscanf(line, "%s %s -%1c \"%512[^\"]\" -%1c \"%512[^\"]\" -%1c \"%512[^\"]\" -%1c \"%512[^\"]\"", cmd, tDriver, arg[0], var[0], arg[1], var[1] , arg[2], var[2], arg[3], var[3]); int n_args = (n - 2)/2; int j=0; for (j=0; j < n_args; j++) { //fprintf(stderr, "arg[%d]: %c\n", i, arg[j][0]); //fprintf(stderr, "var[%d]: %s\n", i, var[j]); if (arg[j][0] == 'n') { strncpy(tName, var[j], MAXSBUF-1); tName[MAXSBUF-1] = '\0'; if (verbose) fprintf(stderr, "With name: %s\n", envDev); } else if (arg[j][0] == 'c') { strncpy(envConfig, var[j], MAXSBUF-1); envConfig[MAXSBUF-1] = '\0'; if (verbose) fprintf(stderr, "With config: %s\n", envConfig); } else if (arg[j][0] == 's') { strncpy(envSkel, var[j], MAXSBUF-1); envSkel[MAXSBUF-1] = '\0'; if (verbose) fprintf(stderr, "With skeketon: %s\n", envSkel); } else if (arg[j][0] == 'p') { strncpy(envPrefix, var[j], MAXSBUF-1); envPrefix[MAXSBUF-1] = '\0'; if (verbose) fprintf(stderr, "With prefix: %s\n", envPrefix); } } if (!strcmp(cmd, "start")) startCmd = 1; else startCmd = 0; if (startCmd) { if (verbose) fprintf(stderr, "FIFO: Starting driver %s with name (%s)\n", tDriver, tName); dp = allocDvr(); strncpy(dp->name, tDriver, MAXINDIDEVICE); //strncpy(dp->dev, tName, MAXINDIDEVICE); strncpy(dp->envDev, tName, MAXSBUF); strncpy(dp->envConfig, envConfig, MAXSBUF); strncpy(dp->envSkel, envSkel, MAXSBUF); strncpy(dp->envPrefix, envPrefix, MAXSBUF); startDvr (dp); } else { for (dp = dvrinfo; dp < &dvrinfo[ndvrinfo]; dp++) { fprintf(stderr, "dp->name: %s - tDriver: %s\n", dp->name, tDriver); if (!strcmp(dp->name, tDriver) && dp->active==1) { fprintf(stderr, "name: %s - dp->dev[0]: %s\n", tName, dp->dev[0]); /* If device name is given, check against it before shutting down */ //if (tName[0] && strcmp(dp->dev[0], tName)) if (tName[0] && isDeviceInDriver(tName, dp) == 0) continue; if (verbose) fprintf(stderr, "FIFO: Shutting down driver: %s\n", tDriver); for (i=0; i < dp->ndev; i++) { /* Inform clients that this driver is dead */ XMLEle *root = addXMLEle (NULL, "delProperty"); addXMLAtt(root, "device", dp->dev[i]); prXMLEle(stderr, root, 0); Msg * mp = newMsg(); q2Clients(NULL, 0, dp->dev[i], NULL, mp, root); if (mp->count > 0) setMsgXMLEle (mp, root); else freeMsg (mp); delXMLEle (root); } shutdownDvr(dp, 0); break; } } } } }