Exemplo n.º 1
0
Arquivo: cqp.c Projeto: rforge/rcwb
/**
 * Initialises the CQP program (or cqpserver or cqpcl).
 *
 * This function:
 * - initialises the global variables;
 * - initialises the built-in random number generator;
 * - initialises the macro database;
 * - parses the program options;
 * - reads the initialisation file;
 * - reads the macro initialisation file;
 * - and loads the default corpus, if any.
 *
 * @param argc  The argc from main()
 * @param argv  The argv from main()
 * @return      Always 1.
 */
int
initialize_cqp(int argc, char **argv)
{
  char *home = NULL;
  char *homedrive = NULL;
  char *homepath = NULL;
  char init_file_fullname[CL_MAX_FILENAME_LENGTH];

  /* file handle for initialisation files, if any */
  FILE *cqprc;

  extern int yydebug;

  /* initialize global variables */

  exit_cqp = 0;
  cqp_file_p = 0;

  corpuslist = NULL;

  eep = -1;

  /* intialise built-in random number generator */
  cl_randomize();

  /* initialise macro database */
  init_macros();

  /* parse program options */
  parse_options(argc, argv);

  /* let's always run stdout unbuffered */
  /*  if (batchmode || rangeoutput || insecure || !isatty(fileno(stdout))) */
  if (setvbuf(stdout, NULL, _IONBF, 0) != 0)
    perror("unbuffer stdout");

  yydebug = parser_debug;

  /* before we start looking for files, let's get the home directory, if we can,
   * so we don't have to detect it in more than one place. */
#ifndef __MINGW__
  home = (char *)getenv("HOME");
#else
  /* under Windows it is %HOMEDRIVE%%HOMEPATH% */
  if ((homepath = (char *)getenv("HOMEPATH")) != NULL && (homedrive = (char *)getenv("HOMEDRIVE")) != NULL )  {
    home = (char *)cl_malloc(256);
    sprintf(home, "%s%s", homedrive, homepath);
  }
#endif
  /* note that either way above, home is NULL if the needed env var(s) were not found. */


  /* read initialization file if specified via -I, or if we are in interactive mode */
  if (cqp_init_file ||
      (!child_process && (!batchmode || batchfd == NULL) && which_app != cqpserver)
      ) {

    /*
     * Read init file specified with -I <file>
     *   if no init file was specified, and we're not in batchmode, child mode, or cqpserver,
     *   looks for ~/.cqprc
     * Same with macro init file (-M <file> or ~/.cqpmacros), but ONLY if macros are enabled.
     */

    /*
     * allow interactive commands during processing of initialization file ???
     * (I don't think this is the case!!)
     */

    init_file_fullname[0] = '\0';

    /* read init file specified with -I , otherwise look for $HOME/.cqprc */
    if (cqp_init_file)
      sprintf(init_file_fullname, "%s", cqp_init_file);
    else if (home)
      sprintf(init_file_fullname, "%s%c%s", home, SUBDIR_SEPARATOR, CQPRC_NAME);

    if (init_file_fullname[0] != '\0') {
      if ((cqprc = fopen(init_file_fullname, "r")) != NULL) {

        reading_cqprc = 1;        /* not good for very much, really */
        if (!cqp_parse_file(cqprc, 1)) {
          fprintf(stderr, "Parse errors while reading %s, exiting.\n",
                  init_file_fullname);
          exit(1);
        }
        reading_cqprc = 0;

        /* fclose(cqprc);  was already closed by cqp_parse_file!! */
      }
      else if (cqp_init_file) {
        fprintf(stderr, "Can't read initialization file %s\n",
                init_file_fullname);
        exit(1);
      }
    }
  }

  if (!enable_macros && macro_init_file)
    cqpmessage(Warning, "Macros not enabled. Ignoring macro init file %s.", macro_init_file);

  if (enable_macros &&
      (macro_init_file ||
       (!child_process && (!batchmode || (batchfd == NULL)) && !(which_app == cqpserver))
       )
      ) {

    init_file_fullname[0] = '\0';

    /* read macro init file specified with -M , otherwise look for ~/.cqpmacros */
    if (macro_init_file)
      sprintf(init_file_fullname, "%s", macro_init_file);
    else if (home)
      sprintf(init_file_fullname, "%s%c%s", home, SUBDIR_SEPARATOR, CQPMACRORC_NAME);

    if (init_file_fullname[0] != '\0') {
      if ((cqprc = fopen(init_file_fullname, "r")) != NULL) {

        reading_cqprc = 1;        /* not good for very much, really */
        if (!cqp_parse_file(cqprc, 1)) {
          fprintf(stderr, "Parse errors while reading %s, exiting.\n",
                  init_file_fullname);
          exit(1);
        }
        reading_cqprc = 0;

        /* fclose(cqprc);  was already closed by cqp_parse_file!! */
      }
      else if (macro_init_file) {
        fprintf(stderr, "Can't read macro initialization file %s\n",
                init_file_fullname);
        exit(1);
      }
    }
  } /* ends if (!child_process || (batchmode ... ) ... ) */

  check_available_corpora(UNDEF);

  /* load the default corpus. */
  if ((default_corpus) && !set_current_corpus_name(default_corpus, 0)) {
    fprintf(stderr, "Can't set current corpus to default corpus %s, exiting.\n",
            default_corpus);
    exit(1);
  }

#ifndef __MINGW__
  if (signal(SIGPIPE, SIG_IGN) == SIG_IGN) {
    /* fprintf(stderr, "Couldn't install SIG_IGN for SIGPIPE signal\n"); */
    /* -- be silent about not being able to ignore the SIGPIPE signal, which often happens in slave mode */
    /* note that SIGPIPE does not seem to exist in signal.h under MinGW */
    signal(SIGPIPE, SIG_DFL);
  }
#endif

#ifdef __MINGW__
  /* due to how the home path was calculated, home contains a malloc'ed string */
  cl_free(home);
#endif

  return 1;
}
Exemplo n.º 2
0
/**
 * Main function for the cqpserver app.
 */
