Esempio n. 1
0
/*! \brief Annotates symbols in an Init with their key.
 *
 * \param symbol_table
 *  the symbol table.
 * \param scope
 *  the scope under which the Init is defined.
 * \param init
 *  the Init.
 */
static void
annotate_init (SymbolTable symbol_table, Key scope, Init init)
{
  if (init)
    {
      if (P_GetInitExpr (init))
	annotate_expr (symbol_table, scope, P_GetInitExpr (init));
      else
	annotate_init (symbol_table, scope, P_GetInitSet (init));

      annotate_init (symbol_table, scope, P_GetInitNext (init));
    }

  return;
}
Esempio n. 2
0
int main(int argc, char **argv)
{
    int opt;
    char *alt_config = NULL;
    int r = IMAP_NOTFOUND;
    strarray_t mboxnames = STRARRAY_INITIALIZER;
    const char *query = NULL;
    int background = 1;
    const char *channel = "squatter";
    const char *synclogfile = NULL;
    int init_flags = CYRUSINIT_PERROR;
    int multi_folder = 0;
    int user_mode = 0;
    int compact_flags = 0;
    const char *fromfile = NULL;
    strarray_t *srctiers = NULL;
    const char *desttier = NULL;
    enum { UNKNOWN, INDEXER, INDEXFROM, SEARCH, ROLLING, SYNCLOG,
           START_DAEMON, STOP_DAEMON, RUN_DAEMON, COMPACT } mode = UNKNOWN;

    if ((geteuid()) == 0 && (become_cyrus(/*is_master*/0) != 0)) {
        fatal("must run as the Cyrus user", EC_USAGE);
    }

    setbuf(stdout, NULL);

    while ((opt = getopt(argc, argv, "C:I:N:RAXT:S:Fc:de:f:mn:rsiavz:t:ou")) != EOF) {
        switch (opt) {
        case 'C':               /* alt config file */
            alt_config = optarg;
            break;

        case 'A':
            compact_flags |= SEARCH_COMPACT_AUDIT;
            break;

        case 'F':
            compact_flags |= SEARCH_COMPACT_FILTER;
            break;

        case 'X':
            compact_flags |= SEARCH_COMPACT_REINDEX;
            break;

        case 'N':
            name_starts_from = optarg;
            break;

        case 'I':               /* indexer, using specified mbox/uids in file */
            if (mode != UNKNOWN && mode != INDEXFROM) usage(argv[0]);
            fromfile = optarg;
            mode = INDEXFROM;
            break;

        case 'R':               /* rolling indexer */
            if (mode != UNKNOWN) usage(argv[0]);
            mode = ROLLING;
            incremental_mode = 1; /* always incremental if rolling */
            break;

        case 'S':               /* sleep time in seconds */
            sleepmicroseconds = (atof(optarg) * 1000000);
            break;

        case 'T':               /* temporary root directory for search */
            temp_root_dir = optarg;
            break;

        /* This option is deliberately undocumented, for testing only */
        case 'c':               /* daemon control mode */
            if (mode != UNKNOWN) usage(argv[0]);
            if (!strcmp(optarg, "start"))
                mode = START_DAEMON;
            else if (!strcmp(optarg, "stop"))
                mode = STOP_DAEMON;
            else if (!strcmp(optarg, "run"))
                mode = RUN_DAEMON;
            else
                usage(argv[0]);
            break;

        case 'd':               /* foreground (with -R) */
            background = 0;
            break;

        /* This option is deliberately undocumented, for testing only */
        case 'e':               /* add a search term */
            if (mode != UNKNOWN && mode != SEARCH) usage(argv[0]);
            query = optarg;
            mode = SEARCH;
            break;

        case 'f': /* alternate synclogfile used in SYNCLOG mode */
            synclogfile = optarg;
            mode = SYNCLOG;
            break;

        /* This option is deliberately undocumented, for testing only */
        case 'm':               /* multi-folder in SEARCH mode */
            if (mode != UNKNOWN && mode != SEARCH) usage(argv[0]);
            multi_folder = 1;
            mode = SEARCH;
            break;

        case 'n':               /* sync channel name (with -R) */
            channel = optarg;
            break;

        case 'o':               /* copy one DB rather than compressing */
            compact_flags |= SEARCH_COMPACT_COPYONE;
            break;

        case 'v':               /* verbose */
            verbose++;
            break;

        case 'r':               /* recurse */
            if (mode != UNKNOWN && mode != INDEXER) usage(argv[0]);
            recursive_flag = 1;
            mode = INDEXER;
            break;

        case 'i':               /* incremental mode */
            incremental_mode = 1;
            break;

        case 'a':               /* use /squat annotation */
            if (mode != UNKNOWN && mode != INDEXER) usage(argv[0]);
            annotation_flag = 1;
            mode = INDEXER;
            break;

        case 'z':
            if (mode != UNKNOWN && mode != COMPACT) usage(argv[0]);
            desttier = optarg;
            mode = COMPACT;
            break;

        case 't':
            if (mode != UNKNOWN && mode != COMPACT) usage(argv[0]);
            srctiers = strarray_split(optarg, ",", 0);
            mode = COMPACT;
            break;

        case 'u':
            user_mode = 1;
            break;

        default:
            usage("squatter");
        }
    }

    compact_flags |= SEARCH_VERBOSE(verbose);

    if (mode == UNKNOWN)
        mode = INDEXER;

    /* fork and close fds if required */
    if (mode == ROLLING && background) {
        become_daemon();
        init_flags &= ~CYRUSINIT_PERROR;
    }

    if (mode == COMPACT && (!desttier || !srctiers)) {
        /* need both src and dest for compact */
        usage("squatter");
    }

    cyrus_init(alt_config, "squatter", init_flags, CONFIG_NEED_PARTITION_DATA);

    /* Set namespace -- force standard (internal) */
    if ((r = mboxname_init_namespace(&squat_namespace, 1)) != 0) {
        fatal(error_message(r), EC_CONFIG);
    }

    annotate_init(NULL, NULL);
    annotatemore_open();

    mboxlist_init(0);
    mboxlist_open(NULL);

    if (mode == ROLLING || mode == SYNCLOG) {
        signals_set_shutdown(&shut_down);
        signals_add_handlers(0);
    }

    switch (mode) {
    case UNKNOWN:
        break;
    case INDEXER:
        /* -r requires at least one mailbox */
        if (recursive_flag && optind == argc) usage(argv[0]);
        expand_mboxnames(&mboxnames, argc-optind, (const char **)argv+optind, user_mode);
        syslog(LOG_NOTICE, "indexing mailboxes");
        r = do_indexer(&mboxnames);
        syslog(LOG_NOTICE, "done indexing mailboxes");
        break;
    case INDEXFROM:
        syslog(LOG_NOTICE, "indexing messages");
        r = do_indexfrom(fromfile);
        syslog(LOG_NOTICE, "done indexing messages");
        break;
    case SEARCH:
        if (recursive_flag && optind == argc) usage(argv[0]);
        expand_mboxnames(&mboxnames, argc-optind, (const char **)argv+optind, user_mode);
        r = do_search(query, !multi_folder, &mboxnames);
        break;
    case ROLLING:
        do_rolling(channel);
        /* never returns */
        break;
    case SYNCLOG:
        r = do_synclogfile(synclogfile);
        break;
    case START_DAEMON:
        if (optind != argc) usage("squatter");
        search_start_daemon(verbose);
        break;
    case STOP_DAEMON:
        if (optind != argc) usage("squatter");
        search_stop_daemon(verbose);
        break;
    case RUN_DAEMON:
        if (optind != argc) usage("squatter");
        do_run_daemon();
        break;
    case COMPACT:
        if (recursive_flag && optind == argc) usage(argv[0]);
        expand_mboxnames(&mboxnames, argc-optind, (const char **)argv+optind, user_mode);
        r = do_compact(&mboxnames, srctiers, desttier, compact_flags);
        break;
    }

    strarray_fini(&mboxnames);
    shut_down(r ? EC_TEMPFAIL : 0);
}
Esempio n. 3
0
/*! \brief Annotates symbols in a Stmt with their key.
 *
 * \param symbol_table
 *  the symbol table.
 * \param scope
 *  the scope under which the Stmt is defined.
 * \param stmt
 *  the Stmt.
 */
