Beispiel #1
1
/* prepare for new client arriving on lsocket.
 * exit if trouble.
 */
static void
newClient()
{
	ClInfo *cp = NULL;
	int s, cli;

	/* assign new socket */
	s = newClSocket ();

	/* try to reuse a clinfo slot, else add one */
	for (cli = 0; cli < nclinfo; cli++)
	    if (!(cp = &clinfo[cli])->active)
		break;
	if (cli == nclinfo) {
	    /* grow clinfo, lock while moving */
	    pthread_mutex_lock (&client_m);
	    clinfo = (ClInfo *) myrealloc (clinfo, (nclinfo+1)*sizeof(ClInfo));
	    if (!clinfo) {
		fprintf (stderr, "%s: no memory for new client\n", me);
		exit(1);
	    }
	    cp = &clinfo[nclinfo++];
	    pthread_mutex_unlock (&client_m);
	}

	/* rig up new clinfo entry */
	memset (cp, 0, sizeof(*cp));
	cp->active = 1;
	cp->s = s;
	cp->lp = newLilXML();
	cp->msgq = newFQ(1);
	cp->devs = mymalloc (1);

	/* N.B. beware implied use of malloc */
	pthread_mutex_lock (&malloc_m);
	cp->wfp = fdopen (cp->s, "a");
	setbuf (cp->wfp, NULL);
	pthread_mutex_unlock (&malloc_m);

	if (verbose > 0)
	    fprintf (stderr, "Client %d: new arrival - welcome!\n", cp->s);

	/* start the writer thread */
	s = pthread_create (&cp->wtid, NULL, clientWThread, (void*)(cp-clinfo));
	if (s) {
	    fprintf (stderr, "Thread create error: %s\n", strerror(s));
	    exit (1);
	}
}
Beispiel #2
0
/* start the INDI driver process using the given DvrInfo slot.
 * exit if trouble.
 */
static void
startDvr (DvrInfo *dp)
{
	int rp[2], wp[2];
	int pid;

	/* build two pipes for r and w */
	if (pipe (rp) < 0) {
	    fprintf (stderr, "%s: read pipe: %s\n", me, strerror(errno));
	    exit(1);
	}
	if (pipe (wp) < 0) {
	    fprintf (stderr, "%s: write pipe: %s\n", me, strerror(errno));
	    exit(1);
	}

	/* fork&exec new process */
	pid = fork();
	if (pid < 0) {
	    fprintf (stderr, "%s: fork: %s\n", me, strerror(errno));
	    exit(1);
	}
	if (pid == 0) {
	    /* child: exec name */
	    int fd;

	    /* rig up pipes as stdin/out; stderr stays, everything else goes */
	    dup2 (wp[0], 0);
	    dup2 (rp[1], 1);
	    for (fd = 3; fd < 100; fd++)
		(void) close (fd);

	    /* go -- should never return */
	    execlp (dp->name, dp->name, NULL);
	    fprintf (stderr, "Driver %s: %s\n", dp->name, strerror(errno));
	    _exit (1);	/* parent will notice EOF shortly */
	}

	/* don't need child's side of pipes */
	close (rp[1]);
	close (wp[0]);

	/* record pid, io channel, init lp */
	dp->pid = pid;
	dp->rfd = rp[0];
	dp->lp = newLilXML();

	/* N.B. beware implied use of malloc */
	pthread_mutex_lock (&malloc_m);
	dp->wfp = fdopen (wp[1], "a");
	setbuf (dp->wfp, NULL);
	pthread_mutex_unlock (&malloc_m);

	if (verbose > 0)
	    fprintf (stderr, "Driver %s: rfd=%d wfd=%d\n", dp->name, dp->rfd,
	    								wp[1]);
}
Beispiel #3
0
/* start the given remote INDI driver connection.
 * exit if trouble.
 */
