Ejemplo n.º 1
0
int main(int argc, char *argv[])
{
    CURL *curl;
    CURLcode res;
    int ch;
    struct curl_httppost *post=NULL, *last=NULL;
    struct curl_slist *slist = NULL;
    char *name=NULL, *email=NULL, *filename=NULL;
    int setURL=0, fromStream=0;

    curl_global_init(CURL_GLOBAL_ALL);

    curl = curl_easy_init();
    if (!(curl)) {
        fprintf(stderr, "ERROR: Could not initialize libcurl\n");
        exit(1);
    }

    while ((ch = my_getopt(argc, argv, OPTS)) > 0) {
        switch (ch) {
            case 'v':
                version();
            case 'e':
                email = optarg;
                break;
            case 'N':
                name = optarg;
                break;
            case 'p':
                if (setURL)
                    usage(argv[0]);

                filename = optarg;

                curl_easy_setopt(curl, CURLOPT_URL, "http://cgi.clamav.net/sendfp.cgi");
                setURL=1;
                break;
            case 'n':
                if (setURL)
                    usage(argv[0]);

                filename = optarg;

                curl_easy_setopt(curl, CURLOPT_URL, "http://cgi.clamav.net/sendmalware.cgi");
                setURL=1;
                break;
            case 'h':
            case '?':
            default:
                usage(argv[0]);
        }
    }

    if (!(name) || !(email) || !(filename))
        usage(argv[0]);

    if (strlen(filename) == 1 && filename[0] == '-') {
        filename = read_stream();
        if (!(filename)) {
            fprintf(stderr, "ERROR: Unable to read stream\n");
            exit(1);
        }

        fromStream=1;
    }

    slist = curl_slist_append(slist, "Expect:");
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, slist);

    if (curl_formadd(&post, &last, CURLFORM_COPYNAME, "sendername", CURLFORM_COPYCONTENTS, name, CURLFORM_END)) {
        fprintf(stderr, "Unable to specify name in libcurl form for file %s\n", optarg);
        goto end;
    }

    if (curl_formadd(&post, &last, CURLFORM_COPYNAME, "email", CURLFORM_COPYCONTENTS, email, CURLFORM_END)) {
        fprintf(stderr, "Unable to specify email in libcurl form for file %s\n", optarg);
        goto end;
    }

    if (curl_formadd(&post, &last, CURLFORM_COPYNAME, "file", CURLFORM_FILE, filename, CURLFORM_END)) {
        fprintf(stderr, "Unable to specify file path in libcurl form for file %s\n", optarg);
        goto end;
    }

    curl_formadd(&post, &last, CURLFORM_COPYNAME, "action", CURLFORM_COPYCONTENTS, "submit", CURLFORM_END);
    curl_formadd(&post, &last, CURLFORM_COPYNAME, "privacy", CURLFORM_COPYCONTENTS, "yes", CURLFORM_END);
    curl_formadd(&post, &last, CURLFORM_COPYNAME, "notify", CURLFORM_COPYCONTENTS, "yes", CURLFORM_END);

    curl_easy_setopt(curl, CURLOPT_HTTPPOST, post);
    res = curl_easy_perform(curl);

    if (res) {
        fprintf(stderr, "Error: %s\n", curl_easy_strerror(res));
    }

