コード例 #1
0
ファイル: cmd.c プロジェクト: jblaine/openafs
static int
HelpProc(struct cmd_syndesc *as, void *arock)
{
    struct cmd_syndesc *ts;
    struct cmd_item *ti;
    int ambig;
    int code = 0;

    if (as->parms[0].items == 0) {
	printf("%sCommands are:\n", NName(as->a0name, ": "));
	for (ts = allSyntax; ts; ts = ts->next) {
	    if ((ts->flags & CMD_ALIAS) || (ts->flags & CMD_HIDDEN))
		continue;
	    printf("%-15s %s\n", ts->name, (ts->help ? ts->help : ""));
	}
    } else {
	/* print out individual help topics */
	for (ti = as->parms[0].items; ti; ti = ti->next) {
	    code = 0;
	    ts = FindSyntax(ti->data, &ambig);
	    if (ts && (ts->flags & CMD_HIDDEN))
		ts = 0;		/* no hidden commands */
	    if (ts) {
		/* print out command name and help */
		printf("%s%s: %s ", NName(as->a0name, " "), ts->name,
		       (ts->help ? ts->help : ""));
		ts->a0name = as->a0name;
		PrintAliases(ts);
		PrintSyntax(ts);
		PrintFlagHelp(ts);
	    } else {
		if (!ambig)
		    fprintf(stderr, "%sUnknown topic '%s'\n",
			    NName(as->a0name, ": "), ti->data);
		else {
		    /* ambiguous, list 'em all */
		    fprintf(stderr,
			    "%sAmbiguous topic '%s'; use 'apropos' to list\n",
			    NName(as->a0name, ": "), ti->data);
		}
		code = CMD_UNKNOWNCMD;
	    }
	}
    }
    return (code);
}
コード例 #2
0
int main(int argc, char *argv[])
{
    int done = FALSE;
    opterr = 0;

    //fprintf(stderr, "ctrack started.");
    c_control = C_RUN;

    srand((int)time(NULL));

	ErrorInit();    
    ConfigInit(); // initializes verbose; must be called before any output

   	ReadConfig(TRUE); // default loc.
    TorrentDBCreate();

    unsigned int p;
    while (!done) {
        switch (getopt(argc, argv, "+vqVhrdt:u:p:c:"))  { // + means "don't shuffle args"
            case '?': // invalid option
                PrintSyntax(1);
            case 'h': // help option
                PrintSyntax(0);
            case 'V':
            	printf("ctrack " VERSION "\n");
            	return 0;
                break;
            case 'v':
                SetConfigBool(CFG_VERBOSE, TRUE);
                log("Verbose mode");
                break;
            case 'q':
                SetConfigBool(CFG_VERBOSE, FALSE);
                log("Quiet mode");
                break;
            case 't':
                if (b_assign(atoi(optarg),1,65535,(int *)&p))
                    SetConfigUInt(CFG_HTTP_PORT, p);
                break;
            case 'u':
                if (b_assign(atoi(optarg),1,65535,(int *)&p))
                    SetConfigUInt(CFG_UDP_PORT, p);
                break;
            case 'p':
                if (b_assign(atoi(optarg),1,65535,(int *)&p))
                    SetConfigUInt(CFG_SERVER_PORT, p);
                break;
            case 'd':
                SetConfigBool(CFG_DAEMON, TRUE);
                break;
            case 'c': //config file
	            SetConfigString(CFG_CONFIG_FILE, optarg);
                ReadConfig(FALSE);
            	break;
            case -1:  //end of options
                done = TRUE;
                break;
            default:
                PrintSyntax(1);
                break;    
        }//switch
    }//while
    int i;
    for (i = optind; i < argc; i++) {
    	PTorrentInfo t;
    	char ibuffer[20];
    	if (strtohash(argv[i], ibuffer)) {
			NewTorrentInfo(&t, ibuffer);
		} else {
			errorm("Invalid hash: %s", argv[i]);
		}
    }//for

    //TODO:parse args
    //TODO:init torrent db

#ifdef DAEMON_SUPPORT
    if (GetConfigBool(CFG_DAEMON) == TRUE) {
    /* Our process ID and Session ID */
    pid_t pid, sid;

    /* Fork off the parent process */
    pid = fork();
    if (pid < 0) { exit(EXIT_FAILURE); }
    /* If we got a good PID, then we can exit the parent process. */
    if (pid > 0) { exit(EXIT_SUCCESS); }
    /* Change the file mode mask */
    umask(0);
        /* Create a new SID for the child process */
    sid = setsid();
    if (sid < 0) {
		errorm("setsid() failed: %s", str_error());
		exit(EXIT_FAILURE);
    }
    /* Change the current working directory */
    if ((chdir("/")) < 0) {
		errorm("chdir() failed: %s", str_error());
        exit(EXIT_FAILURE);
    }
    /* Close out the standard file descriptors */
    close(STDIN_FILENO);
    close(STDOUT_FILENO);
    close(STDERR_FILENO);

	if (daemon(TRUE, FALSE) != 0) 
        errorf(E_SYSTEM, "daemon() failed: %S", str_error());
    } else {
		extern int asdaemon;
		asdaemon = TRUE;
    }
#endif

    //SetupSignalHandlers
	sigset_t set;
	int sig;

    while (c_control == C_RUN) {
    	sigfillset(&set);
    	pthread_sigmask(SIG_SETMASK, &set, NULL);

        if (GetConfigBool(CFG_HTTP_SERVER)) { // HTTP server
	        if (SetUpListener())
    	        HTTPThreadInit();
	    }

	    if (GetConfigBool(CFG_UDP_SERVER)) { // UDP server
	        UDPThreadInit();
	    }

		//TODO: sigwait
		while (c_control == C_RUN) {
		    sigwait(&set, &sig);
			logf("Caught signal #%d", sig);
			switch (sig) {
				case SIGINT:
	                c_control = C_TERMINATE;
    	            log("Exitting...");
        	        break;
				case SIGHUP:
	                c_control = C_RESTART;
	                log("Restarting...");
                   	ReadConfig(FALSE);
	                break;
				case SIGSEGV:
	                c_control = C_TERMINATE;
    	            log("Exitting...");
			}//switch
		}//while
        ThreadsDestroy();
    	CloseTCPSocket();
    	CloseUDPSocket();

        if (c_control == C_RESTART) { c_control = C_RUN; }
    }//while

  	log("exit ");
    return ((sig==SIGINT) ? EXIT_SUCCESS : EXIT_FAILURE);
}
コード例 #3
0
ファイル: cmd.c プロジェクト: jblaine/openafs
/* Call the appropriate function, or return syntax error code.  Note: if
 * no opcode is specified, an initialization routine exists, and it has
 * NOT been called before, we invoke the special initialization opcode
 */