void
startRemoteDvr (DvrInfo *dp)
{
	Msg *mp;
	char dev[1024];
	char host[1024];
	char buf[1024];
	int indi_port, sockfd;

	/* extract host and port */
	indi_port = INDIPORT;
	if (sscanf (dp->name, "%[^@]@%[^:]:%d", dev, host, &indi_port) < 2) {
	    fprintf (stderr, "Bad remote device syntax: %s\n", dp->name);
	    Bye();
	}

	/* connect */
	sockfd = openINDIServer (host, indi_port);

	/* record flag pid, io channels, init lp and snoop list */
	dp->pid = REMOTEDVR;
	dp->rfd = sockfd;
	dp->wfd = sockfd;
	dp->lp = newLilXML();
	dp->msgq = newFQ(1);
    dp->sprops = (Property*) malloc (1);	/* seed for realloc */
	dp->nsprops = 0;
	dp->nsent = 0;
    dp->active = 1;
    dp->ndev = 1;
    dp->dev = (char **) malloc(sizeof(char *));

	/* N.B. storing name now is key to limiting outbound traffic to this
	 * dev.
	 */
    dp->dev[0] = (char *) malloc(MAXINDIDEVICE * sizeof(char));
    strncpy (dp->dev[0], dev, MAXINDIDEVICE-1);
    dp->dev[0][MAXINDIDEVICE-1] = '\0';

	/* Sending getProperties with device lets remote server limit its
	 * outbound (and our inbound) traffic on this socket to this device.
	 */
	mp = newMsg();
	pushFQ (dp->msgq, mp);
	sprintf (buf, "<getProperties device='%s' version='%g'/>\n",
             dp->dev[0], INDIV);
	setMsgStr (mp, buf);
	mp->count++;

	if (verbose > 0)
	    fprintf (stderr, "%s: Driver %s: socket=%d\n", indi_tstamp(NULL),
							    dp->name, sockfd);
}
Beispiel #4
0
/* prepare for new client arriving on lsocket.
 * exit if trouble.
 */
void
newClient()
{
	ClInfo *cp = NULL;
	int s, cli;

	/* assign new socket */
	s = newClSocket ();

	/* try to reuse a clinfo slot, else add one */
	for (cli = 0; cli < nclinfo; cli++)
	    if (!(cp = &clinfo[cli])->active)
		break;
	if (cli == nclinfo) {
	    /* grow clinfo */
	    clinfo = (ClInfo *) realloc (clinfo, (nclinfo+1)*sizeof(ClInfo));
	    if (!clinfo) {
		fprintf (stderr, "no memory for new client\n");
		Bye();
	    }
	    cp = &clinfo[nclinfo++];
	}

	/* rig up new clinfo entry */
	memset (cp, 0, sizeof(*cp));
	cp->active = 1;
	cp->s = s;
	cp->lp = newLilXML();
	cp->msgq = newFQ(1);
	cp->props = malloc (1);
	cp->nsent = 0;

	if (verbose > 0) {
	    struct sockaddr_in addr;
	    socklen_t len = sizeof(addr);
	    getpeername(s, (struct sockaddr*)&addr, &len);
	    fprintf(stderr,"%s: Client %d: new arrival from %s:%d - welcome!\n",
			    indi_tstamp(NULL), cp->s, inet_ntoa(addr.sin_addr),
							ntohs(addr.sin_port));
	}
#ifdef OSX_EMBEDED_MODE
  int active = 0;
  for (int i = 0; i < nclinfo; i++)
    if (clinfo[i].active)
      active++;
  fprintf(stderr, "CLIENTS %d\n", active); fflush(stderr);
#endif
}
Beispiel #5
0
bool INDI::BaseClientQt::connectServer()
{
    client_socket.connectToHost(cServer.c_str(), cPort);

    if (client_socket.waitForConnected(timeout_sec*1000) == false)
    {
        sConnected = false;
        return false;
    }

    clear();

    lillp = newLilXML();

    sConnected = true;

    serverConnected();

    char * orig = setlocale(LC_NUMERIC,"C");
    QString getProp;
    if (cDeviceNames.empty())
    {
        getProp = QString("<getProperties version='%1'/>\n").arg(QString::number(INDIV));

        client_socket.write(getProp.toLatin1());

        if (verbose)
            std::cerr << getProp.toLatin1().constData() << std::endl;
    }
    else
    {
        vector<string>::const_iterator stri;
        for ( stri = cDeviceNames.begin(); stri != cDeviceNames.end(); stri++)
        {
            getProp = QString("<getProperties version='%1' device='%2'/>\n").arg(QString::number(INDIV)).arg( (*stri).c_str());

            client_socket.write(getProp.toLatin1());
            if (verbose)
                std::cerr << getProp.toLatin1().constData() << std::endl;
        }
    }
    setlocale(LC_NUMERIC,orig);

    return true;
}
Beispiel #6
0
/* start the given local INDI driver process.
 * exit if trouble.
 */
