Пример #1
0
Файл: avr.c Проект: olcai/sommar
void cmd_TIME(const uint8_t* arg)
{
  if(rtc_settime(arg))
  {
    cmd_ok();
    command_parsed = 1;
  }
}
Пример #2
0
Файл: avr.c Проект: olcai/sommar
void cmd_INT(const uint8_t* arg)
{
  if(adc_set_interval(arg))
  {
    cmd_ok();
    command_parsed = 1;
  }
}
Пример #3
0
static void crash_shell(void) {
	char qry[1000], cmd[1000], line[1000];
	char *str, *p;

	crash_shell_help();
	fprintf(stderr, "\ncrash> ");
	while (fgets(line, 1000, stdin) != NULL) {
		str = lblanks(line);

		p = str;
		while(*p) {
			if (*p == '\n') {
				*p = '\0';
			}
			p++;
		}

		if (*str == 'q' && *(str+1) == '\0') {
			fprintf(stderr, "quiting.\n");
			return;
		} else if (*str == 'h' && *(str+1) == '\0') {
			crash_shell_help();
		} else if (*str == '?' && *(str+1) == '\0') {
			crash_shell_help();
		} else if (*str == 's' && *(str+1) == '\0') {
			sprintf(cmd, "sh -c '(%s) &'", crash_stack_command1);
			/* crash */
			if (no_external_cmds || !cmd_ok("crash")) {
				fprintf(stderr, "\nno_external_cmds=%d\n",
				    no_external_cmds);
				goto crash_prompt;
			}
			fprintf(stderr, "\nrunning:\n\t%s\n\n",
			    crash_stack_command1);
			system(cmd);
			usleep(1000*1000);

			sprintf(cmd, "sh -c '(%s) &'", crash_stack_command2);
			fprintf(stderr, "\nrunning:\n\t%s\n\n",
			    crash_stack_command2);
			system(cmd);
			usleep(1000*1000);
		} else {
			snprintf(qry, 1000, "qry=%s", str);
			p = process_remote_cmd(qry, 1);
			fprintf(stderr, "\n\nresult:\n%s\n", p);
			free(p);
		}
		
crash_prompt:
		fprintf(stderr, "crash> ");
	}
}
Пример #4
0
// eventcat_id;
ExecWindow::ExecWindow(watchCond *wc, int pid, QString cmd)
{
    setupUi(this);
    setWindowTitle( tr( "Qps Watchdog" ) );

    wcond = wc;

    QString str;

    if (wc->cond == WATCH_PROCESS_START)
    {
        textEdit->append(cmd + "(" + QString::number(pid) + ")" + " start");
    }
    if (wc->cond == WATCH_PROCESS_FINISH)
        textEdit->append(cmd + "(" + QString::number(pid) + ")" + " finished");

    flag_started = false;

    pr = new QProcess;          // leak?
    if (!wc->command.isEmpty()) // conflict pid's command
    {
        pr->start(wc->command); // thread run, if null then segfault occurs. ?
    }

    connect(okButton, SIGNAL(clicked()), this, SLOT(cmd_ok()));

    connect(pr, SIGNAL(started()), this, SLOT(cmd_started()));
    connect(pr, SIGNAL(finished(int, QProcess::ExitStatus)), this,
            SLOT(cmd_finished(int, QProcess::ExitStatus)));
    connect(pr, SIGNAL(error(QProcess::ProcessError)), this,
            SLOT(cmd_error(QProcess::ProcessError)));

    show();

    execlist.append(this);
}
Пример #5
0
static char *guess_via_v4l_info(char *dev, int *fd) {
	char *atparms, *cmd;
	char line[1024], tmp[] = "/tmp/x11vnc-tmp.XXXXXX";
	FILE *out;
	int tmp_fd, len, rc, curr = 0;
	int g_w = 0, g_h = 0, g_b = 0, mask_rev = 0;
	char *g_fmt = NULL;

	if (*fd) {}

	/* v4l-info */
	if (no_external_cmds || !cmd_ok("v4l-info")) {
		rfbLog("guess_via_v4l_info: cannot run external "
		    "command: v4l-info\n");
		return NULL;
	}

	if (strchr(dev, '\'')) {
		rfbLog("guess_via_v4l_info: bad dev string: %s\n", dev);
		return NULL;
	}

	tmp_fd = mkstemp(tmp);
	if (tmp_fd < 0) {
		return NULL;
	}

	len =  strlen("v4l-info")+1+1+strlen(dev)+1+1+1+1+strlen(tmp)+1; 
	cmd = (char *) malloc(len);
	rfbLog("guess_via_v4l_info running: v4l-info '%s'\n", dev);
	sprintf(cmd, "v4l-info '%s' > %s", dev, tmp);

	close(tmp_fd);
	close_exec_fds();
	rc = system(cmd);
	if (rc != 0) {
		unlink(tmp);
		return NULL;
	}

	out = fopen(tmp, "r");
	if (out == NULL) {
		unlink(tmp);
		return NULL;
	}
	
	curr = 0;
	while (fgets(line, 1024, out) != NULL) {
		char *lb = lblanks(line);
		if (strstr(line, "video capture") == line) {
			curr = C_VIDEO_CAPTURE;
		} else if (strstr(line, "picture") == line) {
			curr = C_PICTURE;
		} else if (strstr(line, "window") == line) {
			curr = C_WINDOW;
		}

if (0) fprintf(stderr, "lb: %s", lb);

		if (curr == C_VIDEO_CAPTURE) {
			if (strstr(lb, "pixelformat ") == lb) {
				fprintf(stderr, "%s", line);
			} else if (strstr(lb, "fmt.pix.width ") == lb) {
				if (! g_w) {
					g_w = colon_n(line);
				}
			} else if (strstr(lb, "fmt.pix.height ") == lb) {
				if (! g_h) {
					g_h = colon_n(line);
				}
			} else if (strstr(lb, "fmt.pix.pixelformat ") == lb) {
				if (! g_fmt) {
					g_fmt = colon_tag(line);
				}
			}
		} else if (curr == C_PICTURE) {
			if (strstr(lb, "depth ") == lb) {
				if (! g_b) {
					g_b = colon_n(line);
				}
			} else if (strstr(lb, "palette ") == lb) {
				if (! g_fmt) {
					g_fmt = colon_str(line);
				}
			}
		} else if (curr == C_WINDOW) {
			if (strstr(lb, "width ") == lb) {
				if (! g_w) {
					g_w = colon_n(line);
				}
			} else if (strstr(lb, "height ") == lb) {
				if (! g_h) {
					g_h = colon_n(line);
				}
			}
		}
	}
	fclose(out);
	unlink(tmp);

	if (! g_w) {
		rfbLog("could not guess device width.\n");
		return NULL;
	}
	rfbLog("guessed device width:  %d\n", g_w);

	if (! g_h) {
		rfbLog("could not guess device height.\n");
		return NULL;
	}
	rfbLog("guessed device height: %d\n", g_h);

	if (g_fmt) {
		rfbLog("guessed pixel fmt:     %s\n", g_fmt);
		lookup_rgb(g_fmt, &g_b, &mask_rev);
	}
	if (! g_b) {
		rfbLog("could not guess device bpp.\n");
		return NULL;
	}
	rfbLog("guessed device bpp:    %d\n", g_b);

	atparms = (char *) malloc(100);
	sprintf(atparms, "%dx%dx%d", g_w, g_h, g_b);
	return atparms;
}
Пример #6
0
Файл: avr.c Проект: olcai/sommar
void cmd_PING(const uint8_t* arg)
{
  cmd_ok();
  command_parsed= 1;
}
Пример #7
0
void iap_handlepkt_mode2(const unsigned int len, const unsigned char *buf)
{
    static bool poweron_pressed = false;
    unsigned int cmd = buf[1];

    /* We expect at least three bytes in the buffer, one for the
     * lingo, one for the command, and one for the first button
     * state bits.
     */
    CHECKLEN(3);

    /* Lingo 0x02 must have been negotiated */
    if (!DEVICE_LINGO_SUPPORTED(0x02)) {
        cmd_ack(cmd, IAP_ACK_BAD_PARAM);
        return;
    }

    switch (cmd)
    {
        /* ContextButtonStatus (0x00)
         *
         * Transmit button events from the device to the iPod
         *
         * Packet format (offset in buf[]: Description)
         * 0x00: Lingo ID: Simple Remote Lingo, always 0x02
         * 0x01: Command, always 0x00
         * 0x02: Button states 0:7
         * 0x03: Button states 8:15 (optional)
         * 0x04: Button states 16:23 (optional)
         * 0x05: Button states 24:31 (optional)
         *
         * Returns: (none)
         */
        case 0x00:
        {
            iap_remotebtn = BUTTON_NONE;
            iap_timeoutbtn = 0;

            if(buf[2] != 0)
            {
                if(buf[2] & 1)
                    REMOTE_BUTTON(BUTTON_RC_PLAY);
                if(buf[2] & 2)
                    REMOTE_BUTTON(BUTTON_RC_VOL_UP);
                if(buf[2] & 4)
                    REMOTE_BUTTON(BUTTON_RC_VOL_DOWN);
                if(buf[2] & 8)
                    REMOTE_BUTTON(BUTTON_RC_RIGHT);
                if(buf[2] & 16)
                    REMOTE_BUTTON(BUTTON_RC_LEFT);
            }
            else if(len >= 4 && buf[3] != 0)
            {
                if(buf[3] & 1) /* play */
                {
                    if (audio_status() != AUDIO_STATUS_PLAY)
                        REMOTE_BUTTON(BUTTON_RC_PLAY);
                }
                if(buf[3] & 2) /* pause */
                {
                    if (audio_status() == AUDIO_STATUS_PLAY)
                        REMOTE_BUTTON(BUTTON_RC_PLAY);
                }
                if(buf[3] & 128) /* Shuffle */
                {
                    if (!iap_btnshuffle)
                    {
                        iap_shuffle_state(!global_settings.playlist_shuffle);
                        iap_btnshuffle = true;
                    }
                }
            }
            else if(len >= 5 && buf[4] != 0)
            {
                if(buf[4] & 1) /* repeat */
                {
                    if (!iap_btnrepeat)
                    {
                        iap_repeat_next();
                        iap_btnrepeat = true;
                    }
                }

                if (buf[4] & 2) /* power on */
                {
                    poweron_pressed = true;
                }

                /* Power off
                 * Not quite sure how to react to this, but stopping playback
                 * is a good start.
                 */
                if (buf[4] & 0x04)
                {
                    if (audio_status() == AUDIO_STATUS_PLAY)
                        REMOTE_BUTTON(BUTTON_RC_PLAY);
                }

                if(buf[4] & 16) /* ffwd */
                    REMOTE_BUTTON(BUTTON_RC_RIGHT);
                if(buf[4] & 32) /* frwd */
                    REMOTE_BUTTON(BUTTON_RC_LEFT);
            }

            /* power on released */
            if (poweron_pressed && len >= 5 && !(buf[4] & 2))
            {
                poweron_pressed = false;
#ifdef HAVE_LINE_REC
                /* Belkin TuneTalk microphone sends power-on press+release
                 * events once authentication sequence is finished,
                 * GetDevCaps command is ignored by the device when it is
                 * sent before power-on release event is received.
                 * XXX: It is unknown if other microphone devices are
                 * sending the power-on events.
                 */
                if (DEVICE_LINGO_SUPPORTED(0x01)) {
                    /* GetDevCaps */
                    IAP_TX_INIT(0x01, 0x07);
                    iap_send_tx();
                }
#endif
            }

            break;
        }
        /* ACK (0x01)
         *
         * Sent from the iPod to the device
         */

        /* ImageButtonStatus (0x02)
         *
         * Transmit image button events from the device to the iPod
         *
         * Packet format (offset in buf[]: Description)
         * 0x00: Lingo ID: Simple Remote Lingo, always 0x02
         * 0x01: Command, always 0x02
         * 0x02: Button states 0:7
         * 0x03: Button states 8:15 (optional)
         * 0x04: Button states 16:23 (optional)
         * 0x05: Button states 24:31 (optional)
         *
         * This command requires authentication
         *
         * Returns on success:
         * IAP_ACK_OK
         *
         * Returns on failure:
         * IAP_ACK_*
         */
        case 0x02:
        {
            if (!DEVICE_AUTHENTICATED) {
                cmd_ack(cmd, IAP_ACK_NO_AUTHEN);
                break;
            }

            cmd_ack(cmd, IAP_ACK_CMD_FAILED);
            break;
        }

        /* VideoButtonStatus (0x03)
         *
         * Transmit video button events from the device to the iPod
         *
         * Packet format (offset in buf[]: Description)
         * 0x00: Lingo ID: Simple Remote Lingo, always 0x02
         * 0x01: Command, always 0x03
         * 0x02: Button states 0:7
         * 0x03: Button states 8:15 (optional)
         * 0x04: Button states 16:23 (optional)
         * 0x05: Button states 24:31 (optional)
         *
         * This command requires authentication
         *
         * Returns on success:
         * IAP_ACK_OK
         *
         * Returns on failure:
         * IAP_ACK_*
         */
        case 0x03:
        {
            if (!DEVICE_AUTHENTICATED) {
                cmd_ack(cmd, IAP_ACK_NO_AUTHEN);
                break;
            }

            cmd_ack(cmd, IAP_ACK_CMD_FAILED);
            break;
        }

        /* AudioButtonStatus (0x04)
         *
         * Transmit audio button events from the device to the iPod
         *
         * Packet format (offset in buf[]: Description)
         * 0x00: Lingo ID: Simple Remote Lingo, always 0x02
         * 0x01: Command, always 0x04
         * 0x02: Button states 0:7
         * 0x03: Button states 8:15 (optional)
         * 0x04: Button states 16:23 (optional)
         * 0x05: Button states 24:31 (optional)
         *
         * This command requires authentication
         *
         * Returns on success:
         * IAP_ACK_OK
         *
         * Returns on failure:
         * IAP_ACK_*
         */
        case 0x04:
        {
            unsigned char repeatbuf[6];

            if (!DEVICE_AUTHENTICATED) {
                cmd_ack(cmd, IAP_ACK_NO_AUTHEN);
                break;
            }

            /* This is basically the same command as ContextButtonStatus (0x00),
             * with the difference that it requires authentication and that
             * it returns an ACK packet to the device.
             * So just route it through the handler again, with 0x00 as the
             * command
             */
            memcpy(repeatbuf, buf, 6);
            repeatbuf[1] = 0x00;
            iap_handlepkt_mode2((len<6)?len:6, repeatbuf);

            cmd_ok(cmd);
            break;
        }

        /* The default response is IAP_ACK_BAD_PARAM */
        default:
        {
#ifdef LOGF_ENABLE
            logf("iap: Unsupported Mode02 Command");
#else
            cmd_ack(cmd, IAP_ACK_BAD_PARAM);
#endif
            break;
        }
    }
}
Пример #8
0
int start_stunnel(int stunnel_port, int x11vnc_port, int hport, int x11vnc_hport) {
#ifdef SSLCMDS
	char extra[] = ":/usr/sbin:/usr/local/sbin:/dist/sbin";
	char *path, *p, *exe;
	char *stunnel_path = NULL;
	struct stat verify_buf;
	struct stat crl_buf;
	int status, tmp_pem = 0;

	if (stunnel_pid) {
		stop_stunnel();
	}
	stunnel_pid = 0;

	path = getenv("PATH");
	if (! path) {
		path = strdup(extra+1);
	} else {
		char *pt = path;
		path = (char *) malloc(strlen(path)+strlen(extra)+1);
		if (! path) {
			return 0;
		}
		strcpy(path, pt);
		strcat(path, extra);
	}

	exe = (char *) malloc(strlen(path) + 1 + strlen("stunnel4") + 1);

	p = strtok(path, ":");

	exe[0] = '\0';

	while (p) {
		struct stat sbuf;

		sprintf(exe, "%s/%s", p, "stunnel4");
		if (! stunnel_path && stat(exe, &sbuf) == 0) {
			if (! S_ISDIR(sbuf.st_mode)) {
				stunnel_path = exe;
				break;
			}
		}

		sprintf(exe, "%s/%s", p, "stunnel");
		if (! stunnel_path && stat(exe, &sbuf) == 0) {
			if (! S_ISDIR(sbuf.st_mode)) {
				stunnel_path = exe;
				break;
			}
		}

		p = strtok(NULL, ":");
	}
	if (path) {
		free(path);
	}

	if (getenv("STUNNEL_PROG")) {
		free(exe);
		exe = strdup(getenv("STUNNEL_PROG"));
		stunnel_path = exe;
	}

	if (! stunnel_path) {
		free(exe);
		return 0;
	}
	if (stunnel_path[0] == '\0') {
		free(exe);
		return 0;
	}

	/* stunnel */
	if (no_external_cmds || !cmd_ok("stunnel")) {
		rfbLogEnable(1);
		rfbLog("start_stunnel: cannot run external commands in -nocmds mode:\n");
		rfbLog("   \"%s\"\n", stunnel_path);
		rfbLog("   exiting.\n");
		clean_up_exit(1);
	}

	if (! quiet) {
		rfbLog("\n");
		rfbLog("starting ssl tunnel: %s  %d -> %d\n", stunnel_path,
		    stunnel_port, x11vnc_port);
	}

	if (stunnel_pem && strstr(stunnel_pem, "SAVE") == stunnel_pem) {
		stunnel_pem = get_saved_pem(stunnel_pem, 1);
		if (! stunnel_pem) {
			rfbLog("start_stunnel: could not create or open"
			    " saved PEM.\n");	
			clean_up_exit(1);
		}
	} else if (!stunnel_pem) {
		stunnel_pem = create_tmp_pem(NULL, 0);
		if (! stunnel_pem) {
			rfbLog("start_stunnel: could not create temporary,"
			    " self-signed PEM.\n");	
			clean_up_exit(1);
		}
		tmp_pem = 1;
		if (getenv("X11VNC_SHOW_TMP_PEM")) {
			FILE *in = fopen(stunnel_pem, "r");
			if (in != NULL) {
				char line[128];
				fprintf(stderr, "\n");
				while (fgets(line, 128, in) != NULL) {
					fprintf(stderr, "%s", line);
				}
				fprintf(stderr, "\n");
				fclose(in);
			}
		}
	}

	if (ssl_verify) {
		char *file = get_ssl_verify_file(ssl_verify);
		if (file) {
			ssl_verify = file;
		}
		if (stat(ssl_verify, &verify_buf) != 0) {
			rfbLog("stunnel: %s does not exist.\n", ssl_verify);
			clean_up_exit(1);
		}
	}
	if (ssl_crl) {
		if (stat(ssl_crl, &crl_buf) != 0) {
			rfbLog("stunnel: %s does not exist.\n", ssl_crl);
			clean_up_exit(1);
		}
	}

	stunnel_pid = fork();

	if (stunnel_pid < 0) {
		stunnel_pid = 0;
		free(exe);
		return 0;
	}

	if (stunnel_pid == 0) {
		FILE *in;
		char fd[20];
		int i;
		char *st_if = getenv("STUNNEL_LISTEN");

		if (st_if == NULL) {
			st_if = "";
		} else {
			st_if = (char *) malloc(strlen(st_if) + 2);
			sprintf(st_if, "%s:", getenv("STUNNEL_LISTEN"));
		}


		for (i=3; i<256; i++) {
			close(i);
		}

		if (use_stunnel == 3) {
			char sp[30], xp[30], *a = NULL;
			char *st = stunnel_path;
			char *pm = stunnel_pem;
			char *sv = ssl_verify;

			sprintf(sp, "%d", stunnel_port);
			sprintf(xp, "%d", x11vnc_port);

			if (ssl_verify) {
				if(S_ISDIR(verify_buf.st_mode)) {
					a = "-a";
				} else {
					a = "-A";
				}
			}

			if (ssl_crl) {
				rfbLog("stunnel: stunnel3 does not support CRL. %s\n", ssl_crl);
				clean_up_exit(1);
			}
			
			if (stunnel_pem && ssl_verify) {
				/* XXX double check -v 2 */
				execlp(st, st, "-f", "-d", sp, "-r", xp, "-P",
				    "none", "-p", pm, a, sv, "-v", "2",
				    (char *) NULL);
			} else if (stunnel_pem && !ssl_verify) {
				execlp(st, st, "-f", "-d", sp, "-r", xp, "-P",
				    "none", "-p", pm,
				    (char *) NULL);
			} else if (!stunnel_pem && ssl_verify) {
				execlp(st, st, "-f", "-d", sp, "-r", xp, "-P",
				    "none", a, sv, "-v", "2",
				    (char *) NULL);
			} else {
				execlp(st, st, "-f", "-d", sp, "-r", xp, "-P",
				    "none", (char *) NULL);
			}
			exit(1);
		}

		in = tmpfile();
		if (! in) {
			exit(1);
		}

		fprintf(in, "foreground = yes\n");
		fprintf(in, "pid =\n");
		if (stunnel_pem) {
			fprintf(in, "cert = %s\n", stunnel_pem);
		}
		if (ssl_crl) {
			if(S_ISDIR(crl_buf.st_mode)) {
				fprintf(in, "CRLpath = %s\n", ssl_crl);
			} else {
				fprintf(in, "CRLfile = %s\n", ssl_crl);
			}
		}
		if (ssl_verify) {
			if(S_ISDIR(verify_buf.st_mode)) {
				fprintf(in, "CApath = %s\n", ssl_verify);
			} else {
				fprintf(in, "CAfile = %s\n", ssl_verify);
			}
			fprintf(in, "verify = 2\n");
		}
		fprintf(in, ";debug = 7\n\n");
		fprintf(in, "[x11vnc_stunnel]\n");
		fprintf(in, "accept = %s%d\n", st_if, stunnel_port);
		fprintf(in, "connect = %d\n", x11vnc_port);

		if (hport > 0 && x11vnc_hport > 0) {
			fprintf(in, "\n[x11vnc_http]\n");
			fprintf(in, "accept = %s%d\n", st_if, hport);
			fprintf(in, "connect = %d\n", x11vnc_hport);
		}

		fflush(in);
		rewind(in);

		if (getenv("STUNNEL_DEBUG")) {
			char line[1000];
			fprintf(stderr, "\nstunnel config contents:\n\n");
			while (fgets(line, sizeof(line), in) != NULL) {
				fprintf(stderr, "%s", line);
			}
			fprintf(stderr, "\n");
			rewind(in);
		}
		
		sprintf(fd, "%d", fileno(in));
		execlp(stunnel_path, stunnel_path, "-fd", fd, (char *) NULL);
		exit(1);
	}

	free(exe);
	usleep(750 * 1000);

	waitpid(stunnel_pid, &status, WNOHANG); 

	if (ssl_verify && strstr(ssl_verify, "/sslverify-tmp-load-")) {
		/* temporary file */
		usleep(1000 * 1000);
		unlink(ssl_verify);
	}
	if (tmp_pem) {
		/* temporary cert */
		usleep(1500 * 1000);
		unlink(stunnel_pem);
	}

	if (kill(stunnel_pid, 0) != 0) {
		waitpid(stunnel_pid, &status, WNOHANG); 
		stunnel_pid = 0;
		return 0;
	}

	if (! quiet) {
		rfbLog("stunnel pid is: %d\n", (int) stunnel_pid);
	}

	return 1;
#else
	return 0;
#endif
}
Пример #9
0
static int try_avahi_helper(char *name, char *host, uint16_t port) {
#if LIBVNCSERVER_HAVE_FORK
	char *cmd, *p, *path = getenv("PATH"), portstr[32];
	int i;

	if (!name || !host || !port) {}

	/* avahi-publish */
	if (no_external_cmds || !cmd_ok("zeroconf")) {
		return 0;
	}

	if (!path) {
		return 0;
	}

	path = strdup(path); 
	cmd = (char *) malloc(strlen(path) + 100);
	sprintf(portstr, "%d", (int) port);

	p = strtok(path, ":");
	while (p) {
		struct stat sbuf;

		sprintf(cmd, "%s/avahi-publish", p);
		if (stat(cmd, &sbuf) == 0) {
			break;
		}
		sprintf(cmd, "%s/dns-sd", p);
		if (stat(cmd, &sbuf) == 0) {
			break;
		}
		sprintf(cmd, "%s/mDNS", p);
		if (stat(cmd, &sbuf) == 0) {
			break;
		}
		cmd[0] = '\0';

		p = strtok(NULL, ":");
	}
	free(path);

	if (!strcmp(cmd, "")) {
		free(cmd);
		rfbLog("Could not find an external avahi/zeroconf helper program.\n");
		return 0;
	}

	avahi_pid = fork();

	if (avahi_pid < 0) {
		rfbLogPerror("fork");
		avahi_pid = 0;
		free(cmd);
		return 0;
	}

	if (avahi_pid != 0) {
		int status;

		usleep(500 * 1000);
		waitpid(avahi_pid, &status, WNOHANG); 
		if (kill(avahi_pid, 0) != 0) {
			waitpid(avahi_pid, &status, WNOHANG); 
			avahi_pid = 0;
			free(cmd);
			return 0;
		}
		if (! quiet) {
			rfbLog("%s helper pid is: %d\n", cmd, (int) avahi_pid);
		}
		free(cmd);
		return 1;
	}

	for (i=3; i<256; i++) {
		close(i);
	}

	if (strstr(cmd, "/avahi-publish")) {
		execlp(cmd, cmd, "-s", name, "_rfb._tcp", portstr, (char *) NULL);
	} else {
		execlp(cmd, cmd, "-R", name, "_rfb._tcp", ".", portstr, (char *) NULL);
	}
	exit(1);
#else
	if (!name || !host || !port) {}
	return 0;
#endif
}