int
main(int argc, char *argv[])
{
  int cmd;

  which_app = cqpserver;

  /* TODO: shouldn't these come AFTER initialize_cqp(), as that function may overwrite these values with defaults?
   * or maybe I've missed some subtlety here....*/
  silent = 1; 
  paging = autoshow = auto_save = 0;

  if (!initialize_cqp(argc, argv)) {
   Rprintf( "CQPserver: ERROR Couldn't initialise CQP engine.\n");
    rcqp_receive_error(1);
  }
  cqiserver_welcome();

  if (localhost) {
    add_host_to_list("127.0.0.1"); /* in -L mode, connections from localhost are automatically accepted  */
  }

  if (0 < accept_connection(server_port)) {
    if (server_log)
     Rprintf("CQPserver: Connected. Waiting for CONNECT request.\n");
  }
  else {
   Rprintf( "CQPserver: ERROR Connection failed.\n");
    rcqp_receive_error(1);
  }

  /* establish CQi connection: wait for CONNECT request */
  cmd = cqi_read_command();
  if (cmd != CQI_CTRL_CONNECT) {
    if (server_log)
     Rprintf("CQPserver: Connection refused.\n");
    cqiserver_wrong_command_error(cmd);
  }
  user = cqi_read_string();
  passwd = cqi_read_string();
  if (server_log)
   Rprintf("CQPserver: CONNECT  user = '******'  passwd = '%s'  pid = %d\n", user, passwd, (int)getpid());

  /* check password here (always required !!) */
  if (!authenticate_user(user, passwd)) {
   Rprintf("CQPserver: Wrong username or password. Connection refused.\n"); /* TODO shouldn't this be to stderr as it is not conditional on server_log? */
    cqi_command(CQI_ERROR_CONNECT_REFUSED);
  }
  else {
    cqi_command(CQI_STATUS_CONNECT_OK);

    /* re-randomize for query lock key generation */
    cl_randomize();

    /* check which corpora the user is granted access to */
    {
      CorpusList *cl = FirstCorpusFromList();
      while (cl != NULL) {
        if (!check_grant(user, cl->name))
          dropcorpus(cl);
        cl = NextCorpusFromList(cl);
      }
    }

    /* start command interpreter loop */
    interpreter();

    if (server_log)
     Rprintf("CQPserver: User '%s' has logged off.\n", user);
  }

  /* connection terminated; clean up and exit */
 Rprintf("CQPserver: Exit. (pid = %d)\n", (int)getpid());

  /* TODO should we check cqp_error_status as in the main cqp app? */
  return 0;
}