end:
    curl_easy_cleanup(curl);
    if (fromStream) {
        remove(filename);
        free(filename);
    }

    return 0;
}
Ejemplo n.º 2
0
int my_getopt(int argc, char * argv[], const char *opts)
{
  static int charind=0;
  const char *s;
  char mode, colon_mode;
  int off = 0, opt = -1;

  if(getenv("POSIXLY_CORRECT")) colon_mode = mode = '+';
  else {
    if((colon_mode = *opts) == ':') off ++;
    if(((mode = opts[off]) == '+') || (mode == '-')) {
      off++;
      if((colon_mode != ':') && ((colon_mode = opts[off]) == ':'))
        off ++;
    }
  }
  my_optarg = 0;
  if(charind) {
    my_optopt = argv[my_optind][charind];
    for(s=opts+off; *s; s++) if(my_optopt == *s) {
      charind++;
      if((*(++s) == ':') || ((my_optopt == 'W') && (*s == ';'))) {
        if(argv[my_optind][charind]) {
          my_optarg = &(argv[my_optind++][charind]);
          charind = 0;
        } else if(*(++s) != ':') {
          charind = 0;
          if(++my_optind >= argc) {
            if(my_opterr) fprintf(stderr,
                                "%s: option requires an argument -- %c\n",
                                argv[0], my_optopt);
            opt = (colon_mode == ':') ? ':' : '?';
            goto my_getopt_ok;
          }
          my_optarg = argv[my_optind++];
        }
      }
      opt = my_optopt;
      goto my_getopt_ok;
    }
    if(my_opterr) fprintf(stderr,
                        "%s: illegal option -- %c\n",
                        argv[0], my_optopt);
    opt = '?';
    if(argv[my_optind][++charind] == '\0') {
      my_optind++;
      charind = 0;
    }
  my_getopt_ok:
    if(charind && ! argv[my_optind][charind]) {
      my_optind++;
      charind = 0;
    }
  } else if((my_optind >= argc) ||
             ((argv[my_optind][0] == '-') &&
              (argv[my_optind][1] == '-') &&
              (argv[my_optind][2] == '\0'))) {
    my_optind++;
    opt = -1;
  } else if((argv[my_optind][0] != '-') ||
             (argv[my_optind][1] == '\0')) {
    char *tmp;
    int i, j, k;

    if(mode == '+') opt = -1;
    else if(mode == '-') {
      my_optarg = argv[my_optind++];
      charind = 0;
      opt = 1;
    } else {
      for(i=j=my_optind; i<argc; i++) if((argv[i][0] == '-') &&
                                        (argv[i][1] != '\0')) {
        my_optind=i;
        opt=my_getopt(argc, argv, opts);
        while(i > j) {
          tmp=argv[--i];
          for(k=i; k+1<my_optind; k++) argv[k]=argv[k+1];
          argv[--my_optind]=tmp;
        }
        break;
      }
      if(i == argc) opt = -1;
    }
  } else {
    charind++;
    opt = my_getopt(argc, argv, opts);
  }
  if (my_optind > argc) my_optind = argc;
  return opt;
}
Ejemplo n.º 3
0
int bench_main(int argc, char *argv[])
{
     double tmin = 0.0;
     double tol;
     int repeat = 0;
     int rounds = 10;
     int iarounds = 0;
     int arounds = 1; /* this is too low for precise results */
     int c;

     report = report_verbose; /* default */
     verbose = 0;

     tol = SINGLE_PRECISION ? 1.0e-3 : (QUAD_PRECISION ? 1e-29 : 1.0e-10);

     main_init(&argc, &argv);

     bench_srand(1);

     while ((c = my_getopt (argc, argv, options)) != -1) {
	  switch (c) {
	      case 't' :
		   tmin = strtod(my_optarg, 0);
		   break;
	      case 'r':
		   repeat = atoi(my_optarg);
		   break;
	      case 's':
		   timer_init(tmin, repeat);
		   speed(my_optarg, 0);
		   break;
	      case 'S':
		   timer_init(tmin, repeat);
		   speed(my_optarg, 1);
		   break;
	      case 'd':
		   report_can_do(my_optarg);
		   break;
	      case 'o':
		   useropt(my_optarg);
		   break;
	      case 'v':
		   if (verbose >= 0) { /* verbose < 0 disables output */
			if (my_optarg)
			     verbose = atoi(my_optarg);
			else
			     ++verbose;
		   }
		   break;
	      case 'y':
		   verify(my_optarg, rounds, tol);
		   break;
	      case 'a':
		   accuracy(my_optarg, arounds, iarounds);
		   break;
	      case 'i':
		   report_info(my_optarg);
		   break;
	      case 'I':
		   report_info_all();
		   break;
	      case 'h':
		   if (verbose >= 0) my_usage(argv[0], options);
		   break;

	      case 300: /* --report-mflops */
		   report = report_mflops;
		   break;

	      case 310: /* --report-time */
		   report = report_time;
		   break;

 	      case 320: /* --report-benchmark */
		   report = report_benchmark;
		   break;

 	      case 330: /* --report-verbose */
		   report = report_verbose;
		   break;

	      case 400: /* --print-time-min */
		   timer_init(tmin, repeat);
		   ovtpvt("%g\n", time_min);
		   break;

	      case 401: /* --verify-rounds */
		   rounds = atoi(my_optarg);
		   break;

	      case 402: /* --print-precision */
		   if (SINGLE_PRECISION)
			ovtpvt("single\n");
		   else if (QUAD_PRECISION)
			ovtpvt("quad\n");
		   else if (LDOUBLE_PRECISION)
			ovtpvt("long-double\n");
		   else if (DOUBLE_PRECISION)
			ovtpvt("double\n");
		   else 
			ovtpvt("unknown %d\n", sizeof(bench_real));
		   break;

	      case 403: /* --verify-tolerance */
		   tol = strtod(my_optarg, 0);
		   break;

	      case 404: /* --random-seed */
		   bench_srand(atoi(my_optarg));
		   break;

	      case 405: /* --accuracy-rounds */
		   arounds = atoi(my_optarg);
		   break;
		   
	      case 406: /* --impulse-accuracy-rounds */
		   iarounds = atoi(my_optarg);
		   break;
		   
	      case '?':
		   /* my_getopt() already printed an error message. */
		   cleanup();
		   return 1;

	      default:
		   abort ();
	  }
     }

     /* assume that any remaining arguments are problems to be
        benchmarked */
     while (my_optind < argc) {
	  timer_init(tmin, repeat);
	  speed(argv[my_optind++], 0);
     }

     cleanup();
     return 0;
}
Ejemplo n.º 4
0
int _my_getopt_internal(int argc, char * argv[], const char *shortopts,
                     const struct option *longopts, int *longind,
                     int long_only)
{
  char mode, colon_mode = *shortopts;
  int shortoff = 0, opt = -1;

  if(getenv("POSIXLY_CORRECT")) colon_mode = mode = '+';
  else {
    if((colon_mode = *shortopts) == ':') shortoff ++;
    if(((mode = shortopts[shortoff]) == '+') || (mode == '-')) {
      shortoff++;
      if((colon_mode != ':') && ((colon_mode = shortopts[shortoff]) == ':'))
        shortoff ++;
    }
  }
  my_optarg = 0;
  if((my_optind >= argc) ||
      ((argv[my_optind][0] == '-') &&
       (argv[my_optind][1] == '-') &&
       (argv[my_optind][2] == '\0'))) {
    my_optind++;
    opt = -1;
  } else if((argv[my_optind][0] != '-') ||
            (argv[my_optind][1] == '\0')) {
    char *tmp;
    int i, j, k;

    opt = -1;
    if(mode == '+') return -1;
    else if(mode == '-') {
      my_optarg = argv[my_optind++];
      return 1;
    }
    for(i=j=my_optind; i<argc; i++) if((argv[i][0] == '-') &&
                                    (argv[i][1] != '\0')) {
      my_optind=i;
      opt=_my_getopt_internal(argc, argv, shortopts,
                              longopts, longind,
                              long_only);
      while(i > j) {
        tmp=argv[--i];
        for(k=i; k+1<my_optind; k++)
          argv[k]=argv[k+1];
        argv[--my_optind]=tmp;
      }
      break;
    }
  } else if((!long_only) && (argv[my_optind][1] != '-'))
    opt = my_getopt(argc, argv, shortopts);
  else {
    int charind, offset;
    int found = 0, ind, hits = 0;

    if(((my_optopt = argv[my_optind][1]) != '-') && ! argv[my_optind][2]) {
      int c;
      
      ind = shortoff;
      while((c = shortopts[ind++])) {
        if(((shortopts[ind] == ':') ||
            ((c == 'W') && (shortopts[ind] == ';'))) &&
           (shortopts[++ind] == ':'))
          ind ++;
        if(my_optopt == c) return my_getopt(argc, argv, shortopts);
      }
    }
    offset = 2 - (argv[my_optind][1] != '-');
    for(charind = offset;
        (argv[my_optind][charind] != '\0') &&
          (argv[my_optind][charind] != '=');
        charind++);
    for(ind = 0; longopts[ind].name && !hits; ind++)
      if((strlen(longopts[ind].name) == (size_t) (charind - offset)) &&
         (strncmp(longopts[ind].name,
                  argv[my_optind] + offset, charind - offset) == 0))
        found = ind, hits++;
    if(!hits) for(ind = 0; longopts[ind].name; ind++)
      if(strncmp(longopts[ind].name,
                 argv[my_optind] + offset, charind - offset) == 0)
        found = ind, hits++;
    if(hits == 1) {
      opt = 0;

      if(argv[my_optind][charind] == '=') {
        if(longopts[found].has_arg == 0) {
          opt = '?';
          if(my_opterr) fprintf(stderr,
                             "%s: option `--%s' doesn't allow an argument\n",
                             argv[0], longopts[found].name);
        } else {
          my_optarg = argv[my_optind] + ++charind;
          charind = 0;
        }
      } else if(longopts[found].has_arg == 1) {
        if(++my_optind >= argc) {
          opt = (colon_mode == ':') ? ':' : '?';
          if(my_opterr) fprintf(stderr,
                             "%s: option `--%s' requires an argument\n",
                             argv[0], longopts[found].name);
        } else my_optarg = argv[my_optind];
      }
      if(!opt) {
        if (longind) *longind = found;
        if(!longopts[found].flag) opt = longopts[found].val;
        else *(longopts[found].flag) = longopts[found].val;
      }
      my_optind++;
    } else if(!hits) {
      if(offset == 1) opt = my_getopt(argc, argv, shortopts);
      else {
        opt = '?';
        if(my_opterr) fprintf(stderr,
                           "%s: unrecognized option `%s'\n",
                           argv[0], argv[my_optind++]);
      }
    } else {
      opt = '?';
      if(my_opterr) fprintf(stderr,
                         "%s: option `%s' is ambiguous\n",
                         argv[0], argv[my_optind++]);
    }
  }
  if (my_optind > argc) my_optind = argc;
  return opt;
}
Ejemplo n.º 5
0
int NaClSelLdrMain(int argc, char **argv) {
  int                           opt;
  char                          *rest;
  struct redir                  *entry;
  struct redir                  *redir_queue;
  struct redir                  **redir_qend;


  struct NaClApp                state;
  char                          *nacl_file = NULL;
  char                          *blob_library_file = NULL;
  int                           rpc_supplies_nexe = 0;
  int                           export_addr_to = -1;

  struct NaClApp                *nap = &state;

  struct GioFile                gout;
  NaClErrorCode                 errcode = LOAD_INTERNAL;
  struct GioMemoryFileSnapshot  blob_file;

  int                           ret_code;
  struct DynArray               env_vars;

  char                          *log_file = NULL;
  int                           verbosity = 0;
  int                           fuzzing_quit_after_load = 0;
  int                           debug_mode_bypass_acl_checks = 0;
  int                           debug_mode_ignore_validator = 0;
  int                           skip_qualification = 0;
  int                           handle_signals = 0;
  int                           enable_debug_stub = 0;
  struct NaClPerfCounter        time_all_main;
  const char                    **envp;
  struct NaClEnvCleanser        env_cleanser;

#if NACL_OSX
  /* Mac dynamic libraries cannot access the environ variable directly. */
  envp = (const char **) *_NSGetEnviron();
#else
  /* Overzealous code style check is overzealous. */
  /* @IGNORE_LINES_FOR_CODE_HYGIENE[1] */
  extern char **environ;
  envp = (const char **) environ;
#endif

  ret_code = 1;
  redir_queue = NULL;
  redir_qend = &redir_queue;

  memset(&state, 0, sizeof state);
  NaClAllModulesInit();
  NaClBootstrapChannelErrorReporterInit();
  NaClErrorLogHookInit(NaClBootstrapChannelErrorReporter, &state);

  verbosity = NaClLogGetVerbosity();

  NaClPerfCounterCtor(&time_all_main, "SelMain");

  fflush((FILE *) NULL);

  NaClDebugExceptionHandlerStandaloneHandleArgs(argc, argv);

  if (!GioFileRefCtor(&gout, stdout)) {
    fprintf(stderr, "Could not create general standard output channel\n");
    exit(1);
  }
  if (!NaClAppCtor(&state)) {
    NaClLog(LOG_FATAL, "NaClAppCtor() failed\n");
  }
  if (!DynArrayCtor(&env_vars, 0)) {
    NaClLog(LOG_FATAL, "Failed to allocate env var array\n");
  }
  /*
   * On platforms with glibc getopt, require POSIXLY_CORRECT behavior,
   * viz, no reordering of the arglist -- stop argument processing as
   * soon as an unrecognized argument is encountered, so that, for
   * example, in the invocation
   *
   *   sel_ldr foo.nexe -vvv
   *
   * the -vvv flags are made available to the nexe, rather than being
   * consumed by getopt.  This makes the behavior of the Linux build
   * of sel_ldr consistent with the Windows and OSX builds.
   */
  while ((opt = my_getopt(argc, argv,
#if NACL_LINUX
                       "+D:z:"
#endif
                       "aB:ceE:f:Fgh:i:l:Qr:RsSvw:X:Z")) != -1) {
    switch (opt) {
      case 'a':
        fprintf(stderr, "DEBUG MODE ENABLED (bypass acl)\n");
        debug_mode_bypass_acl_checks = 1;
        break;
      case 'B':
        blob_library_file = optarg;
        break;
      case 'c':
        ++debug_mode_ignore_validator;
        break;
#if NACL_LINUX
      case 'D':
        NaClHandleRDebug(optarg, argv[0]);
        break;
#endif
      case 'e':
        nap->enable_exception_handling = 1;
        break;
      case 'E':
        /*
         * For simplicity, we treat the environment variables as a
         * list of strings rather than a key/value mapping.  We do not
         * try to prevent duplicate keys or require the strings to be
         * of the form "KEY=VALUE".  This is in line with how execve()
         * works in Unix.
         *
         * We expect that most callers passing "-E" will either pass
         * in a fixed list or will construct the list using a
         * high-level language, in which case de-duplicating keys
         * outside of sel_ldr is easier.  However, we could do
         * de-duplication here if it proves to be worthwhile.
         */
        if (!DynArraySet(&env_vars, env_vars.num_entries, optarg)) {
          NaClLog(LOG_FATAL, "Adding item to env_vars failed\n");
        }
        break;
      case 'f':
        nacl_file = optarg;
        break;
      case 'F':
        fuzzing_quit_after_load = 1;
        break;

      case 'g':
        enable_debug_stub = 1;
        break;

      case 'h':
      case 'r':
      case 'w':
        /* import host descriptor */
        entry = malloc(sizeof *entry);
        if (NULL == entry) {
          fprintf(stderr, "No memory for redirection queue\n");
          exit(1);
        }
        entry->next = NULL;
        entry->nacl_desc = strtol(optarg, &rest, 0);
        entry->tag = HOST_DESC;
        entry->u.host.d = strtol(rest+1, (char **) 0, 0);
        entry->u.host.mode = ImportModeMap(opt);
        *redir_qend = entry;
        redir_qend = &entry->next;
        break;
      case 'i':
        /* import IMC handle */
        entry = malloc(sizeof *entry);
        if (NULL == entry) {
          fprintf(stderr, "No memory for redirection queue\n");
          exit(1);
        }
        entry->next = NULL;
        entry->nacl_desc = strtol(optarg, &rest, 0);
        entry->tag = IMC_DESC;
        entry->u.handle = (NaClHandle) strtol(rest+1, (char **) 0, 0);
        *redir_qend = entry;
        redir_qend = &entry->next;
        break;
      case 'l':
        log_file = optarg;
        break;
      case 'Q':
        fprintf(stderr, "PLATFORM QUALIFICATION DISABLED BY -Q - "
                "Native Client's sandbox will be unreliable!\n");
        skip_qualification = 1;
        break;
      case 'R':
        rpc_supplies_nexe = 1;
        break;
      /* case 'r':  with 'h' and 'w' above */
      case 's':
        nap->validator_stub_out_mode = 1;
        break;
      case 'S':
        handle_signals = 1;
        break;
      case 'v':
        ++verbosity;
        NaClLogIncrVerbosity();
        break;
      /* case 'w':  with 'h' and 'r' above */
      case 'X':
        export_addr_to = strtol(optarg, (char **) 0, 0);
        break;
#if NACL_LINUX
      case 'z':
        NaClHandleReservedAtZero(optarg);
        break;
#endif
      case 'Z':
        NaClLog(LOG_WARNING, "Enabling Fixed-Feature CPU Mode\n");
        nap->fixed_feature_cpu_mode = 1;
        if (!nap->validator->FixCPUFeatures(nap->cpu_features)) {
          NaClLog(LOG_ERROR,
                  "This CPU lacks features required by "
                  "fixed-function CPU mode.\n");
          exit(1);
        }
        break;
      default:
        fprintf(stderr, "ERROR: unknown option: [%c]\n\n", opt);
        PrintUsage();
        exit(-1);
    }
  }

  if (debug_mode_ignore_validator == 1)
    fprintf(stderr, "DEBUG MODE ENABLED (ignore validator)\n");
  else if (debug_mode_ignore_validator > 1)
    fprintf(stderr, "DEBUG MODE ENABLED (skip validator)\n");

  if (verbosity) {
    int         ix;
    char const  *separator = "";

    fprintf(stderr, "sel_ldr argument list:\n");
    for (ix = 0; ix < argc; ++ix) {
      fprintf(stderr, "%s%s", separator, argv[ix]);
      separator = " ";
    }
    putc('\n', stderr);
  }

  if (debug_mode_bypass_acl_checks) {
    NaClInsecurelyBypassAllAclChecks();
  }

  /*
   * change stdout/stderr to log file now, so that subsequent error
   * messages will go there.  unfortunately, error messages that
   * result from getopt processing -- usually out-of-memory, which
   * shouldn't happen -- won't show up.
   */
  if (NULL != log_file) {
    NaClLogSetFile(log_file);
  }

  if (rpc_supplies_nexe) {
    if (NULL != nacl_file) {
      fprintf(stderr,
              "sel_ldr: mutually exclusive flags -f and -R both used\n");
      exit(1);
    }
    /* post: NULL == nacl_file */
    if (export_addr_to < 0) {
      fprintf(stderr,
              "sel_ldr: -R requires -X to set up secure command channel\n");
      exit(1);
    }
  } else {
    if (NULL == nacl_file && optind < argc) {
      nacl_file = argv[optind];
      ++optind;
    }
    if (NULL == nacl_file) {
      fprintf(stderr, "No nacl file specified\n");
      exit(1);
    }
    /* post: NULL != nacl_file */
  }
  /*
   * post condition established by the above code (in Hoare logic
   * terminology):
   *
   * NULL == nacl_file iff rpc_supplies_nexe
   *
   * so hence forth, testing !rpc_supplies_nexe suffices for
   * establishing NULL != nacl_file.
   */
  CHECK((NULL == nacl_file) == rpc_supplies_nexe);

  /* to be passed to NaClMain, eventually... */
  argv[--optind] = (char *) "NaClMain";

  state.ignore_validator_result = (debug_mode_ignore_validator > 0);
  state.skip_validator = (debug_mode_ignore_validator > 1);

  if (getenv("NACL_UNTRUSTED_EXCEPTION_HANDLING") != NULL) {
    state.enable_exception_handling = 1;
  }
  if (state.enable_exception_handling || enable_debug_stub) {
#if NACL_WINDOWS
    state.attach_debug_exception_handler_func =
        NaClDebugExceptionHandlerStandaloneAttach;
#elif NACL_LINUX
    /* NaCl's signal handler is always enabled on Linux. */
#elif NACL_OSX
    if (!NaClInterceptMachExceptions()) {
      fprintf(stderr, "ERROR setting up Mach exception interception.\n");
      return -1;
    }
#else
# error Unknown host OS
#endif
  }
  if (NACL_LINUX) {
    handle_signals = 1;
  }

  errcode = LOAD_OK;

  /*
   * in order to report load error to the browser plugin through the
   * secure command channel, we do not immediate jump to cleanup code
   * on error.  rather, we continue processing (assuming earlier
   * errors do not make it inappropriate) until the secure command
   * channel is set up, and then bail out.
   */

  /*
   * Ensure the platform qualification checks pass.
   *
   * NACL_DANGEROUS_SKIP_QUALIFICATION_TEST is used by tsan / memcheck
   * (see src/third_party/valgrind/).
   */
  if (!skip_qualification &&
      getenv("NACL_DANGEROUS_SKIP_QUALIFICATION_TEST") != NULL) {
    fprintf(stderr, "PLATFORM QUALIFICATION DISABLED BY ENVIRONMENT - "
            "Native Client's sandbox will be unreliable!\n");
    skip_qualification = 1;
  }

  if (!skip_qualification) {
    NaClErrorCode pq_error = NACL_FI_VAL("pq", NaClErrorCode,
                                         NaClRunSelQualificationTests());
    if (LOAD_OK != pq_error) {
      errcode = pq_error;
      nap->module_load_status = pq_error;
      fprintf(stderr, "Error while loading \"%s\": %s\n",
              NULL != nacl_file ? nacl_file
                                : "(no file, to-be-supplied-via-RPC)",
              NaClErrorString(errcode));
    }
  }

  if (handle_signals) {
    NaClSignalHandlerInit();
  } else {
    /*
     * Patch the Windows exception dispatcher to be safe in the case
     * of faults inside x86-64 sandboxed code.  The sandbox is not
     * secure on 64-bit Windows without this.
     */
#if (NACL_WINDOWS && NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86 && \
     NACL_BUILD_SUBARCH == 64)
    NaClPatchWindowsExceptionDispatcher();
#endif
  }
  NaClSignalTestCrashOnStartup();

  /*
   * Open both files first because (on Mac OS X at least)
   * NaClAppLoadFile() enables an outer sandbox.
   */
  if (NULL != blob_library_file) {
    NaClFileNameForValgrind(blob_library_file);
    if (0 == GioMemoryFileSnapshotCtor(&blob_file, blob_library_file)) {
      perror("sel_main");
      fprintf(stderr, "Cannot open \"%s\".\n", blob_library_file);
      exit(1);
    }
    NaClPerfCounterMark(&time_all_main, "SnapshotBlob");
    NaClPerfCounterIntervalLast(&time_all_main);
  }

  NaClAppInitialDescriptorHookup(nap);

  if (!rpc_supplies_nexe) {
    struct GioMemoryFileSnapshot main_file;

    NaClFileNameForValgrind(nacl_file);
    if (0 == GioMemoryFileSnapshotCtor(&main_file, nacl_file)) {
      perror("sel_main");
      fprintf(stderr, "Cannot open \"%s\".\n", nacl_file);
      exit(1);
    }
    NaClPerfCounterMark(&time_all_main, "SnapshotNaclFile");
    NaClPerfCounterIntervalLast(&time_all_main);

    if (LOAD_OK == errcode) {
      NaClLog(2, "Loading nacl file %s (non-RPC)\n", nacl_file);
      errcode = NaClAppLoadFile((struct Gio *) &main_file, nap);
      if (LOAD_OK != errcode) {
        fprintf(stderr, "Error while loading \"%s\": %s\n",
                nacl_file,
                NaClErrorString(errcode));
        fprintf(stderr,
                ("Using the wrong type of nexe (nacl-x86-32"
                 " on an x86-64 or vice versa)\n"
                 "or a corrupt nexe file may be"
                 " responsible for this error.\n"));
      }
      NaClPerfCounterMark(&time_all_main, "AppLoadEnd");
      NaClPerfCounterIntervalLast(&time_all_main);

      NaClXMutexLock(&nap->mu);
      nap->module_load_status = errcode;
      NaClXCondVarBroadcast(&nap->cv);
      NaClXMutexUnlock(&nap->mu);
    }

    if (-1 == (*((struct Gio *) &main_file)->vtbl->Close)((struct Gio *)
                                                          &main_file)) {
      fprintf(stderr, "Error while closing \"%s\".\n", nacl_file);
    }
    (*((struct Gio *) &main_file)->vtbl->Dtor)((struct Gio *) &main_file);

    if (fuzzing_quit_after_load) {
      exit(0);
    }
  }

  /*
   * Execute additional I/O redirections.  NB: since the NaClApp
   * takes ownership of host / IMC socket descriptors, all but
   * the first run will not get access if the NaClApp closes
   * them.  Currently a normal NaClApp process exit does not
   * close descriptors, since the underlying host OS will do so
   * as part of service runtime exit.
   */
  NaClLog(4, "Processing I/O redirection/inheritance from command line\n");
  for (entry = redir_queue; NULL != entry; entry = entry->next) {
    switch (entry->tag) {
      case HOST_DESC:
        NaClAddHostDescriptor(nap, entry->u.host.d,
                              entry->u.host.mode, entry->nacl_desc);
        break;
      case IMC_DESC:
        NaClAddImcHandle(nap, entry->u.handle, entry->nacl_desc);
        break;
    }
  }

  /*
   * If export_addr_to is set to a non-negative integer, we create a
   * bound socket and socket address pair and bind the former to
   * descriptor NACL_SERVICE_PORT_DESCRIPTOR (3 [see sel_ldr.h]) and
   * the latter to descriptor NACL_SERVICE_ADDRESS_DESCRIPTOR (4).
   * The socket address is sent to the export_addr_to descriptor.
   *
   * The service runtime also accepts a connection on the bound socket
   * and spawns a secure command channel thread to service it.
   */
  if (0 <= export_addr_to) {
    NaClCreateServiceSocket(nap);
    /*
     * LOG_FATAL errors that occur before NaClSetUpBootstrapChannel will
     * not be reported via the crash log mechanism (for Chromium
     * embedding of NaCl, shown in the JavaScript console).
     *
     * Some errors, such as due to NaClRunSelQualificationTests, do not
     * trigger a LOG_FATAL but instead set module_load_status to be sent
     * in the start_module RPC reply.  Log messages associated with such
     * errors would be seen, since NaClSetUpBootstrapChannel will get
     * called.
     */
    NaClSetUpBootstrapChannel(nap, (NaClHandle) export_addr_to);
    /*
     * NB: spawns a thread that uses the command channel.  we do
     * this after NaClAppLoadFile so that NaClApp object is more
     * fully populated.  Hereafter any changes to nap should be done
     * while holding locks.
     */
    NaClSecureCommandChannel(nap);
  }

  /*
   * May have created a thread, so need to synchronize uses of nap
   * contents henceforth.
   */

  if (rpc_supplies_nexe) {
    errcode = NaClWaitForLoadModuleStatus(nap);
    NaClPerfCounterMark(&time_all_main, "WaitForLoad");
    NaClPerfCounterIntervalLast(&time_all_main);
  } else {
    /**************************************************************************
     * TODO(bsy): This else block should be made unconditional and
     * invoked after the LoadModule RPC completes, eliminating the
     * essentially dulicated code in latter part of NaClLoadModuleRpc.
     * This cannot be done until we have full saucer separation
     * technology, since Chrome currently uses sel_main_chrome.c and
     * relies on the functionality of the duplicated code.
     *************************************************************************/
    if (LOAD_OK == errcode) {
      if (verbosity) {
        gprintf((struct Gio *) &gout, "printing NaClApp details\n");
        NaClAppPrintDetails(nap, (struct Gio *) &gout);
      }

      /*
       * Finish setting up the NaCl App.  On x86-32, this means
       * allocating segment selectors.  On x86-64 and ARM, this is
       * (currently) a no-op.
       */
      errcode = NaClAppPrepareToLaunch(nap);
      if (LOAD_OK != errcode) {
        nap->module_load_status = errcode;
        fprintf(stderr, "NaClAppPrepareToLaunch returned %d", errcode);
      }
      NaClPerfCounterMark(&time_all_main, "AppPrepLaunch");
      NaClPerfCounterIntervalLast(&time_all_main);
    }

    /* Give debuggers a well known point at which xlate_base is known.  */
    NaClGdbHook(&state);
  }

  /*
   * Tell the debug stub to bind a TCP port before enabling the outer
   * sandbox.  This is only needed on Mac OS X since that is the only
   * platform where we have an outer sandbox in standalone sel_ldr.
   * In principle this call should work on all platforms, but Windows
   * XP seems to have some problems when we do bind()/listen() on a
   * separate thread from accept().
   */
  if (enable_debug_stub && NACL_OSX) {
    if (!NaClDebugBindSocket()) {
      exit(1);
    }
  }

  /*
   * Enable the outer sandbox, if one is defined.  Do this as soon as
   * possible.
   *
   * This must come after NaClWaitForLoadModuleStatus(), which waits
   * for another thread to have called NaClAppLoadFile().
   * NaClAppLoadFile() does not work inside the Mac outer sandbox in
   * standalone sel_ldr when using a dynamic code area because it uses
   * NaClCreateMemoryObject() which opens a file in /tmp.
   *
   * We cannot enable the sandbox if file access is enabled.
   */
  if (!NaClAclBypassChecks && g_enable_outer_sandbox_func != NULL) {
    g_enable_outer_sandbox_func();
  }

  if (NULL != blob_library_file) {
    if (LOAD_OK == errcode) {
      NaClLog(2, "Loading blob file %s\n", blob_library_file);
      errcode = NaClAppLoadFileDynamically(nap, (struct Gio *) &blob_file);
      if (LOAD_OK != errcode) {
        fprintf(stderr, "Error while loading \"%s\": %s\n",
                blob_library_file,
                NaClErrorString(errcode));
      }
      NaClPerfCounterMark(&time_all_main, "BlobLoaded");
      NaClPerfCounterIntervalLast(&time_all_main);
    }

    if (-1 == (*((struct Gio *) &blob_file)->vtbl->Close)((struct Gio *)
                                                          &blob_file)) {
      fprintf(stderr, "Error while closing \"%s\".\n", blob_library_file);
    }
    (*((struct Gio *) &blob_file)->vtbl->Dtor)((struct Gio *) &blob_file);
    if (verbosity) {
      gprintf((struct Gio *) &gout, "printing post-IRT NaClApp details\n");
      NaClAppPrintDetails(nap, (struct Gio *) &gout);
    }
  }

  /*
   * Print out a marker for scripts to use to mark the start of app
   * output.
   */
  NaClLog(1, "NACL: Application output follows\n");

  /*
   * Make sure all the file buffers are flushed before entering
   * the application code.
   */
  fflush((FILE *) NULL);

  if (NULL != nap->secure_service) {
    NaClErrorCode start_result;
    /*
     * wait for start_module RPC call on secure channel thread.
     */
    start_result = NaClWaitForStartModuleCommand(nap);
    NaClPerfCounterMark(&time_all_main, "WaitedForStartModuleCommand");
    NaClPerfCounterIntervalLast(&time_all_main);
    if (LOAD_OK == errcode) {
      errcode = start_result;
    }
  }

  /*
   * error reporting done; can quit now if there was an error earlier.
   */
  if (LOAD_OK != errcode) {
    NaClLog(4,
            "Not running app code since errcode is %s (%d)\n",
            NaClErrorString(errcode),
            errcode);
    goto done;
  }

  if (!DynArraySet(&env_vars, env_vars.num_entries, NULL)) {
    NaClLog(LOG_FATAL, "Adding env_vars NULL terminator failed\n");
  }

  NaClEnvCleanserCtor(&env_cleanser, 0);
  if (!NaClEnvCleanserInit(&env_cleanser, envp,
          (char const *const *)env_vars.ptr_array)) {
    NaClLog(LOG_FATAL, "Failed to initialise env cleanser\n");
  }

  if (!NaClAppLaunchServiceThreads(nap)) {
    fprintf(stderr, "Launch service threads failed\n");
    goto done;
  }
  if (enable_debug_stub) {
    if (!NaClDebugInit(nap)) {
      goto done;
    }
  }
  NACL_TEST_INJECTION(BeforeMainThreadLaunches, ());
  if (!NaClCreateMainThread(nap,
                            argc - optind,
                            argv + optind,
                            NaClEnvCleanserEnvironment(&env_cleanser))) {
    fprintf(stderr, "creating main thread failed\n");
    goto done;
  }

  NaClEnvCleanserDtor(&env_cleanser);

  NaClPerfCounterMark(&time_all_main, "CreateMainThread");
  NaClPerfCounterIntervalLast(&time_all_main);
  DynArrayDtor(&env_vars);

  ret_code = NaClWaitForMainThreadToExit(nap);
  NaClPerfCounterMark(&time_all_main, "WaitForMainThread");
  NaClPerfCounterIntervalLast(&time_all_main);

  NaClPerfCounterMark(&time_all_main, "SelMainEnd");
  NaClPerfCounterIntervalTotal(&time_all_main);

  /*
   * exit_group or equiv kills any still running threads while module
   * addr space is still valid.  otherwise we'd have to kill threads
   * before we clean up the address space.
   */
  NaClExit(ret_code);

 done:
  fflush(stdout);

  if (verbosity) {
    gprintf((struct Gio *) &gout, "exiting -- printing NaClApp details\n");
    NaClAppPrintDetails(nap, (struct Gio *) &gout);

    printf("Dumping vmmap.\n"); fflush(stdout);
    PrintVmmap(nap);
    fflush(stdout);
  }
  /*
   * If there is a secure command channel, we sent an RPC reply with
   * the reason that the nexe was rejected.  If we exit now, that
   * reply may still be in-flight and the various channel closure (esp
   * reverse channel) may be detected first.  This would result in a
   * crash being reported, rather than the error in the RPC reply.
   * Instead, we wait for the hard-shutdown on the command channel.
   */
  if (LOAD_OK != errcode) {
    NaClBlockIfCommandChannelExists(nap);
  }

  if (verbosity > 0) {
    printf("Done.\n");
  }
  fflush(stdout);

  if (handle_signals) NaClSignalHandlerFini();
  NaClAllModulesFini();

  NaClExit(ret_code);

  /* Unreachable, but having the return prevents a compiler error. */
  return ret_code;
}
Ejemplo n.º 6
0
int
main( int argc, char ** const argv )
{
#ifndef WIN32
	/* Add the signals we want unblocked into sigSet */
	sigset_t sigSet;
	struct sigaction act;

	sigemptyset( &sigSet );
	sigaddset(&sigSet,SIGTERM);
	sigaddset(&sigSet,SIGQUIT);
	sigaddset(&sigSet,SIGPIPE);

	/* Set signal handlers */
	sigemptyset(&act.sa_mask);  /* do not block anything in handler */
	act.sa_flags = 0;

	/* Signals which should cause us to exit with status = signum */
	act.sa_handler = quit_on_signal;
	sigaction(SIGTERM,&act,0);
	sigaction(SIGQUIT,&act,0);
	sigaction(SIGPIPE,&act,0);

	/* Unblock signals in our set */
	sigprocmask( SIG_UNBLOCK, &sigSet, NULL );
#endif

	set_mySubSystem("AMAZON_GAHP", SUBSYSTEM_TYPE_GAHP);

	int min_workers = MIN_NUMBER_WORKERS;
	int max_workers = -1;
	const char * dprintfName = "EC2_GAHP";

	int c = 0;
	while ( (c = my_getopt(argc, argv, "l:f:d:w:m:" )) != -1 ) {
		switch(c) {
			case 'l':
				if( my_optarg && *my_optarg ) {
					dprintfName = my_optarg;
				}
				break;
			case 'f':
				break;
			case 'd':
				// Debug Level
				if( my_optarg && *my_optarg ) {
					set_debug_flags(my_optarg, 0);
				}
				break;
			case 'w':
				// Minimum number of worker pools
				min_workers = atoi(my_optarg);
				if( min_workers < MIN_NUMBER_WORKERS ) {
					min_workers = MIN_NUMBER_WORKERS;
				}
				break;
			case 'm':
				// Maximum number of worker pools
				max_workers = atoi(my_optarg);
				if( max_workers <= 0 ) {
					max_workers = -1;
				}
				break;
			default:
				usage();
		}
	}

    config();
    dprintf_config( dprintfName );
    const char * debug_string = getenv( "DebugLevel" );
    if( debug_string && * debug_string ) {
        set_debug_flags( debug_string, 0 );
    }

	dprintf(D_FULLDEBUG, "Welcome to the EC2 GAHP\n");

	const char *buff;

	//Try to read env for amazon_http_proxy
	buff = getenv(AMAZON_HTTP_PROXY);
	if( buff && *buff ) {
		set_amazon_proxy_server(buff);
		dprintf(D_ALWAYS, "Using http proxy = %s\n", buff);
	}

	// Register all amazon commands
	if( registerAllAmazonCommands() == false ) {
		dprintf(D_ALWAYS, "Can't register Amazon Commands\n");
		exit(1);
	}

	// Create IOProcess class
	ioprocess = new IOProcess;
	ASSERT(ioprocess);

	if( ioprocess->startUp(REQUEST_INBOX, min_workers, max_workers) == false ) {
		dprintf(D_ALWAYS, "Failed to start IO Process\n");
		delete ioprocess;
		exit(1);
	}

	// Print out the GAHP version to the screen
	// now we're ready to roll
	printf ("%s\n", version);
	fflush(stdout);

	dprintf( D_ALWAYS, "EC2 GAHP initialized\n" );

		/* Our main thread should grab the mutex first.  We will then
		 * release it and let other threads run when we would otherwise
		 * block.
		 */
	amazon_gahp_grab_big_mutex();

	for(;;) {
		ioprocess->stdinPipeHandler();
	}

	return 0;
}
Ejemplo n.º 7
0
/**
 * new connecion comes, copy file descroptor of new connecton to child
 * process , parent process select
 * @return  0
 */