void
startLocalDvr (DvrInfo *dp)
{
	Msg *mp;
    char buf[32];
	int rp[2], wp[2], ep[2];
	int pid;

#ifdef OSX_EMBEDED_MODE
  fprintf(stderr, "STARTING \"%s\"\n", dp->name); fflush(stderr);
#endif

	/* build three pipes: r, w and error*/
	if (pipe (rp) < 0) {
	    fprintf (stderr, "%s: read pipe: %s\n", indi_tstamp(NULL),
							    strerror(errno));
	    Bye();
	}
	if (pipe (wp) < 0) {
	    fprintf (stderr, "%s: write pipe: %s\n", indi_tstamp(NULL),
							    strerror(errno));
	    Bye();
	}
	if (pipe (ep) < 0) {
	    fprintf (stderr, "%s: stderr pipe: %s\n", indi_tstamp(NULL),
							    strerror(errno));
	    Bye();
	}

	/* fork&exec new process */
	pid = fork();
	if (pid < 0) {
	    fprintf (stderr, "%s: fork: %s\n", indi_tstamp(NULL), strerror(errno));
	    Bye();
	}
	if (pid == 0) {
	    /* child: exec name */
	    int fd;

	    /* rig up pipes */
	    dup2 (wp[0], 0);	/* driver stdin reads from wp[0] */
	    dup2 (rp[1], 1);	/* driver stdout writes to rp[1] */
	    dup2 (ep[1], 2);	/* driver stderr writes to e[]1] */
	    for (fd = 3; fd < 100; fd++)
		(void) close (fd);

	    if (*dp->envDev)
	      setenv("INDIDEV", dp->envDev, 1);
        /* Only reset environment variable in case of FIFO */
        else if (fifo.fd > 0)
	      unsetenv("INDIDEV");
	    if (*dp->envConfig)
	      setenv("INDICONFIG", dp->envConfig, 1);
        else if (fifo.fd > 0)
	      unsetenv("INDICONFIG");
	    if (*dp->envSkel)
	      setenv("INDISKEL", dp->envSkel, 1);
        else if (fifo.fd > 0)
	      unsetenv("INDISKEL");
	    char executable[MAXSBUF];
        if (*dp->envPrefix)
        {
	      setenv("INDIPREFIX", dp->envPrefix, 1);
#ifdef OSX_EMBEDED_MODE
	      snprintf(executable, MAXSBUF, "%s/Contents/MacOS/%s", dp->envPrefix, dp->name);
#else
        snprintf(executable, MAXSBUF, "%s/bin/%s", dp->envPrefix, dp->name);
#endif
        
        fprintf(stderr, "%s\n", executable);
        
          execlp (executable, dp->name, NULL);
        }
        else
        {
          if (fifo.fd > 0)
            unsetenv("INDIPREFIX");
          execlp (dp->name, dp->name, NULL);
	    }

#ifdef OSX_EMBEDED_MODE
  fprintf(stderr, "FAILED \"%s\"\n", dp->name); fflush(stderr);
#endif
	    fprintf (stderr, "%s: Driver %s: execlp: %s\n", indi_tstamp(NULL),
						dp->name, strerror(errno));
	    _exit (1);	/* parent will notice EOF shortly */
	}

	/* don't need child's side of pipes */
	close (wp[0]);
	close (rp[1]);
	close (ep[1]);

	/* record pid, io channels, init lp and snoop list */
	dp->pid = pid;
	dp->rfd = rp[0];
	dp->wfd = wp[1];
	dp->efd = ep[0];
	dp->lp = newLilXML();
    dp->msgq = newFQ(1);
    dp->sprops = (Property*) malloc (1);	/* seed for realloc */
	dp->nsprops = 0;
	dp->nsent = 0;
    dp->active = 1;
    dp->ndev = 0;
    dp->dev = (char **) malloc(sizeof(char *));

	/* first message primes driver to report its properties -- dev known
	 * if restarting
	 */
    mp = newMsg();
	pushFQ (dp->msgq, mp);
    sprintf (buf, "<getProperties version='%g'/>\n", INDIV);
	setMsgStr (mp, buf);
    mp->count++;

	if (verbose > 0)
	    fprintf (stderr, "%s: Driver %s: pid=%d rfd=%d wfd=%d efd=%d\n",
		    indi_tstamp(NULL), dp->name, dp->pid, dp->rfd, dp->wfd, dp->efd);
}
Beispiel #7
0
int
main (int ac, char *av[])
{
	FILE *fp;

	/* save our name for usage() */
	me = av[0];

	/* crack args */
	while (--ac && **++av == '-') {
	    char *s = *av;
	    while (*++s) {
		switch (*s) {
		case 'b':	/* beep when true */
		    bflag++;
		    break;
		case 'd':
		    if (ac < 2) {
			fprintf (stderr, "-d requires open fileno\n");
			usage();
		    }
		    directfd = atoi(*++av);
		    ac--;
		    break;
		case 'e':	/* print each updated expression value */
		    eflag++;
		    break;
		case 'f':	/* print final expression value */
		    fflag++;
		    break;
		case 'h':
		    if (directfd >= 0) {
			fprintf (stderr, "Can not combine -d and -h\n");
			usage();
		    }
		    if (ac < 2) {
			fprintf (stderr, "-h requires host name\n");
			usage();
		    }
		    host = *++av;
		    ac--;
		    break;
		case 'i':	/* read expression from stdin */
		    iflag++;
		    break;
		case 'o':	/* print operands as they change */
		    oflag++;
		    break;
		case 'p':
		    if (directfd >= 0) {
			fprintf (stderr, "Can not combine -d and -p\n");
			usage();
		    }
		    if (ac < 2) {
			fprintf (stderr, "-p requires tcp port number\n");
			usage();
		    }
		    port = atoi(*++av);
		    ac--;
		    break;
		case 't':
		    if (ac < 2) {
			fprintf (stderr, "-t requires timeout\n");
			usage();
		    }
		    timeout = atoi(*++av);
		    ac--;
		    break;
		case 'v':	/* verbose */
		    verbose++;
		    break;
		case 'w':	/* wait for expression to be true */
		    wflag++;
		    break;
		default:
		    fprintf (stderr, "Unknown flag: %c\n", *s);
		    usage();
		}
	    }
	}

	/* now there are ac args starting with av[0] */

	/* compile expression from av[0] or stdin */
	if (ac == 0)
	    compile (NULL);
	else if (ac == 1)
	    compile (av[0]);
	else
	    usage();

        /* open connection */
	if (directfd >= 0) {
	    fp = fdopen (directfd, "r+");
	    setbuf (fp, NULL);		/* don't absorb next guy's stuff */
	    if (!fp) {
		fprintf (stderr, "Direct fd %d: %s\n",directfd,strerror(errno));
		exit(1);
	    }
	    if (verbose)
		fprintf (stderr, "Using direct fd %d\n", directfd);
	} else {
	    fp = openINDIServer();
	    if (verbose)
		fprintf (stderr, "Connected to %s on port %d\n", host, port);
	}

	/* build a parser context for cracking XML responses */
	lillp = newLilXML();

	/* set up to catch an io timeout function */
	signal (SIGALRM, onAlarm);

	/* send getProperties */
	getProps(fp);

	/* initialize all properties */
	initProps(fp);

	/* evaluate expression, return depending on flags */
	return (runEval(fp));
}