예제 #1
0
파일: glue.c 프로젝트: hharte/c3270
int
parse_command_line(int argc, const char **argv, const char **cl_hostname)
{
	int cl, i;
	int hn_argc;
	int sl;
	int xcmd_len = 0;
	char *xcmd;
	int xargc;
	const char **xargv;
	Boolean read_session_or_profile = False;

	/* Figure out who we are */
#if defined(_WIN32) /*[*/
	programname = strrchr(argv[0], '\\');
#else /*][*/
	programname = strrchr(argv[0], '/');
#endif /*]*/
	if (programname)
		++programname;
	else
		programname = argv[0];

	/* Save the command string for tracing purposes. */
	cl = strlen(programname);
	for (i = 0; i < argc; i++) {
		cl += 1 + strlen(argv[i]);
	}
	cl++;
	command_string = Malloc(cl);
	(void) strcpy(command_string, programname);
	for (i = 0; i < argc; i++) {
		(void) strcat(strcat(command_string, " "), argv[i]);
	}

	/*
	 * Save the command-line options so they can be reapplied after
	 * the session file or profile has been read in.
	 */
	xcmd_len = 0;
	for (i = 0; i < argc; i++)
		xcmd_len += strlen(argv[i]) + 1;
	xcmd = Malloc(xcmd_len + 1);
	xargv = (const char **)Malloc((argc + 1) * sizeof(char *));
	xcmd_len = 0;
	for (i = 0; i < argc; i++) {
		xargv[i] = xcmd + xcmd_len;
		(void) strcpy(xcmd + xcmd_len, argv[i]);
		xcmd_len += strlen(argv[i]) + 1;
	}
	xargv[i] = CN;
	*(xcmd + xcmd_len) = '\0';
	xargc = argc;

#if defined(LOCAL_PROCESS) /*[*/ 
        /* Pick out the -e option. */
        parse_local_process(&argc, argv, cl_hostname);
#endif /*]*/    

	/* Set the defaults. */
	set_appres_defaults();

	/* Parse command-line options. */
	parse_options(&argc, argv);

	/* Pick out the remaining -set and -clear toggle options. */
	parse_set_clear(&argc, argv);

	/* Now figure out if there's a hostname. */
	for (hn_argc = 1; hn_argc < argc; hn_argc++) {
		if (!strcmp(argv[hn_argc], LAST_ARG))
			break;
	}

	/* Verify command-line syntax. */
	switch (hn_argc) {
	    case 1:
		break;
	    case 2:
		no_minus(argv[1]);
		*cl_hostname = argv[1];
		break;
	    case 3:
		no_minus(argv[1]);
		no_minus(argv[2]);
		*cl_hostname = xs_buffer("%s:%s", argv[1], argv[2]);
		break;
	    default:
		usage("Too many command-line arguments");
		break;
	}

	/* Delete the host name and any "--". */
	if (argv[hn_argc] != CN && !strcmp(argv[hn_argc], LAST_ARG))
		hn_argc++;
	if (hn_argc > 1) {
		for (i = 1; i < argc - hn_argc + 2; i++) {
			argv[i] = argv[i + hn_argc - 1];
		}
	}

	/* Merge in the session. */
	if (*cl_hostname != CN &&
	    (((sl = strlen(*cl_hostname)) > SESSION_SFX_LEN &&
	      !strcasecmp(*cl_hostname + sl - SESSION_SFX_LEN, SESSION_SFX))
#if defined(_WIN32) /*[*/
	     || ((sl = strlen(*cl_hostname)) > SESSION_SSFX_LEN &&
	      !strcasecmp(*cl_hostname + sl - SESSION_SSFX_LEN, SESSION_SSFX))
#endif /*]*/
	     )) {

		const char *pname;

		if (read_resource_file(*cl_hostname, True) < 0)
		    	x3270_exit(1);

		read_session_or_profile = True;

		pname = strrchr(*cl_hostname, '\\');
		if (pname != CN)
		    	pname++;
		else
		    	pname = *cl_hostname;
		profile_name = NewString(pname);
		Replace(profile_path, NewString(profile_name));

		sl = strlen(profile_name);
		if (sl > SESSION_SFX_LEN &&
			!strcasecmp(profile_name + sl - SESSION_SFX_LEN,
				SESSION_SFX)) {
			profile_name[sl - SESSION_SFX_LEN] = '\0';
#if defined(_WIN32) /*[*/
		} else if (sl > SESSION_SSFX_LEN &&
			!strcasecmp(profile_name + sl - SESSION_SSFX_LEN,
				SESSION_SSFX)) {
			profile_name[sl - SESSION_SSFX_LEN] = '\0';
#endif /*]*/
		}

		*cl_hostname = appres.hostname; /* might be NULL */
	} else {
	    	/* There is no session file. */

#if defined(C3270) && !defined(_WIN32) /*[*/
		/*
		 * For c3270 only, read in the c3270 profile (~/.c3270pro).
		 */
	    	read_session_or_profile = merge_profile();
#endif /*]*/
		/*
		 * If there was a hostname resource defined somewhere, but not
		 * as a positional command-line argument, pretend it was one,
		 * so we will connect to it at start-up.
		 */
		if (*cl_hostname == CN && appres.hostname != CN)
		    	*cl_hostname = appres.hostname;
	}

	/*
	 * Now parse the command-line arguments again, so they take
	 * precedence over the session file or profile.
	 */
	if (read_session_or_profile) {
		parse_options(&xargc, xargv);
		parse_set_clear(&xargc, xargv);
	}
	/* Can't free xcmd, parts of it are still in use. */
	Free((char *)xargv);

	/*
	 * All right, we have all of the resources defined.
	 * Sort out the contradictory and implicit settings.
	 */

	if (appres.apl_mode)
		appres.charset = Apl;
	if (*cl_hostname == CN)
		appres.once = False;
	if (appres.conf_dir == CN)
		appres.conf_dir = LIBX3270DIR;

#if defined(X3270_TRACE) /*[*/
	if (!appres.debug_tracing) {
		 appres.toggle[TRACING].value = False;
	}
#endif /*]*/

	return argc;
}
예제 #2
0
파일: glue.c 프로젝트: Oxyoptia/x3270
/* Parse the command line and read in any session file. */
int
parse_command_line(int argc, const char **argv, const char **cl_hostname)
{
    size_t cl;
    int i;
    int hn_argc;
    size_t sl;
    size_t xcmd_len = 0;
    char *xcmd;
    int xargc;
    const char **xargv;
    bool read_session_or_profile = false;

    /* Figure out who we are */
#if defined(_WIN32) /*[*/
    programname = strrchr(argv[0], '\\');
#else /*][*/
    programname = strrchr(argv[0], '/');
#endif /*]*/
    if (programname) {
	++programname;
    } else {
	programname = argv[0];
    }

    /* Save the command string for tracing purposes. */
    cl = strlen(programname);
    for (i = 0; i < argc; i++) {
	cl += 1 + strlen(argv[i]);
    }
    cl++;
    command_string = Malloc(cl);
    (void) strcpy(command_string, programname);
    for (i = 0; i < argc; i++) {
	(void) strcat(strcat(command_string, " "), argv[i]);
    }

    /*
     * Save the command-line options so they can be reapplied after
     * the session file or profile has been read in.
     */
    xcmd_len = 0;
    for (i = 0; i < argc; i++) {
	xcmd_len += strlen(argv[i]) + 1;
    }
    xcmd = Malloc(xcmd_len + 1);
    xargv = (const char **)Malloc((argc + 1) * sizeof(char *));
    xcmd_len = 0;
    for (i = 0; i < argc; i++) {
	xargv[i] = xcmd + xcmd_len;
	(void) strcpy(xcmd + xcmd_len, argv[i]);
	xcmd_len += strlen(argv[i]) + 1;
    }
    xargv[i] = NULL;
    *(xcmd + xcmd_len) = '\0';
    xargc = argc;

#if defined(LOCAL_PROCESS) /*[*/ 
    /* Pick out the -e option. */
    parse_local_process(&argc, argv, cl_hostname);
#endif /*]*/    

    /* Set the defaults. */
    set_appres_defaults();

    /* Parse command-line options. */
    parse_options(&argc, argv);

    /* Pick out the remaining -set and -clear toggle options. */
    parse_set_clear(&argc, argv);

    /* Now figure out if there's a hostname. */
    for (hn_argc = 1; hn_argc < argc; hn_argc++) {
	if (!strcmp(argv[hn_argc], LAST_ARG)) {
	    break;
	}
    }

    /* Verify command-line syntax. */
    switch (hn_argc) {
    case 1:
	break;
    case 2:
	no_minus(argv[1]);
	*cl_hostname = argv[1];
	break;
    case 3:
	no_minus(argv[1]);
	no_minus(argv[2]);
	*cl_hostname = xs_buffer("%s:%s", argv[1], argv[2]);
	break;
    default:
	usage("Too many command-line arguments");
	break;
    }

    /* Delete the host name and any "--". */
    if (argv[hn_argc] != NULL && !strcmp(argv[hn_argc], LAST_ARG)) {
	hn_argc++;
    }
    if (hn_argc > 1) {
	for (i = 1; i < argc - hn_argc + 2; i++) {
	    argv[i] = argv[i + hn_argc - 1];
	}
    }

    /* Merge in the session. */
    if (session_suffix == NULL) {
	session_suffix = xs_buffer(".%s", app);
	session_suffix_len = strlen(session_suffix);
    }
#if defined(_WIN32) /*[*/
    if (session_short_suffix == NULL) {
	session_short_suffix = xs_buffer(".%.3s", app);
	session_short_suffix_len = strlen(session_short_suffix);
    }
#endif /*]*/
    if (*cl_hostname != NULL &&
	(((sl = strlen(*cl_hostname)) > session_suffix_len &&
	  !strcasecmp(*cl_hostname + sl - session_suffix_len, session_suffix))
#if defined(_WIN32) /*[*/
	 || ((sl = strlen(*cl_hostname)) > session_short_suffix_len &&
	  !strcasecmp(*cl_hostname + sl - session_short_suffix_len,
	      session_short_suffix))
#endif /*]*/
	 )) {

	const char *pname;

	if (!read_resource_file(*cl_hostname, true)) {
	    x3270_exit(1);
	}

	read_session_or_profile = true;

	pname = strrchr(*cl_hostname, '\\');
	if (pname != NULL) {
	    pname++;
	} else {
	    pname = *cl_hostname;
	}
	profile_name = NewString(pname);
	Replace(profile_path, NewString(profile_name));

	sl = strlen(profile_name);
	if (sl > session_suffix_len &&
		!strcasecmp(profile_name + sl - session_suffix_len,
		    session_suffix)) {
	    profile_name[sl - session_suffix_len] = '\0';
#if defined(_WIN32) /*[*/
	} else if (sl > session_short_suffix_len &&
		!strcasecmp(profile_name + sl - session_short_suffix_len,
			session_short_suffix)) {
	    profile_name[sl - session_short_suffix_len] = '\0';
#endif /*]*/
	}

	*cl_hostname = appres.hostname; /* might be NULL */
    } else {
	/* There is no session file. */

	/* For c3270 only, read in the c3270 profile (~/.c3270pro). */
	if (merge_profilep != NULL) {
	    read_session_or_profile = (*merge_profilep)();
	}

	/*
	 * If there was a hostname resource defined somewhere, but not
	 * as a positional command-line argument, pretend it was one,
	 * so we will connect to it at start-up.
	 */
	if (*cl_hostname == NULL && appres.hostname != NULL) {
	    *cl_hostname = appres.hostname;
	}
    }

    /*
     * Now parse the command-line arguments again, so they take
     * precedence over the session file or profile.
     */
    if (read_session_or_profile) {
	parse_options(&xargc, xargv);
	parse_set_clear(&xargc, xargv);
    }
    /* Can't free xcmd, parts of it are still in use. */
    Free((char *)xargv);

    /*
     * All right, we have all of the resources defined.
     * Sort out the contradictory and implicit settings.
     */

    if (appres.apl_mode) {
	appres.charset = Apl;
    }
    if (*cl_hostname == NULL) {
	appres.once = false;
    }
    if (!appres.debug_tracing) {
	/* debug_tracing was explicitly cleared */
	 set_toggle(TRACING, false);
    }
#if defined(_WIN32) /*[*/
    if (appres.utf8) {
	/* utf8 overrides local_cp */
	appres.local_cp = CP_UTF8;
    }
#endif /*]*/

    return argc;
}