int
cmd_Parse(int argc, char **argv, struct cmd_syndesc **outsyntax)
{
    char *pname;
    struct cmd_syndesc *ts = NULL;
    struct cmd_parmdesc *tparm;
    int i;
    int curType;
    int positional;
    int ambig;
    int code = 0;
    char *param = NULL;
    char *embeddedvalue = NULL;
    static int initd = 0;	/*Is this the first time this routine has been called? */
    static int initcmdpossible = 1;	/*Should be consider parsing the initial command? */

    *outsyntax = NULL;

    if (!initd) {
	initd = 1;
	initSyntax();
    }

    /*Remember the program name */
    pname = argv[0];

    if (noOpcodes) {
	if (argc == 1) {
	    if (!NoParmsOK(allSyntax)) {
		printf("%s: Type '%s -help' for help\n", pname, pname);
		code = CMD_USAGE;
		goto out;
	    }
	}
    } else {
	if (argc < 2) {
	    /* if there is an initcmd, don't print an error message, just
	     * setup to use the initcmd below. */
	    if (!(initcmdpossible && FindSyntax(initcmd_opcode, NULL))) {
		printf("%s: Type '%s help' or '%s help <topic>' for help\n",
		       pname, pname, pname);
		code = CMD_USAGE;
		goto out;
	    }
	}
    }

    /* Find the syntax descriptor for this command, doing prefix matching properly */
    if (noOpcodes) {
	ts = allSyntax;
    } else {
	ts = (argc < 2 ? 0 : FindSyntax(argv[1], &ambig));
	if (!ts) {
	    /*First token doesn't match a syntax descriptor */
	    if (initcmdpossible) {
		/*If initial command line handling hasn't been done yet,
		 * see if there is a descriptor for the initialization opcode.
		 * Only try this once. */
		initcmdpossible = 0;
		ts = FindSyntax(initcmd_opcode, NULL);
		if (!ts) {
		    /*There is no initialization opcode available, so we declare
		     * an error */
		    if (ambig) {
			fprintf(stderr, "%s", NName(pname, ": "));
			fprintf(stderr,
				"Ambiguous operation '%s'; type '%shelp' for list\n",
				argv[1], NName(pname, " "));
		    } else {
			fprintf(stderr, "%s", NName(pname, ": "));
			fprintf(stderr,
				"Unrecognized operation '%s'; type '%shelp' for list\n",
				argv[1], NName(pname, " "));
		    }
		    code = CMD_UNKNOWNCMD;
		    goto out;
		} else {
		    /*Found syntax structure for an initialization opcode.  Fix
		     * up argv and argc to relect what the user
		     * ``should have'' typed */
		    if (!(argv = InsertInitOpcode(&argc, argv))) {
			fprintf(stderr,
				"%sCan't insert implicit init opcode into command line\n",
				NName(pname, ": "));
			code = CMD_INTERNALERROR;
			goto out;
		    }
		}
	    } /*Initial opcode not yet attempted */
	    else {
		/* init cmd already run and no syntax entry found */
		if (ambig) {
		    fprintf(stderr, "%s", NName(pname, ": "));
		    fprintf(stderr,
			    "Ambiguous operation '%s'; type '%shelp' for list\n",
			    argv[1], NName(pname, " "));
		} else {
		    fprintf(stderr, "%s", NName(pname, ": "));
		    fprintf(stderr,
			    "Unrecognized operation '%s'; type '%shelp' for list\n",
			    argv[1], NName(pname, " "));
		}
		code = CMD_UNKNOWNCMD;
		goto out;
	    }
	}			/*Argv[1] is not a valid opcode */
    }				/*Opcodes are defined */

    /* Found the descriptor; start parsing.  curType is the type we're
     * trying to parse */
    curType = 0;

    /* We start off parsing in "positional" mode, where tokens are put in
     * slots positionally.  If we find a name that takes args, we go
     * out of positional mode, and from that point on, expect a switch
     * before any particular token. */

    positional = enablePositional;	/* Accepting positional cmds ? */
    i = noOpcodes ? 1 : 2;
    SetupExpandsFlag(ts);
    for (; i < argc; i++) {
	if (param) {
	    free(param);
	    param = NULL;
	    embeddedvalue = NULL;
	}

	/* Only tokens that start with a hyphen and are not followed by a digit
	 * are considered switches.  This allow negative numbers. */

	if ((argv[i][0] == '-') && !isdigit(argv[i][1])) {
	    int j;

	    /* Find switch */
	    if (strrchr(argv[i], '=') != NULL) {
		param = strdup(argv[i]);
		embeddedvalue = strrchr(param, '=');
		*embeddedvalue = '\0';
		embeddedvalue ++;
	        j = FindType(ts, param);
	    } else {
	        j = FindType(ts, argv[i]);
	    }

	    if (j < 0) {
		fprintf(stderr,
			"%sUnrecognized or ambiguous switch '%s'; type ",
			NName(pname, ": "), argv[i]);
		if (noOpcodes)
		    fprintf(stderr, "'%s -help' for detailed help\n",
			    argv[0]);
		else
		    fprintf(stderr, "'%shelp %s' for detailed help\n",
			    NName(argv[0], " "), ts->name);
		code = CMD_UNKNOWNSWITCH;
		goto out;
	    }
	    if (j >= CMD_MAXPARMS) {
		fprintf(stderr, "%sInternal parsing error\n",
			NName(pname, ": "));
		code = CMD_INTERNALERROR;
		goto out;
	    }
	    if (ts->parms[j].type == CMD_FLAG) {
		ts->parms[j].items = &dummy;

		if (embeddedvalue) {
		    fprintf(stderr, "%sSwitch '%s' doesn't take an argument\n",
			    NName(pname, ": "), ts->parms[j].name);
		    code = CMD_TOOMANY;
		    goto out;
		}
	    } else {
		positional = 0;
		curType = j;
		ts->parms[j].flags |= CMD_PROCESSED;

		if (embeddedvalue) {
		    AddItem(&ts->parms[curType], embeddedvalue, pname);
		}
	    }
	} else {
	    /* Try to fit in this descr */
	    if (curType >= CMD_MAXPARMS) {
		fprintf(stderr, "%sToo many arguments\n", NName(pname, ": "));
		code = CMD_TOOMANY;
		goto out;
	    }
	    tparm = &ts->parms[curType];

	    if ((tparm->type == 0) ||	/* No option in this slot */
		(tparm->type == CMD_FLAG)) {	/* A flag (not an argument */
		/* skipped parm slot */
		curType++;	/* Skip this slot and reprocess this parm */
		i--;
		continue;
	    }

	    if (!(tparm->flags & CMD_PROCESSED) && (tparm->flags & CMD_HIDE)) {
		curType++;	/* Skip this slot and reprocess this parm */
		i--;
		continue;
	    }

	    if (tparm->type == CMD_SINGLE ||
	        tparm->type == CMD_SINGLE_OR_FLAG) {
		if (tparm->items) {
		    fprintf(stderr, "%sToo many values after switch %s\n",
		            NName(pname, ": "), tparm->name);
		    code = CMD_NOTLIST;
		    goto out;
		}
		AddItem(tparm, argv[i], pname);        /* Add to end of list */
	    } else if (tparm->type == CMD_LIST) {
		AddItem(tparm, argv[i], pname);        /* Add to end of list */
	    }

	    /* Now, if we're in positional mode, advance to the next item */
	    if (positional)
		curType = AdvanceType(ts, curType);
	}
    }

    /* keep track of this for messages */
    ts->a0name = argv[0];

    /* If we make it here, all the parameters are filled in.  Check to see if
     * this is a -help version.  Must do this before checking for all
     * required parms, otherwise it is a real nuisance */
    if (ts->parms[CMD_HELPPARM].items) {
	PrintSyntax(ts);
	/* Display full help syntax if we don't have subcommands */
	if (noOpcodes)
	    PrintFlagHelp(ts);
	code = CMD_HELP;
	goto out;
    }

    /* Parsing done, see if we have all of our required parameters */
    for (i = 0; i < CMD_MAXPARMS; i++) {
	tparm = &ts->parms[i];
	if (tparm->type == 0)
	    continue;		/* Skipped parm slot */
	if ((tparm->flags & CMD_PROCESSED) && tparm->items == 0) {
	    if (tparm->type == CMD_SINGLE_OR_FLAG) {
		tparm->items = &dummy;
	    } else {
	        fprintf(stderr, "%s The field '%s' isn't completed properly\n",
		    NName(pname, ": "), tparm->name);
	        code = CMD_TOOFEW;
	        goto out;
	    }
	}
	if (!(tparm->flags & CMD_OPTIONAL) && tparm->items == 0) {
	    fprintf(stderr, "%sMissing required parameter '%s'\n",
		    NName(pname, ": "), tparm->name);
	    code = CMD_TOOFEW;
	    goto out;
	}
	tparm->flags &= ~CMD_PROCESSED;
    }
    *outsyntax = ts;

out:
    if (code && ts != NULL)
	ResetSyntax(ts);

    return code;
}
コード例 #4
0
ファイル: lztest.c プロジェクト: mingpen/OpenNT
VOID
__cdecl
main(
    IN ULONG argc,
    IN PCHAR argv[]
    )