static void
annotate_stmt (SymbolTable symbol_table, Key scope, Stmt stmt)
{
  while (stmt)
    {
      if (stmt == NULL)
	return;
  
      switch (P_GetStmtType (stmt))
	{
	case ST_NOOP:
	case ST_CONT:
	case ST_BREAK:
	case ST_ADVANCE:
	case ST_AWAIT:
	case ST_MUTEX:
	  break;
	  
	case ST_RETURN:
	  annotate_expr (symbol_table, scope, P_GetStmtRet (stmt));
	  break;

	case ST_GOTO:
	  if (!P_ValidKey (P_GetStmtLabelKey (stmt)))
	    P_SetStmtLabelKey (stmt, find_label (symbol_table, scope,
						 P_GetStmtLabelVal (stmt)));
	  break;
	  
	case ST_COMPOUND:
	  {
	    Compound c = P_GetStmtCompound (stmt);
	    VarList var_list = P_GetCompoundVarList (c);
	    VarDcl var_dcl;
	    
	    /* Annotate any variables used in initializers. */
	    for (List_start (var_list), var_dcl = (VarDcl)List_next (var_list);
		 var_dcl; var_dcl = (VarDcl)List_next (var_list))
	      {
		if (P_GetVarDclInit (var_dcl))
		  annotate_init (symbol_table, P_GetStmtKey (stmt),
				 P_GetVarDclInit (var_dcl));
	      }

	    annotate_stmt (symbol_table, P_GetStmtKey (stmt),
			   P_GetCompoundStmtList (c));
	  }
	  break;
	  
	case ST_IF:
	  {
	    IfStmt i = P_GetStmtIfStmt (stmt);
	    
	    annotate_expr (symbol_table, scope, P_GetIfStmtCondExpr (i));
	    annotate_stmt (symbol_table, scope, P_GetIfStmtThenBlock (i));
	    annotate_stmt (symbol_table, scope, P_GetIfStmtElseBlock (i));
	  }
	  break;
	  
	case ST_SWITCH:
	  {
	    SwitchStmt s = P_GetStmtSwitchStmt (stmt);
	    
	    annotate_expr (symbol_table, scope, P_GetSwitchStmtExpression (s));
	    annotate_stmt (symbol_table, scope, P_GetSwitchStmtSwitchBody (s));
	  }
	  break;
	  
	case ST_PSTMT:
	  {
	    Pstmt p = P_GetStmtPstmt (stmt);
	    
	    annotate_stmt (symbol_table, scope, P_GetPstmtStmt (p));
	  }
	  break;
	  
	case ST_COBEGIN:
	  {
	    Cobegin c = P_GetStmtCobegin (stmt);
	    
	    annotate_stmt (symbol_table, scope, P_GetCobeginStatements (c));
	  }
	  break;
	  
	case ST_PARLOOP:
	  {
	    ParLoop p = P_GetStmtParLoop (stmt);
	    
	    annotate_stmt (symbol_table, scope,
			   P_GetPstmtStmt (P_GetParLoopPstmt (p)));
	    annotate_expr (symbol_table, scope, P_GetParLoopIterationVar (p));
	    annotate_expr (symbol_table, scope, P_GetParLoopInitValue (p));
	    annotate_expr (symbol_table, scope, P_GetParLoopFinalValue (p));
	    annotate_expr (symbol_table, scope, P_GetParLoopIncrValue (p));
	    annotate_stmt (symbol_table, scope, P_GetParLoopChild (p));
	  }
	  break;
	  
	case ST_SERLOOP:
	  {
	    SerLoop s = P_GetStmtSerLoop (stmt);
	    
	    annotate_stmt (symbol_table, scope, P_GetSerLoopLoopBody (s));
	    annotate_expr (symbol_table, scope, P_GetSerLoopCondExpr (s));
	    annotate_expr (symbol_table, scope, P_GetSerLoopInitExpr (s));
	    annotate_expr (symbol_table, scope, P_GetSerLoopIterExpr (s));
	  }
	  break;
	  
	case ST_EXPR:
	  annotate_expr (symbol_table, scope, P_GetStmtExpr (stmt));
	  break;
	  
	case ST_BODY:
	  {
	    BodyStmt b = P_GetStmtBodyStmt (stmt);
	    
	    annotate_stmt (symbol_table, scope, P_GetBodyStmtStatement (b));
	  }
	  break;
	  
	case ST_EPILOGUE:
	  {
	    EpilogueStmt e = P_GetStmtEpilogueStmt (stmt);
	    
	    annotate_stmt (symbol_table, scope,
			   P_GetEpilogueStmtStatement (e));
	  }
	  break;

	case ST_ASM:
	  {
	    AsmStmt a = P_GetStmtAsmStmt (stmt);
	    
	    annotate_expr (symbol_table, scope, P_GetAsmStmtAsmClobbers (a));
	    annotate_expr (symbol_table, scope, P_GetAsmStmtAsmString (a));
	    annotate_expr (symbol_table, scope, P_GetAsmStmtAsmOperands (a));
	  }
	  break;
	}

      stmt = P_GetStmtLexNext (stmt);
    }

  return;
}