int main(int argc, char **argv)
{

    int res;
    res = register_sig_handler();
    if (res < 0)
        err_sys("register_sig_handler is err");

    my_getopt(argc, argv);

    int pipefd[2];

    int socket_fd;
    res = srv_socket_init(&socket_fd, 50, PORT);
    if (res < 0)
        err_sys("srv_socket_init err");

    fd_set myset;
    FD_ZERO(&myset);
    FD_SET(socket_fd, &myset);
    int max = socket_fd;

    arraychild = (child_t *) malloc(sizeof(child_t) * childnum);
    memset(arraychild, 0, sizeof(child_t) * childnum);
    for (int i = 0 ; i < childnum; i++)
    {

        res = socketpair(AF_LOCAL, SOCK_STREAM, 0, pipefd);
        if (res < 0)
            err_sys("socketpair is err");
        arraychild[i].child_pipefd = pipefd[0];
        FD_SET(pipefd[0], &myset);
        if (pipefd[0] > max)
            max = pipefd[0];

        int pid = fork();
        if (pid < 0)
            err_sys("fork err");

        if (pid == 0)
        {
            srv_socket_destory(&socket_fd);

            int connfd;
            int childpid = getpid();
            while(1)
            {

                char c;
                res = read_fd(pipefd[1], &c, 1, &connfd);
                if (res < 0)
                    err_sys("read_fd err");
                fprintf(stdout, "pid is %d, accept success.\n",childpid);
                child_process(connfd);

                write(pipefd[1], "", 1);

                srv_socket_close(&connfd);
            }
            //exit(0);
        }
        else
        {
            arraychild[i].child_pid = pid;
        }
    }

    struct sigaction myact;
    myact.sa_handler = sig_int_handler;
    if (sigaction(SIGINT, &myact, NULL) < 0)
        err_sys("sigaction err");

    int navail = childnum;
    fd_set rset ;
    int newfd;
    int i = 0;
    while(1)
    {
        rset = myset;
        if (navail <=0 )
            FD_CLR(socket_fd, &rset);


        select(max + 1, &rset, NULL, NULL, NULL);
        if (FD_ISSET(socket_fd, &rset))
        {
            newfd = accept(socket_fd, NULL, NULL);

            for (i = 0; i < childnum; i++)
            {
                if (arraychild[i].child_status == 0)
                    break;
            }

            res = write_fd(arraychild[i].child_pipefd, "", 1, newfd);
            if (res < 0)
            {
                continue;
            }
            srv_socket_close(&newfd);
            arraychild[i].child_status = 1;
            arraychild[i].child_count++;
            navail--;
        }
        for (int i = 0; i < childnum; i++)
        {
            char c;
            if (FD_ISSET(arraychild[i].child_pipefd, &rset))
            {
                read(arraychild[i].child_pipefd, &c, 1);
                arraychild[i].child_status = 0;
                navail++;
            }
        }
    }

    return 0;
}
Ejemplo n.º 8
0
int main (int argc, char *argv[])
{
  Aoptimizeroptions_t oopt;
  int num_queries = 1, num_rels = 3, num_preds = -1, 
    generate = 0, unparse = 0, header = 0;


 // command line options

  int c;
  extern int my_optind, my_opterr;
  extern char *my_optarg;
  while ((c = my_getopt (argc, argv, 
		      "aAbBcCdeEhHiIJlLmM:n:N:p:rRs:SuvVZ")) != EOF)
    switch (c)
      {
      case 'a': // access_plan
	Aglob_vars()->print_plan = 1;
	break;
      case 'A': // dont use the assembly algorithm
	oopt.dont_use_assembly = 1;
	break;
      case 'b': // dont do bushy_trees, do left deep only
	oopt.left_deep_only = 1;
	break;
      case 'B': // dont do bushy_trees, do right deep only
	oopt.right_deep_only = 1;
	break;
      case 'c': // cartesian_products
	oopt.delay_cartesian_products = 0;
	break;
      case 'C': // dont do mat-collapse
	oopt.do_mat_collapse = 0;
	break;
      case 'd': // dont_execute_queries 
	Aglob_vars()->dont_execute_queries = 1;
	break;
      case 'e': // turn off equivalence classes
	oopt.no_equivalences = 1;
	break;
      case 'E': // dont do exhaustive select positioning
	oopt.do_exhaustive_selects = 0;
	break;
      case 'h': // hash_join
	oopt.do_hash_join = 1;	
	break;
      case 'H': // print the header
	header = 1;
	break;
      case 'i': // index heuristic
	oopt.do_idx_heuristic = 1;
	break;
      case 'I': // dont do path indexes
	oopt.do_path_indexes = 0;
	break;
      case 'J': // dont do mat to join conversion
	oopt.do_mat_to_join = 0;
	break;
      case 'l': // dont split the unexpanded node lists
	oopt.dont_split_lists = 1;
	break;
      case 'L': // dont do select collapse
	oopt.do_select_collapse = 0;
	break;
      case 'm': // merge_join
	oopt.do_merge_join = 1;
	break;
      case 'M': // set the memory size (per operator)
	memory_per_operator = atoi (my_optarg);
	break;
      case 'n': // -n <num>  number of relations
	num_rels = atoi (my_optarg);
	break;
      case 'N': // -N <num>  number of queries 
	num_queries = atoi (my_optarg);
	break;
      case 'p': // -p <num>   number of predicates
	num_preds = atoi (my_optarg);
	break;
      case 'r': // randomize
	srand (generate_seed ());
	break;
      case 'R': // dont read query from file
	generate = 1;
	break;
//       case 's': // -seed <num>   set the seed of the random number generator
// 	srand (atoi (my_optarg));
// 	break;
      case 's': // run setup. 
	use_tcl = 1;
	break;
      case 'S': // secondary joins
	Aglob_vars()->no_secondary_joins = 0;
	break;
      case 'u': // unparse
	unparse = 1;
	break;
      case 'v': // verbose mode. (print stats).
	Aglob_vars()->print_stats = 1;
	break;
      case 'V': // dont use inverse links
	oopt.do_inverse_links = 0;
	break;
      case 'w': // do nothing
	oopt.all_operator_trees = 0;
	oopt.all_operator_trees = 0;
	break;
      case 'W': // do nothing
	oopt.all_operator_trees = 10;
	oopt.all_operator_trees = 0;
	break;
      case 'x': // do nothing
	oopt.all_operator_trees = 90;
	oopt.all_operator_trees = 20;
	break;
      case 'X': // do nothing
	oopt.all_operator_trees = 80;
	oopt.all_operator_trees = 30;
	break;
      case 'y': // do nothing
	oopt.all_operator_trees = 70;
	oopt.all_operator_trees = 5;
	break;
      case 'Y': // do nothing
	oopt.all_operator_trees = -1;
	oopt.all_operator_trees = 60;
	break;
      case 'Z': // dummy argument. ignored.
	break;
      default:
	std::cerr << "usage: " << argv[0] << " [options]" << std::endl
	  << "where options are" << std::endl
	     << " -a\t\tprint the access plan" << std::endl
	     << " -A\t\tdont use the assembly algorithm" << std::endl
	     << " -b\t\tdont do bushy trees, do left deep only" << std::endl
	     << " -B\t\tdont do bushy trees, do right deep only" << std::endl
	     << " -c\t\ttry cartesian products too" << std::endl
	     << " -C\t\tdont do mat collapse" << std::endl
	     << " -d\t\tdont execute queries" << std::endl
	     << " -e\t\tturn off equivalence classes" << std::endl
	     << " -E\t\tdont do exhaustive selects" << std::endl
	     << " -h\t\tuse hash join as a join algorithm too" << std::endl
	     << " -H\t\tprint the header" << std::endl
	     << " -i\t\timplement the index join heuristic" << std::endl
	     << " -I\t\tdont use path indexes" << std::endl
	     << " -l\t\tdont split the unexpanded nodes lists" << std::endl
	     << " -L\t\tdont do select collapse" << std::endl
	     << " -m\t\tuse merge join as a join algorithm too" << std::endl
	     << " -M\t\tset the memory size per operator (pages)" << std::endl
	     << " -n <num>\tnumber of relations to join." << std::endl
	     << " -N <num>\tnumber of queries to run" << std::endl
	     << " -p <num>\tnumber of predicates in where clause" << std::endl
	     << " -r\t\trandomize the random number generator" << std::endl
	     << " -R\t\tread query from file \".query\"" << std::endl
	     << " -s <num>\tset seed for random number generator" << std::endl
	     << " -S\t\tgenerate secondary join predicates too" << std::endl
	     << " -u\t\tunparse and print the generated query" << std::endl
	     << " -v\t\tverbose mode. print statistics and stuff." << std::endl
	     << " -V\t\tdont use inverse links." << std::endl
	     << " -Z\t\tdummy argument. this is ignored." << std::endl;
	exit (1);
	break;
      }

  // setting up the stuff

  Acat_t catalog;
  Asearch_t search;
  Ahashtable_t hashtable (1021);
  Bparser_state_t parser_state;

  Aglob_vars()->cat = &catalog;
  Aglob_vars()->search = &search;
  Aglob_vars()->oopt = &oopt;
  if (getenv ("allops")) Aglob_vars()->oopt->all_operator_trees = 1;

  Aglob_vars()->hashtable = &hashtable;
  Aglob_vars()->parser_state = &parser_state;

  // set up the catalogs
  std::ifstream catfile (".catalog");
  if (!catfile.is_open()) {
    std::cout << "Error opening catalog";
    exit(1);
  }
  //assert (!!catfile);
  catalog.read (catfile);

  
  // do queries.

  if (num_preds < 0) num_preds = num_rels - 1; 
				// useful default
  if (header)
    std::cout
//      << setw (10) << "Startup" 
//      << setw (10) << "Setup" 
      << setw (7) << "SL_tot"
      << setw (7) << "SL_max"
      << setw (7) << "SP_tot"
      << setw (7) << "SP_max"
      << setw (7) << "TotLog"
      << setw (7) << "MaxLog"
      << setw (7) << "TotPhy"
      << setw (7) << "MaxPhy"
      << " "
      << setw (10) << "Cost"
      << " "
      << setw (10) << "OptTime" << std::endl;

//  if (use_tcl)
//    setup_tcl ();

  if (generate)
    for (int i=0; i<num_queries; i++)
      generate_and_execute (num_rels, num_preds, unparse);
  else
    queries_from_parser ();

  return 0;
}