{
    ULONG FileSpecIndex;
    CHAR DirectorySpec[256];
    PCHAR FileSpec;

    ULONG StartTick;
    ULONG StopTick;

    //
    //  Check for the statistics switch
    //

    if ((argc > 1) && (!strcmp(argv[1],"/s") || !strcmp(argv[1],"/S"))) {

        Statistics = TRUE;
        argc--;
        argv++;
    }

    //
    //  Check for the verbose switch
    //

    if ((argc > 1) && (!strcmp(argv[1],"/v") || !strcmp(argv[1],"/V"))) {

        Verbose = TRUE;
        argc--;
        argv++;
    }

    //
    //  Check for the compress or decompress switch.
    //

    if ((argc > 1) && (!strcmp(argv[1],"/c") || !strcmp(argv[1],"/C"))) {

        if (!strcmp(argv[1],"/c")) { WriteOutputFile = FALSE; } else { WriteOutputFile = TRUE;  }

        //
        //  Check for the minimum number of arguments for compression
        //

        if (argc < 4) { PrintSyntax(); }

        if (!strcmp(argv[2],"/LZOPT")) {

            ActionRoutine     = CompressFile;
            CompressRoutine   = CompressLZOPT;
            StatisticsRoutine = StatisticsLZOPT;
            ResetStatistics   = ResetStatisticsLZOPT;
            strcpy( FileExtension, ".CLZOPT");

        } else if (!strcmp(argv[2],"/LZNT1")) {

            ActionRoutine     = CompressFile;
            CompressRoutine   = CompressLZNT1;
            StatisticsRoutine = StatisticsLZNT1;
            ResetStatistics   = ResetStatisticsLZNT1;
            strcpy( FileExtension, ".CLZNT1");

        } else if (!strcmp(argv[2],"/LZDC1")) {

            ActionRoutine     = CompressFile;
            CompressRoutine   = CompressLZDC;
            StatisticsRoutine = StatisticsLZDC1;
            ResetStatistics   = ResetStatisticsLZDC1;
            strcpy( FileExtension, ".CLZDC1");

            MatchFunction     = LZDC1FindMatch;

        } else if (!strcmp(argv[2],"/LZDC2")) {

            ActionRoutine     = CompressFile;
            CompressRoutine   = CompressLZDC;
            StatisticsRoutine = StatisticsLZDC2;
            ResetStatistics   = ResetStatisticsLZDC2;
            strcpy( FileExtension, ".CLZDC2");

            MatchFunction     = LZDC2FindMatch;

        } else if (!strcmp(argv[2],"/LZRW1")) {

            ActionRoutine     = CompressFile;
            CompressRoutine   = CompressLZRW;
            StatisticsRoutine = StatisticsLZRW1;
            ResetStatistics   = ResetStatisticsLZRW1;
            strcpy( FileExtension, ".CLZRW1");

            MatchFunction     = LZRW1FindMatch;

        } else if (!strcmp(argv[2],"/LZRW2")) {

            ActionRoutine     = CompressFile;
            CompressRoutine   = CompressLZRW;
            StatisticsRoutine = StatisticsLZRW2;
            ResetStatistics   = ResetStatisticsLZRW2;
            strcpy( FileExtension, ".CLZRW2");

            MatchFunction     = LZRW2FindMatch;

        } else if (!strcmp(argv[2],"/DBLS")) {

            ActionRoutine     = CompressFile;
            CompressRoutine   = CompressMRCF;
            StatisticsRoutine = StatisticsMRCF;
            ResetStatistics   = ResetStatisticsMRCF;
            strcpy( FileExtension, ".CDBLS");

            MatchFunction     = MrcfFindMatchStandard;

            UncompressedBufferSize = 512;

        } else if (!strcmp(argv[2],"/DBLSOPT")) {

            ActionRoutine     = CompressFile;
            CompressRoutine   = CompressMRCF;
            StatisticsRoutine = StatisticsMRCF;
            ResetStatistics   = ResetStatisticsMRCF;
            strcpy( FileExtension, ".CDBLSOPT");

            MatchFunction     = MrcfFindOptimalMatch;

            UncompressedBufferSize = 512;

        } else if (!strcmp(argv[2],"/MRCF")) {

            ActionRoutine     = CompressFile;
            CompressRoutine   = CompressMRCF;
            StatisticsRoutine = StatisticsMRCF;
            ResetStatistics   = ResetStatisticsMRCF;
            strcpy( FileExtension, ".CMRCF");

            MatchFunction     = MrcfFindMatchStandard;

        } else if (!strcmp(argv[2],"/MRCFOPT")) {

            ActionRoutine     = CompressFile;
            CompressRoutine   = CompressMRCF;
            StatisticsRoutine = StatisticsMRCFOPT;
            ResetStatistics   = ResetStatisticsMRCFOPT;
            strcpy( FileExtension, ".CMRCFOPT");

            MatchFunction     = MrcfFindOptimalMatch;

        } else if (!strcmp(argv[2],"/JMS")) {

            ActionRoutine     = CompressFile;
            CompressRoutine   = CompressJMS;
            StatisticsRoutine = StatisticsJMS;
            ResetStatistics   = ResetStatisticsJMS;
            strcpy( FileExtension, ".CJMS");

            MatchFunction     = JMSFindMatch;

        } else if (!strcmp(argv[2],"/JMSOPT")) {

            ActionRoutine     = CompressFile;
            CompressRoutine   = CompressJMS;
            StatisticsRoutine = StatisticsJMSOPT;
            ResetStatistics   = ResetStatisticsJMSOPT;
            strcpy( FileExtension, ".CJMSOPT");

            MatchFunction     = JMSOPTFindMatch;

        } else if (!strcmp(argv[2],"/LZ115")) {

            ActionRoutine     = CompressFile;
            CompressRoutine   = CompressLZ115;
            StatisticsRoutine = StatisticsLZ115;
            ResetStatistics   = ResetStatisticsLZ115;
            strcpy( FileExtension, ".CLZ115");

            MatchFunction     = LZ115FindMatch;

        } else if (!strcmp(argv[2],"/LZ115OPT")) {

            ActionRoutine     = CompressFile;
            CompressRoutine   = CompressLZ115;
            StatisticsRoutine = StatisticsLZ115OPT;
            ResetStatistics   = ResetStatisticsLZ115OPT;
            strcpy( FileExtension, ".CLZ115OPT");

            MatchFunction     = LZ115OPTFindMatch;

        } else if (!strcmp(argv[2],"/LZ11HALF")) {

            ActionRoutine     = CompressFile;
            CompressRoutine   = CompressLZ11HALF;
            StatisticsRoutine = StatisticsLZ11HALF;
            ResetStatistics   = ResetStatisticsLZ11HALF;
            strcpy( FileExtension, ".CLZ11HALF");

            MatchFunction     = LZ11HALFFindMatch;

        } else if (!strcmp(argv[2],"/LZ11HALFOPT")) {

            ActionRoutine     = CompressFile;
            CompressRoutine   = CompressLZ11HALF;
            StatisticsRoutine = StatisticsLZ11HALFOPT;
            ResetStatistics   = ResetStatisticsLZ11HALFOPT;
            strcpy( FileExtension, ".CLZ11HALFOPT");

            MatchFunction     = LZ11HALFOPTFindMatch;

        } else if (!strcmp(argv[2],"/LZKM1")) {

            ActionRoutine     = CompressFile;
            CompressRoutine   = CompressLZKM;
            StatisticsRoutine = StatisticsLZKM1;
            ResetStatistics   = ResetStatisticsLZKM1;
            strcpy( FileExtension, ".CLZKM1");

            MatchFunction     = LZKM1FindMatch;

        } else if (!strcmp(argv[2],"/LZKM2")) {

            ActionRoutine     = CompressFile;
            CompressRoutine   = CompressLZKM;
            StatisticsRoutine = StatisticsLZKM2;
            ResetStatistics   = ResetStatisticsLZKM2;
            strcpy( FileExtension, ".CLZKM2");

            MatchFunction     = LZKM2FindMatch;

        } else if (!strcmp(argv[2],"/LZKMOPT")) {

            ActionRoutine     = CompressFile;
            CompressRoutine   = CompressLZKM;
            StatisticsRoutine = StatisticsLZKMOPT;
            ResetStatistics   = ResetStatisticsLZKMOPT;
            strcpy( FileExtension, ".CLZKMOPT");

            MatchFunction     = LZKMOPTFindMatch;

        } else if (!strcmp(argv[2],"/LZKM1512")) {

            ActionRoutine     = CompressFile;
            CompressRoutine   = CompressLZKM;
            StatisticsRoutine = StatisticsLZKM1;
            ResetStatistics   = ResetStatisticsLZKM1;
            strcpy( FileExtension, ".CLZKM1512");

            MatchFunction     = LZKM1FindMatch;

            UncompressedBufferSize = 512;

        } else if (!strcmp(argv[2],"/LZKM2512")) {

            ActionRoutine     = CompressFile;
            CompressRoutine   = CompressLZKM;
            StatisticsRoutine = StatisticsLZKM2;
            ResetStatistics   = ResetStatisticsLZKM2;
            strcpy( FileExtension, ".CLZKM2512");

            MatchFunction     = LZKM2FindMatch;

            UncompressedBufferSize = 512;

        } else if (!strcmp(argv[2],"/LZKMOPT512")) {

            ActionRoutine     = CompressFile;
            CompressRoutine   = CompressLZKM;
            StatisticsRoutine = StatisticsLZKMOPT;
            ResetStatistics   = ResetStatisticsLZKMOPT;
            strcpy( FileExtension, ".CLZKMOPT512");

            MatchFunction     = LZKMOPTFindMatch;

            UncompressedBufferSize = 512;

        } else { PrintSyntax(); };

        //sscanf( argv[3], strncmp( argv[3], "0x", 2 ) ? "%ld" : "%lx", &UncompressedBufferSize );

        FileSpecIndex = 3;

    } else if ((argc > 1) && (!strcmp(argv[1],"/d") || !strcmp(argv[1],"/D"))) {

        if (!strcmp(argv[1],"/d")) { WriteOutputFile = FALSE; } else { WriteOutputFile = TRUE;  }

        //
        //  Check for the minimum number of arguments for decompression
        //

        if (argc < 4) { PrintSyntax(); }

        if (!strcmp(argv[2],"/12.4")) {

            ActionRoutine     = DecompressFile;
            DecompressRoutine = DecompressLZRW;
            StatisticsRoutine = StatisticsLZRW1;
            ResetStatistics   = ResetStatisticsLZRW1;
            strcpy( FileExtension, ".D12.4");

        } else if (!strcmp(argv[2],"/11.5")) {

            ActionRoutine     = DecompressFile;
            DecompressRoutine = DecompressLZ115;
            StatisticsRoutine = StatisticsLZ115;
            ResetStatistics   = ResetStatisticsLZ115;
            strcpy( FileExtension, ".D11.5");

        } else if (!strcmp(argv[2],"/11HALF")) {

            ActionRoutine     = DecompressFile;
            DecompressRoutine = DecompressLZ11HALF;
            StatisticsRoutine = StatisticsLZ11HALF;
            ResetStatistics   = ResetStatisticsLZ11HALF;
            strcpy( FileExtension, ".D11HALF");

        } else if (!strcmp(argv[2],"/LZKM")) {

            ActionRoutine     = DecompressFile;
            DecompressRoutine = DecompressLZKM;
            StatisticsRoutine = StatisticsLZKM1;
            ResetStatistics   = ResetStatisticsLZKM1;
            strcpy( FileExtension, ".DLZKM");

        } else if (!strcmp(argv[2],"/MRCF")) {

            ActionRoutine     = DecompressFile;
            DecompressRoutine = DecompressMRCF;
            StatisticsRoutine = StatisticsMRCF;
            strcpy( FileExtension, ".DMRCF");

        } else if (!strcmp(argv[2],"/JMS")) {

            ActionRoutine     = DecompressFile;
            DecompressRoutine = DecompressJMS;
            StatisticsRoutine = StatisticsJMS;
            strcpy( FileExtension, ".DJMS");

        } else { PrintSyntax(); };

        FileSpecIndex = 3;

    } else {

        PrintSyntax();
    }

    if (Statistics) { ResetStatistics(); }

    //
    //  Now do the action routine for each file spec
    //

    StartTick = GetTickCount();

    for (FileSpecIndex; FileSpecIndex < argc; FileSpecIndex += 1) {

        (VOID)GetFullPathName( argv[FileSpecIndex], 256, DirectorySpec, &FileSpec );

        DoAction( DirectorySpec, FileSpec );
    }

    StopTick = GetTickCount();

    //
    //  Now print the final statistics
    //

    if (Statistics) { StatisticsRoutine(); }

    {
        LONGLONG Percent = 100;
        ULONG TotalTicks;

        if (TotalUncompressedSize != 0) {

            Percent = TotalCompressedSize * 100 / TotalUncompressedSize;
        }

        TotalTicks = StopTick - StartTick;

        printf("\n");
        printf("Total File Count        = %8ld\n", (ULONG)TotalFileCount);
        printf("      Compressed Size   = %8ld\n", (ULONG)TotalCompressedSize);
        printf("      Uncompressed Size = %8ld\n", (ULONG)TotalUncompressedSize);
        printf("                        = %8ld%%\n", (ULONG)Percent);
        printf("                        = %8ld ms\n", TotalTicks);
    }

    return;
}