Exemple #1
0
void arrivals_success(int32_t cookie, int http_status, DictionaryIterator* received, void* context)
{
    Tuple *t = dict_find(received, 1);
    char *v = t->value->cstring;
    uint16_t index = 0;
    uint16_t len = t->length;
    arrivalsCount = 0;
    int16_t time = 0;
    MenuIndex top = { 0, 0 };
    

    PblTm now;
    get_time(&now);
    if (clock_is_24h_style()) {
        string_format_time(arrival_time_str, sizeof(arrival_time_str), "Updated: %H:%M", &now);
    }
    else {
        string_format_time(arrival_time_str, sizeof(arrival_time_str), "Updated: %l:%M %p", &now);
    }

    for(unsigned char i=0;i<MAX_ARRIVALS && index < len;i++) {
        //stokenize(char *source, uint16_t index, char delimiter, char *target, uint16_t max_length)
        index = stokenize(v, index, ':', ARRIVALS[i].route, ARRIVAL_ROUTE_LENGTH, len);
        index = stokenize(v, index, ':', ARRIVALS[i].actual, sizeof(ARRIVALS[i].actual), len);
        index = stokenize(v, index, ':', ARRIVALS[i].scheduled, sizeof(ARRIVALS[i].scheduled), len);

        //TODO: DRY

        time = satoi(ARRIVALS[i].actual, strlen(ARRIVALS[i].actual));

        if(abs(time) > 99*60 + 59) //Maximum displayable value.
        	time = (99*60 + 59) * (time < 0 ? -1 : 1);

        if(time > 60 || time < -60) {
	        snprintf(ARRIVALS[i].actual, ARRIVAL_TIME_LENGTH, "%d:%02d", time / 60, abs(time % 60));
	    } else {
	    	snprintf(ARRIVALS[i].actual, ARRIVAL_TIME_LENGTH, "%d", time % 60);
	    }

	    time = satoi(ARRIVALS[i].scheduled, strlen(ARRIVALS[i].scheduled));

        if(abs(time) > 99*60 + 59) //Maximum displayable value.
        	time = (99*60 + 59) * (time < 0 ? -1 : 1);

        if(time > 60 || time < -60) {
	        snprintf(ARRIVALS[i].scheduled, ARRIVAL_TIME_LENGTH, "%d:%02d", time / 60, abs(time % 60));
	    } else {
	    	snprintf(ARRIVALS[i].scheduled, ARRIVAL_TIME_LENGTH, "%d", time % 60);
	    }

        APP_LOG(APP_LOG_LEVEL_INFO, "Received route:%s actual:%s scheduled:%s (index:%d/%d)", ARRIVALS[i].route, ARRIVALS[i].actual, ARRIVALS[i].scheduled, index, len);
        ++arrivalsCount;
    }

    menu_layer_reload_data(&_arrivalsMenu);
    menu_layer_set_selected_index(&_arrivalsMenu, top, MenuRowAlignBottom, false);

}
Exemple #2
0
static void
ck_lock(register char *p, register struct packet *pkt)
{
    int l_rel;
    int locked;

    strcpy(l_str, (const char *) NOGETTEXT("SCCS file locked against editing (co23)"));
    locked = 0;
    if (*p == 'a')
        locked++;
    else while(*p) {
            p = satoi(p,&l_rel);
            ++p;
            if (l_rel == pkt->p_gotsid.s_rel || l_rel == pkt->p_reqsid.s_rel) {
                locked++;
                sprintf(l_str, "release `%d' locked against editing (co23)",
                        l_rel);
                break;
            }
        }
    if (locked)
        fatal(l_str);
}
Exemple #3
0
static void
fixnum(const char *lp)
{
	off_t num;

	while (*lp) {
		switch (*lp) {

		case 'a':
		case 'c':
		case 'd':
		case ',':
		case '\n':
			printf("%c", *lp);
			lp++;
			break;

		default:
			lp = satoi(lp, &num);
			num += linenum;
			printf("%lld", (long long)num);
		}
	}
}
Exemple #4
0
static void
fixnum(char *lp)
{
	long long int num;

	while (*lp) {
		switch (*lp) {

		case 'a':
		case 'c':
		case 'd':
		case ',':
		case '\n':
			(void) printf("%c", *lp);
			lp++;
			break;

		default:
			lp = satoi(lp, &num);
			num += linenum;
			(void) printf("%lld", num);
		}
	}
}
/* internal method to parse the body */
int
msg_body_parse (sip_t * sip, char *start_of_buf, char **next_body)
{
  char *start_of_body;
  char *end_of_body;
  char *tmp;
  int i;

  char *sep_boundary;
  generic_param_t *ct_param;

  /* if MIME-Version: does not exist we just have */
  /* to deal with one body and no header... */
  if (sip->mime_version == NULL)
    {				/* Mime-Version header does NOT exist */
      if (sip->content_type == NULL)
	return 0;		/* no body is attached */
      else
	{
	  size_t body_len;

	  if (start_of_buf[0] == '\0')
	    return -1;		/* final CRLF is missing */
	  /* get rid of the first CRLF */
	  if ('\r' == start_of_buf[0])
	    {
	      if ('\n' == start_of_buf[1])
		start_of_body = start_of_buf + 2;
	      else
		start_of_body = start_of_buf + 1;
	    }
	  else if ('\n' == start_of_buf[0])
	    start_of_body = start_of_buf + 1;
	  else
	    return -1;		/* message does not end with CRLFCRLF, CRCR or LFLF */

	  if (sip->contentlength != NULL)
	    body_len = satoi (sip->contentlength->value);
	  else
	    {			/* if content_length does not exist, set it. */
	      char *tmp = smalloc (8);

	      if (tmp == NULL)
		return -1;
	      body_len = strlen (start_of_body);
	      sprintf (tmp, "%i", body_len);
	      i = msg_setcontent_length (sip, tmp);
	      sfree (tmp);
	      if (i != 0)
		return -1;
	    }

	  if (body_len > strlen (start_of_body))	/* we do not receive the */
	    return -1;		/* complete message      */
	  /* end_of_body = start_of_body + strlen(start_of_body); */
	  end_of_body = start_of_body + body_len;
	  tmp = smalloc (end_of_body - start_of_body + 2);
	  if (tmp == NULL)
	    return -1;
	  sstrncpy (tmp, start_of_body, end_of_body - start_of_body);

	  i = msg_setbody (sip, tmp);
	  sfree (tmp);
	  if (i != 0)
	    return -1;
	  return 0;
	}
    }

  /* find the boundary */
  i = generic_param_getbyname (sip->content_type->gen_params,
			       "boundary", &ct_param);
  if (i != 0)
    return -1;

  if (ct_param == NULL)
    return -1;
  if (ct_param->gvalue == NULL)
    return -1;			/* No boundary but multiple headers??? */

  sep_boundary = (char *) smalloc (strlen (ct_param->gvalue) + 3);
  sprintf (sep_boundary, "--%s", ct_param->gvalue);

  *next_body = NULL;
  start_of_body = start_of_buf;
  for (;;)
    {
      i = find_next_occurence (sep_boundary, start_of_body, &start_of_body);
      if (i == -1)
	{
	  sfree (sep_boundary);
	  return -1;
	}
      i =
	find_next_occurence (sep_boundary,
			     start_of_body + strlen (sep_boundary),
			     &end_of_body);
      if (i == -1)
	{
	  sfree (sep_boundary);
	  return -1;
	}

      /* this is the real beginning of body */
      start_of_body = start_of_body + strlen (sep_boundary) + 2;

      tmp = smalloc (end_of_body - start_of_body + 1);
      sstrncpy (tmp, start_of_body, end_of_body - start_of_body);

      i = msg_setbody_mime (sip, tmp);
      sfree (tmp);
      if (i == -1)
	{
	  sfree (sep_boundary);
	  return -1;
	}

      if (strncmp (end_of_body + strlen (sep_boundary), "--", 2) == 0)
	{			/* end of all bodies */
	  *next_body = end_of_body;
	  sfree (sep_boundary);
	  return 0;
	}
      /* continue on the next body */
      start_of_body = end_of_body;
    }
  /* Unreachable code */
  /* sfree (sep_boundary); */
  return -1;
}
Exemple #6
0
static void init(int argc, char **argv) {
  int c;
  char *p;
  const char *user = NULL;
  const char *rootdir = NULL, *workdir = NULL, *pidfile = NULL;
  const char *bindaddr[MAXSOCK];
  int nba = 0;
  uid_t uid = 0;
  gid_t gid = 0;
  int nodaemon = 0, quickstart = 0, dump = 0, nover = 0, forkon = 0;
  int family = AF_UNSPEC;
  int cfd = -1;
  const struct zone *z;
#ifndef NO_DSO
  char *ext = NULL, *extarg = NULL;
  int (*extinit)(const char *arg, struct zone *zonelist) = NULL;
#endif

  if ((progname = strrchr(argv[0], '/')) != NULL)
    argv[0] = ++progname;
  else
    progname = argv[0];

  if (argc <= 1) usage(1);

  const char *const getopt_fmt = "u:r:b:w:t:c:p:nel:Lqs:h46dvaAfCx:X:zg";
  while((c = getopt(argc, argv, getopt_fmt)) != EOF)
    switch(c) {
    case 'u': user = optarg; break;
    case 'r': rootdir = optarg; break;
    case 'b':
      if (nba >= MAXSOCK)
        error(0, "too many addresses to listen on (%d max)", MAXSOCK);
      bindaddr[nba++] = optarg;
      break;
#ifndef NO_IPv6
    case '4': family = AF_INET; break;
    case '6': family = AF_INET6; break;
#else
    case '4': break;
    case '6': error(0, "IPv6 support isn't compiled in");
#endif
    case 'w': workdir = optarg; break;
    case 'p': pidfile = optarg; break;
    case 't':
      p = optarg;
      if (*p == ':') ++p;
      else {
        if (!(p = parse_time(p, &def_ttl)) || !def_ttl ||
            (*p && *p++ != ':'))
          error(0, "invalid ttl (-t) value `%.50s'", optarg);
      }
      if (*p == ':') ++p;
      else if (*p) {
        if (!(p = parse_time(p, &min_ttl)) || (*p && *p++ != ':'))
          error(0, "invalid minttl (-t) value `%.50s'", optarg);
      }
      if (*p == ':') ++p;
      else if (*p) {
        if (!(p = parse_time(p, &max_ttl)) || (*p && *p++ != ':'))
          error(0, "invalid maxttl (-t) value `%.50s'", optarg);
      }
      if (*p)
        error(0, "invalid value for -t (ttl) option: `%.50s'", optarg);
      if ((min_ttl && max_ttl && min_ttl > max_ttl) ||
          (min_ttl && def_ttl < min_ttl) ||
          (max_ttl && def_ttl > max_ttl))
        error(0, "inconsistent def:min:max ttl: %u:%u:%u",
              def_ttl, min_ttl, max_ttl);
      break;
    case 'c':
      if (!(p = parse_time(optarg, &recheck)) || *p)
        error(0, "invalid check interval (-c) value `%.50s'", optarg);
      break;
    case 'n': nodaemon = 1; break;
    case 'e': accept_in_cidr = 1; break;
    case 'l':
      logfile = optarg;
      if (*logfile != '+') flushlog = 0;
      else ++logfile, flushlog = 1;
      if (!*logfile) logfile = NULL, flushlog = 0;
      else if (logfile[0] == '-' && logfile[1] == '\0')
        logfile = NULL, flog = stdout;
      break;
    case 'L':
      verbose = 1; break;
break;
    case 's':
#ifdef NO_STATS
      fprintf(stderr,
        "%s: warning: no statistics counters support is compiled in\n",
        progname);
#else
      statsfile = optarg;
      if (*statsfile != '+') stats_relative = 0;
      else ++statsfile, stats_relative = 1;
      if (!*statsfile) statsfile = NULL;
#endif
      break;
    case 'q': quickstart = 1; break;
    case 'd':
#ifdef NO_MASTER_DUMP
      error(0, "master-format dump option (-d) isn't compiled in");
#endif
      dump = 1;
      break;
    case 'v': show_version = nover++ ? NULL : "rbldnsd"; break;
    case 'a': lazy = 1; break;
    case 'A': lazy = 0; break;
    case 'f': forkon = 1; break;
    case 'C': nouncompress = 1; break;
#ifndef NO_DSO
    case 'x': ext = optarg; break;
    case 'X': extarg = optarg; break;
#else
    case 'x':
    case 'X':
      error(0, "extension support is not compiled in");
#endif
#ifndef NO_ANONYMIZE
    case 'z': anonymize = 1; break;
#else
    case 'z':
      error(0, "anonymization support is not compiled in");
#endif
#ifndef NO_GEOIP
    case 'g': geoip = 1; break;
    case 'G': geoip = 1; geoip_path = optarg; break;

#else
    case 'g':
    case 'G':
      error(0, "geoip support is not compiled in");
#endif
    case 'h': usage(0);
    default: error(0, "type `%.50s -h' for help", progname);
    }

  if (!(argc -= optind))
    error(0, "no zone(s) to service specified (-h for help)");
  argv += optind;

#ifndef NO_MASTER_DUMP
  if (dump) {
    time_t now;
    logto = LOGTO_STDERR;
    for(c = 0; c < argc; ++c)
      zonelist = addzone(zonelist, argv[c]);
    init_zones_caches(zonelist);
    if (rootdir && (chdir(rootdir) < 0 || chroot(rootdir) < 0))
      error(errno, "unable to chroot to %.50s", rootdir);
    if (workdir && chdir(workdir) < 0)
      error(errno, "unable to chdir to %.50s", workdir);
    if (!do_reload(0))
      error(0, "zone loading errors, aborting");
    now = time(NULL);
    printf("; zone dump made %s", ctime(&now));
    printf("; rbldnsd version %s\n", version);
    for (z = zonelist; z; z = z->z_next)
      dumpzone(z, stdout);
    fflush(stdout);
    exit(ferror(stdout) ? 1 : 0);
  }
#endif

  if (!nba)
    error(0, "no address to listen on (-b option) specified");

  tzset();
  if (nodaemon)
    logto = LOGTO_STDOUT|LOGTO_STDERR;
  else {
    /* fork early so that logging will be from right pid */
    int pfd[2];
    if (pipe(pfd) < 0) error(errno, "pipe() failed");
    c = fork();
    if (c < 0) error(errno, "fork() failed");
    if (c > 0) {
      close(pfd[1]);
      if (read(pfd[0], &c, 1) < 1) exit(1);
      else exit(0);
    }
    cfd = pfd[1];
    close(pfd[0]);
    openlog(progname, LOG_PID|LOG_NDELAY, LOG_DAEMON);
    logto = LOGTO_STDERR|LOGTO_SYSLOG;
    if (!quickstart && !flog) logto |= LOGTO_STDOUT;
  }

  initsockets(bindaddr, nba, family);

#ifndef NO_DSO
  if (ext) {
    void *handle = dlopen(ext, RTLD_NOW);
    if (!handle)
      error(0, "unable to load extension `%s': %s", ext, dlerror());
    extinit = dlsym(handle, "rbldnsd_extension_init");
    if (!extinit)
      error(0, "unable to find extension init routine in `%s'", ext);
  }
#endif

  if (!user && !(uid = getuid()))
    user = "******";

  if (!user)
    p = NULL;
  else {
    if ((p = strchr(user, ':')) != NULL)
      *p++ = '\0';
    if ((c = satoi(user)) >= 0)
      uid = c, gid = c;
    else {
      struct passwd *pw = getpwnam(user);
      if (!pw)
        error(0, "unknown user `%s'", user);
      uid = pw->pw_uid;
      gid = pw->pw_gid;
      endpwent();
    }
  }
  if (!uid)
    error(0, "daemon should not run as root, specify -u option");
  if (p) {
    if ((c = satoi(p)) >= 0)
      gid = c;
    else {
      struct group *gr = getgrnam(p);
      if (!gr)
        error(0, "unknown group `%s'", p);
      gid = gr->gr_gid;
      endgrent();
    }
    p[-1] = ':';
  }

  if (pidfile) {
    int fdpid;
    char buf[40];
    c = sprintf(buf, "%ld\n", (long)getpid());
    fdpid = open(pidfile, O_CREAT|O_WRONLY|O_TRUNC, 0644);
    if (fdpid < 0 || write(fdpid, buf, c) < c)
      error(errno, "unable to write pidfile");
    close(fdpid);
  }

  if (rootdir && (chdir(rootdir) < 0 || chroot(rootdir) < 0))
    error(errno, "unable to chroot to %.50s", rootdir);
  if (workdir && chdir(workdir) < 0)
    error(errno, "unable to chdir to %.50s", workdir);

  if (user)
    if (setgroups(1, &gid) < 0 || setgid(gid) < 0 || setuid(uid) < 0)
      error(errno, "unable to setuid(%d:%d)", (int)uid, (int)gid);

  for(c = 0; c < argc; ++c)
    zonelist = addzone(zonelist, argv[c]);
  init_zones_caches(zonelist);

#ifndef NO_DSO
  if (extinit && extinit(extarg, zonelist) != 0)
    error(0, "unable to iniitialize extension `%s'", ext);
#endif

  if (!quickstart && !do_reload(0))
    error(0, "zone loading errors, aborting");

  /* count number of zones */
  for(c = 0, z = zonelist; z; z = z->z_next)
    ++c;
  numzones = c;

#if STATS_IPC_IOVEC
  stats_iov = (struct iovec *)emalloc(numzones * sizeof(struct iovec));
  for(c = 0, z = zonelist; z; z = z->z_next, ++c) {
    stats_iov[c].iov_base = (char*)&z->z_stats;
    stats_iov[c].iov_len = sizeof(z->z_stats);
  }
#endif
  dslog(LOG_INFO, 0, "rbldnsd version %s started (%d socket(s), %d zone(s))",
        version, numsock, numzones);
  initialized = 1;

  if (cfd >= 0) {
    write(cfd, "", 1);
    close(cfd);
    close(0); close(2);
    if (!flog) close(1);
    setsid();
    logto = LOGTO_SYSLOG;
  }

  if (quickstart)
    do_reload(0);

  /* only set "main" fork_on_reload after first reload */
  fork_on_reload = forkon;
}
Exemple #7
0
static void
initsockets(const char *bindaddr[MAXSOCK], int nba, int UNUSED family) {

  int i, x;
  char *host, *serv;
  const char *ba;

#ifdef NO_IPv6

  struct sockaddr_in sin;
  ip4addr_t sinaddr;
  int port;
  struct servent *se;
  struct hostent *he;

  memset(&sin, 0, sizeof(sin));
  sin.sin_family = AF_INET;

  if (!(se = getservbyname("domain", "udp")))
    port = htons(DNS_PORT);
  else
    port = se->s_port;

#else

  struct addrinfo hints, *aires, *ai;

  memset(&hints, 0, sizeof(hints));
  hints.ai_family = family;
  hints.ai_socktype = SOCK_DGRAM;
  hints.ai_flags = AI_PASSIVE;

#endif

  for (i = 0; i < nba; ++i) {
    ba = bindaddr[i];
    host = estrdup(ba);

    serv = strchr(host, '/');
    if (serv) {
      *serv++ = '\0';
      if (!*host)
        error(0, "missing host part in bind address `%.60s'", ba);
    }

#ifdef NO_IPv6

    if (!serv || !*serv)
      sin.sin_port = port;
    else if ((x = satoi(serv)) > 0 && x <= 0xffff)
      sin.sin_port = htons(x);
    else if (!(se = getservbyname(serv, "udp")))
      error(0, "unknown service in `%.60s'", ba);
    else
      sin.sin_port = se->s_port;

    if (ip4addr(host, &sinaddr, NULL) > 0) {
      sin.sin_addr.s_addr = htonl(sinaddr);
      newsocket(&sin);
    }
    else if (!(he = gethostbyname(host))
             || he->h_addrtype != AF_INET
             || he->h_length != 4
             || !he->h_addr_list[0])
      error(0, "unknown host in `%.60s'", ba);
    else {
      for(x = 0; he->h_addr_list[x]; ++x) {
        memcpy(&sin.sin_addr, he->h_addr_list[x], 4);
        newsocket(&sin);
      }
    }

#else

    if (!serv || !*serv)
      serv = "domain";

    x = getaddrinfo(host, serv, &hints, &aires);
    if (x != 0)
      error(0, "%.60s: %s", ba, gai_strerror(x));
    for(ai = aires, x = 0; ai; ai = ai->ai_next)
      if (newsocket(ai))
        ++x;
    if (!x)
      error(0, "%.60s: no available protocols", ba);
    freeaddrinfo(aires);

#endif

    free(host);
  }
  endservent();
  endhostent();

  for (i = 0; i < numsock; ++i) {
    x = 65536;
    do
      if (setsockopt(sock[i], SOL_SOCKET, SO_RCVBUF, (void*)&x, sizeof x) == 0)
        break;
    while ((x -= (x >> 5)) >= 1024);
  }
}
Exemple #8
0
/* main function - start Rserve */
int main(int argc, char **argv)
{
    int stat, i, http_flags;
	char **top_argv;
	int    top_argc;
	int    rs_silent = 0;

	main_argv = argv;
	main_argc = argc;

    rserve_rev[0] = 0;
    { /* cut out the SVN revision from the Id string */
		const char *c = strstr(rserve_ver_id, ".c ");
		if (c) {
			const char *d = c + 3;
			c = d; while (*c && *c != ' ') c++;
			strncpy(rserve_rev, d, c - d);
		}
    }

#ifdef RSERV_DEBUG
    printf("Rserve %d.%d-%d (%s) (C)Copyright 2002-2013 Simon Urbanek\n%s\n\n",RSRV_VER>>16,(RSRV_VER>>8)&255,RSRV_VER&255, rserve_rev, rserve_ver_id);
#endif
    if (!isByteSexOk()) {
		fprintf(stderr, "FATAL ERROR: This program was not correctly compiled - the endianess is wrong!\nUse -DSWAPEND when compiling on PPC or similar platforms.\n");
		return -100;
    }
    
    loadConfig(CONFIG_FILE);
    
    /** copy argv while removing Rserve specific parameters */
    top_argc = 1;
    top_argv = (char**) malloc(sizeof(char*) * (argc + 1));
    top_argv[0] = argv[0];
    i = 0;
    while (++i < argc) {
		int isRSP = 0;
		if (argv[i] && *argv[i] == '-' && argv[i][1] == '-') {
			if (!strcmp(argv[i] + 2, "RS-port")) {
				isRSP = 1;
				if (++i == argc)
					fprintf(stderr,"Missing port specification for --RS-port.\n");
				else {
					port = satoi(argv[i]);
					if (port < 1) {
						fprintf(stderr,"Invalid port number in --RS-port, using default port.\n");
						port = default_Rsrv_port;
					}
				}
			}
			if (!strcmp(argv[i] + 2, "RS-dumplimit")) {
				isRSP = 1;
				if (++i == argc)
					fprintf(stderr,"Missing limit specification for --RS-dumplimit.\n");
				else {
#ifdef RSERV_DEBUG
					dumpLimit = satoi(argv[i]);
#endif
				}
			}
			if (!strcmp(argv[i] + 2, "RS-socket")) {
				isRSP = 1;
				if (++i == argc)
					fprintf(stderr,"Missing socket specification for --RS-socket.\n");
				else
					localSocketName = argv[i];
			}
			if (!strcmp(argv[i] + 2, "RS-encoding")) {
				isRSP = 1;
				if (++i == argc)
		    fprintf(stderr,"Missing socket specification for --RS-encoding.\n");
				else
					set_string_encoding(argv[i], 1);
			}
			if (!strcmp(argv[i] + 2, "RS-workdir")) {
				isRSP = 1;
				if (++i == argc)
					fprintf(stderr,"Missing directory specification for --RS-workdir.\n");
				else
					workdir=argv[i];
			}
			if (!strcmp(argv[i] + 2, "RS-conf")) {
				isRSP = 1;
				if (++i == argc)
					fprintf(stderr,"Missing config file specification for --RS-conf.\n");
				else
					loadConfig(argv[i]);
			}
			if (!strcmp(argv[i] + 2, "RS-source")) {
				isRSP = 1;
				if (++i == argc)
					fprintf(stderr,"Missing R file specification for --RS-source.\n");
				else
					setConfig("source", argv[i]);
			}
			if (!strcmp(argv[i] + 2, "RS-pidfile")) {
				isRSP = 1;
				if (++i == argc)
					fprintf(stderr,"Missing file specification for --RS-pidfile.\n");
				else
					setConfig("pid.file", argv[i]);
			}
			if (!strcmp(argv[i] + 2, "RS-enable-control")) {
				isRSP = 1;
				setConfig("control", "enable");
			}
			if (!strcmp(argv[i] + 2, "RS-enable-remote")) {
				isRSP = 1;
				setConfig("remote", "enable");
			}
			if (!strcmp(argv[i] + 2, "RS-set")) {
				isRSP = 1;
                if (++i == argc)
					fprintf(stderr,"Missing argument for --RS-set.\n");
				else {
					char *c = argv[i], *c2 = strchr(c, '=');
					if (!c2) 
						c2 = "";
					else {
						*c2 = 0;
						c2++;
					}
					if (!setConfig(c, c2))
						fprintf(stderr, "WARNING: configuration directive '%s' is not supported (used in --RS-set)\n", c);
				}
			}
			if (!strcmp(argv[i] + 2, "RS-settings")) {
				printf("Rserve v%d.%d-%d\n\nconfig file: %s\nworking root: %s\nport: %d\nlocal socket: %s\nauthorization required: %s\nplain text password: %s\npasswords file: %s\nallow I/O: %s\nallow remote access: %s\ncontrol commands: %s\ninteractive: %s\nmax.input buffer size: %ld kB\n\n",
					   RSRV_VER>>16, (RSRV_VER>>8)&255, RSRV_VER&255,
					   CONFIG_FILE, workdir, port, localSocketName ? localSocketName : "[none, TCP/IP used]",
					   authReq ? "yes" : "no", usePlain ? "allowed" : "not allowed", pwdfile ? pwdfile : "[none]",
					   allowIO ? "yes" : "no", localonly ? "no" : "yes",
					   child_control ? "yes" : "no", Rsrv_interactive ? "yes" : "no", maxInBuf / 1024L);
				return 0;	       
			}
			if (!strcmp(argv[i] + 2, "version")) {
				printf("Rserve v%d.%d-%d (%s)\n",RSRV_VER>>16,(RSRV_VER>>8)&255,RSRV_VER&255,rserve_rev);
			}
			/* this is really an R option but we'll abuse it to stay really silent
			   note that we don't use -q/--quiet so there is a way to pick and choose */
			if (!strcmp(argv[i] + 2, "silent")) {
				rs_silent = 1;
			}
			if (!strcmp(argv[i] + 2, "help")) {
				printf("Usage: R CMD Rserve [<options>]\n\nOptions: --help  this help screen\n --version  prints Rserve version (also passed to R)\n --RS-port <port>  listen on the specified TCP port\n --RS-socket <socket>  use specified local (unix) socket instead of TCP/IP.\n --RS-workdir <path>  use specified working directory root for connections.\n --RS-encoding <enc>  set default server string encoding to <enc>.\n --RS-conf <file>  load additional config file.\n --RS-settings  dumps current settings of the Rserve\n --RS-source <file>  source the specified file on startup.\n --RS-enable-control  enable control commands\n --RS-enable-remote  enable remote connections\n --RS-set <config>=<value>   set configuration option as if it was\n                              read from a configuration file\n\nAll other options are passed to the R engine.\n\n");
#ifdef RSERV_DEBUG
				printf("debugging flag:\n --RS-dumplimit <number>  sets limit of items/bytes to dump in debugging output. set to 0 for unlimited\n\n");
#endif
				return 0;
			}
		}