예제 #1
0
파일: trace.c 프로젝트: Oxyoptia/x3270
/* Return the default filename for screen tracing. */
char *
screentrace_default_file(ptype_t ptype)
{
	const char *suffix;

	switch (ptype) {
	default:
	case P_TEXT:
		suffix = "txt";
		break;
	case P_HTML:
		suffix = "html";
		break;
	case P_RTF:
		suffix = "rtf";
		break;
	}
#if defined(_WIN32) /*[*/
	return xs_buffer("%s%sx3scr.$UNIQUE.%s",
		appres.trace_dir? appres.trace_dir: default_trace_dir(),
		appres.trace_dir? "\\": "",
		suffix);
#else /*][*/
	return xs_buffer("%s/x3scr.$UNIQUE.%s", appres.trace_dir, suffix);
#endif /*]*/
}
예제 #2
0
파일: util.c 프로젝트: Oxyoptia/x3270
static char *
ex_getenv(const char *name, unsigned long flags, int *up)
{
    if (!strcasecmp(name, "TIMESTAMP")) {
	/* YYYYMMDDHHMMSSUUUUUU */
	struct timeval tv;
	time_t t; /* on Windows, timeval.tv_sec is a long */
	struct tm *tm;

	if (gettimeofday(&tv, NULL) < 0) {
	    return NewString("?");
	}
	t = tv.tv_sec;
	tm = localtime(&t);
	return xs_buffer("%04u%02u%02u%02u%02u%02u%06u",
		tm->tm_year + 1900,
		tm->tm_mon + 1,
		tm->tm_mday,
		tm->tm_hour,
		tm->tm_min,
		tm->tm_sec,
		(unsigned)tv.tv_usec);
    } else if (!strcasecmp(name, "UNIQUE")) {
	++*up;
	if (*up == 0) {
	    return xs_buffer("%u", (unsigned)getpid());
	} else {
	    return xs_buffer("%u-%u", (unsigned)getpid(), *up);
	}
    } else {
	return getenv(name);
    }
}
예제 #3
0
파일: glue.c 프로젝트: Oxyoptia/x3270
/*
 * Validate a resource that is fetched explicitly, rather than via appres.
 */
static int
valid_explicit(const char *resname, size_t len)
{
    xreslist_t *x;
    unsigned i;
    int j;

    for (x = xreslist; x != NULL; x = x->next) {
	for (i = 0; i < x->count; i++) {
	    size_t sl = strlen(x->xresources[i].name);

	    switch (x->xresources[i].type) {
	    case V_FLAT:
		/* Exact match. */
		if (len == sl &&
		    !strncmp(x->xresources[i].name, resname, sl)) {
		    return 0;
		}
		break;
	    case V_WILD:
		/* xxx.* match. */
		if (len > sl + 1 &&
		    resname[sl] == '.' &&
		    !strncmp(x->xresources[i].name, resname, sl)) {
		    return 0;
		}
		break;
	    case V_COLOR:
		/* xxx<host-color> or xxx<host-color-index> match. */
		for (j = 0; host_color[j].name != NULL; j++) {
		    char *xbuf;

		    xbuf = xs_buffer("%s%s", x->xresources[i].name,
			    host_color[j].name);
		    if (strlen(xbuf) == len &&
			!strncmp(xbuf, resname, len)) {
			    Free(xbuf);
			    return 0;
		    }
		    Free(xbuf);
		    xbuf = xs_buffer("%s%d", x->xresources[i].name,
			    host_color[j].index);
		    if (strlen(xbuf) == len &&
			!strncmp(xbuf, resname, len)) {
			    Free(xbuf);
			    return 0;
		    }
		    Free(xbuf);
		}
		break;
	    }
	}
    }

    return -1;
}
예제 #4
0
파일: trace_ds.c 프로젝트: hharte/c3270
/* Check for a trace file rollover event. */
void
trace_rollover_check(void)
{
	if (tracef == NULL || tracef_max == 0)
		return;

	/* See if we've reached a rollover point. */
	if (tracef_size >= tracef_max) {
	    	char *alt_filename;
		char *new_header;
#if defined(_WIN32) /*[*/
		char *period;
#endif /*]*/

		/* Close up this file. */
		wtrace("Trace rolled over\n");
		fclose(tracef);
		tracef = NULL;

		/* Unlink and rename the alternate file. */
#if defined(_WIN32) /*[*/
		period = strrchr(tracefile_name, '.');
		if (period != CN)
			alt_filename = xs_buffer("%.*s-%s",
				period - tracefile_name,
				tracefile_name,
				period);
		else
#endif /*]*/
			alt_filename = xs_buffer("%s-", tracefile_name);
		(void) unlink(alt_filename);
		(void) rename(tracefile_name, alt_filename);
		Free(alt_filename);
		alt_filename = CN;
		tracef = fopen(tracefile_name, "w");
		if (tracef == (FILE *)NULL) {
			popup_an_errno(errno, "%s", tracefile_name);
			return;
		}

		/* Initialize it. */
		tracef_size = 0L;
		(void) SETLINEBUF(tracef);
		new_header = create_tracefile_header("rolled over");
		do_ts = True;
		wtrace(new_header);
		Free(new_header);
	}
}
예제 #5
0
파일: glue.c 프로젝트: Oxyoptia/x3270
static void
no_minus(const char *arg)
{
    if (arg[0] == '-') {
	usage(xs_buffer("Unknown or incomplete option: %s", arg));
    }
}
예제 #6
0
파일: gdi_print.c 프로젝트: Oxyoptia/x3270
/*
 * Create a Roman font.
 * Returns 0 for success, -1 for failure.
 */
static int
create_roman_font(HDC dc, int fheight, int fwidth, const char **fail)
{
    char *w, *h;

    w = fwidth? xs_buffer("%d", fwidth): NewString("(auto)");
    h = fheight? xs_buffer("%d", fheight): NewString("(auto)");
    vtrace("[gdi] requesting a font %sx%s logical units\n", w, h);
    Free(w);
    Free(h);

    pstate.font = CreateFont(
	    fheight,		/* height */
	    fwidth,		/* width */
	    0,			/* escapement */
	    0,			/* orientation */
	    FW_NORMAL,		/* weight */
	    FALSE,		/* italic */
	    FALSE,		/* underline */
	    FALSE,		/* strikeout */
	    DEFAULT_CHARSET,	/* character set */
	    OUT_OUTLINE_PRECIS,	/* output precision */
	    CLIP_DEFAULT_PRECIS,/* clip precision */
	    DEFAULT_QUALITY,	/* quality */
	    FIXED_PITCH|FF_DONTCARE,/* pitch and family */
	    uparm.font_name);	/* face */
    if (pstate.font == NULL) {
	*fail = "CreateFont failed";
	return -1;
    }

    /* Measure a space to find out the size we got. */
    SelectObject(dc, pstate.font);
    if (!GetTextExtentPoint32(dc, " ", 1, &pstate.space_size)) {
	*fail = "GetTextExtentPoint32 failed";
	return -1;
    }
    vtrace("[gdi] space character is %dx%d logical units\n",
	    (int)pstate.space_size.cx, (int)pstate.space_size.cy);
    pstate.usable_cols = pstate.usable_xpixels / pstate.space_size.cx;
    pstate.usable_rows = pstate.usable_ypixels / pstate.space_size.cy;
    vtrace("[gdi] usable area is %dx%d characters\n",
	    pstate.usable_cols, pstate.usable_rows);
    return 0;
}
예제 #7
0
파일: ft.c 프로젝트: Oxyoptia/x3270
/* Pop up a message, end the transfer. */
void
ft_complete(const char *errmsg)
{
    /* Close the local file. */
    if (fts.local_file != NULL && fclose(fts.local_file) < 0) {
	popup_an_errno(errno, "close(%s)", ftc->local_filename);
    }
    fts.local_file = NULL;

    /* Clean up the state. */
    ft_state = FT_NONE;
    if (ft_start_id != NULL_IOID) {
	RemoveTimeOut(ft_start_id);
	ft_start_id = NULL_IOID;
    }

    /* Get the idle timeout going again. */
    idle_ft_complete();

    /* Pop down the in-progress shell. */
    ft_gui_progress_popdown();

    /* Pop up the text. */
    if (errmsg != NULL) {
	char *msg_copy = NewString(errmsg);

	/* Make sure the error message will fit on the pop-up. */
	ft_gui_errmsg_prepare(msg_copy);

	/* Clear out the progress display. */
	ft_gui_clear_progress();

	/* Pop up the error. */
	popup_an_error("%s", msg_copy);
	Free(msg_copy);
    } else {
	struct timeval t1;
	double bytes_sec;
	char *buf;

	(void) gettimeofday(&t1, NULL);
	bytes_sec = (double)fts.length /
		((double)(t1.tv_sec - t0.tv_sec) + 
		 (double)(t1.tv_usec - t0.tv_usec) / 1.0e6);
	buf = xs_buffer(get_message("ftComplete"), fts.length,
		display_scale(bytes_sec),
		fts.is_cut ? "CUT" : "DFT");
	ft_gui_clear_progress();
	ft_gui_complete_popup(buf);
	Free(buf);
    }

    /* I hope I can do this unconditionally. */
    sms_continue();
}
예제 #8
0
파일: trace.c 프로젝트: Oxyoptia/x3270
/* Open the trace file. */
static void
tracefile_on(int reason, enum toggle_type tt)
{
    char *tracefile_buf = NULL;
    char *tracefile;

    if (tracef != NULL) {
	return;
    }

    trace_reason = reason;
    if (appres.secure && tt != TT_INITIAL) {
	tracefile_ok("none");
	return;
    }
    if (onetime_tracefile_name != NULL) {
	tracefile = tracefile_buf = onetime_tracefile_name;
	onetime_tracefile_name = NULL;
    } else if (appres.trace_file) {
	tracefile = appres.trace_file;
    } else {
#if defined(_WIN32) /*[*/
	tracefile_buf = xs_buffer("%s%sx3trc.$UNIQUE.txt",
		appres.trace_dir? appres.trace_dir: default_trace_dir(),
		appres.trace_dir? "\\": "");
#else /*][*/
	tracefile_buf = xs_buffer("%s/x3trc.$UNIQUE", appres.trace_dir);
#endif /*]*/
	tracefile = tracefile_buf;
    }

    if (!trace_gui_on(reason, tt, tracefile)) {
	tracefile_ok(tracefile);
    } else {
	/* Turn the toggle _off_ until the popup succeeds. */
	set_toggle(reason, false);
    }

    if (tracefile_buf != NULL) {
	Free(tracefile_buf);
    }
}
예제 #9
0
파일: util.c 프로젝트: Oxyoptia/x3270
    /* Substitute and return. */
    if (p == NULL) {
	r = NewString(s);
    } else {
	r = Malloc(strlen(p->pw_dir) + strlen(rest) + 1);
	(void) strcpy(r, p->pw_dir);
	(void) strcat(r, rest);
    }
    return r;
}
#else /*][*/
static char *
tilde_subst(const char *s)
{
    char *t;

    if (*s != '~' || (t = getenv("HOMEPATH")) == NULL) {
	return NewString(s);
    }

    switch (*(s + 1)) {
    case '\0':
	return NewString(t);
    case '/':
    case '\\':
	return xs_buffer("%s%s", t, s + 1);
    default:
	return NewString(s);
    }
}
예제 #10
0
파일: trace.c 프로젝트: Oxyoptia/x3270
/*
 * Start up a window to monitor the trace file.
 *
 * @param[in] path	Trace file path. On Unix, this can be NULL to indicate
 * 			that the trace is just being piped.
 * @param[in] pipefd	Array of pipe file descriptors.
 */
static void
start_trace_window(const char *path, int pipefd[])
{
    switch (tracewindow_pid = fork_child()) {
    case 0:	/* child process */
	(void) execlp("xterm", "xterm", "-title", path? path: "trace",
		"-sb", "-e", "/bin/sh", "-c", xs_buffer("cat <&%d", pipefd[0]),
		NULL);
	(void) perror("exec(xterm) failed");
	_exit(1);
	break;
    default:	/* parent */
	(void) close(pipefd[0]);
	++children;
	break;
    case -1:	/* error */
	popup_an_errno(errno, "fork() failed");
	break;
    }
}
예제 #11
0
파일: glue.c 프로젝트: Oxyoptia/x3270
/* Disply command-line help. */
void
cmdline_help (bool as_action)
{
    unsigned i;
    
    sort_help();
    for (i = 0; i < sorted_help_count; i++) {
	char *h = sorted_help[i].help_opts;
	char *ht;
	char *hx = NULL;
	char *star;

	if (sorted_help[i].type == OPT_XRM &&
		h != NULL && (star = strchr(h, '*')) != NULL) {
	    ht = hx = xs_buffer("%.*s%s%s", (int)(star - h), h, app,
		    star + 1);
	} else {
	    ht = h;
	}

	if (as_action) {
	    action_output("  %s%s%s",
		    sorted_help[i].name,
		    ht? " ": "",
		    ht? ht: "");
	    action_output("    %s", sorted_help[i].help_text);
	} else {
	    fprintf(stderr, "  %s%s%s\n     %s\n",
		    sorted_help[i].name,
		    ht? " ": "",
		    ht? ht: "",
		    sorted_help[i].help_text);
	}
	if (hx != NULL) {
	    Free(hx);
	}
    }
}
예제 #12
0
파일: trace_ds.c 프로젝트: hharte/c3270
/* Open the trace file. */
static void
tracefile_on(int reason, enum toggle_type tt)
{
	char *tracefile_buf = NULL;
	char *tracefile;

	if (tracef != (FILE *)NULL)
		return;

	trace_reason = reason;
	if (appres.secure && tt != TT_INITIAL) {
		tracefile_callback((Widget)NULL, "none", PN);
		return;
	}
	if (onetime_tracefile_name != NULL) {
	    	tracefile = tracefile_buf = onetime_tracefile_name;
		onetime_tracefile_name = NULL;
	} else if (appres.trace_file)
		tracefile = appres.trace_file;
	else {
#if defined(_WIN32) /*[*/
		tracefile_buf = xs_buffer("%s%sx3trc.$UNIQUE.txt",
			appres.trace_dir? appres.trace_dir: DEFAULT_TRACE_DIR,
			appres.trace_dir? "\\": "");
#else /*][*/
		tracefile_buf = xs_buffer("%s/x3trc.$UNIQUE",
			appres.trace_dir);
#endif /*]*/
		tracefile = tracefile_buf;
	}

#if defined(X3270_DISPLAY) /*[*/
	if (tt == TT_INITIAL || tt == TT_ACTION)
#endif /*]*/
	{
		tracefile_callback((Widget)NULL, tracefile, PN);
		if (tracefile_buf != NULL)
		    	Free(tracefile_buf);
		return;
	}
#if defined(X3270_DISPLAY) /*[*/
	if (trace_shell == NULL) {
		trace_shell = create_form_popup("trace",
		    tracefile_callback,
		    appres.trace_monitor? no_tracefile_callback: NULL,
		    FORM_NO_WHITE);
		XtVaSetValues(XtNameToWidget(trace_shell, ObjDialog),
		    XtNvalue, tracefile,
		    NULL);
	}

	/* Turn the toggle _off_ until the popup succeeds. */
	appres.toggle[reason].value = False;
	appres.toggle[reason].changed = True;

	popup_popup(trace_shell, XtGrabExclusive);
#endif /*]*/

	if (tracefile_buf != NULL)
		Free(tracefile_buf);
}
예제 #13
0
파일: trace_ds.c 프로젝트: hharte/c3270
/* Callback for "OK" button on trace popup */
static void
tracefile_callback(Widget w, XtPointer client_data, XtPointer call_data _is_unused)
{
	char *tfn = CN;
	int devfd = -1;
#if defined(X3270_DISPLAY) /*[*/
	int pipefd[2];
	Boolean just_piped = False;
#endif /*]*/
	char *buf;

#if defined(X3270_DISPLAY) /*[*/
	if (w)
		tfn = XawDialogGetValueString((Widget)client_data);
	else
#endif /*]*/
		tfn = (char *)client_data;
	tfn = do_subst(tfn, DS_VARS | DS_TILDE | DS_UNIQUE);
	if (strchr(tfn, '\'') ||
	    ((int)strlen(tfn) > 0 && tfn[strlen(tfn)-1] == '\\')) {
		popup_an_error("Illegal file name: %s", tfn);
		Free(tfn);
		goto done;
	}

	tracef_max = 0;

	if (!strcmp(tfn, "stdout")) {
		tracef = stdout;
	} else {
#if defined(X3270_DISPLAY) /*[*/
		FILE *pipefile = NULL;

		if (!strcmp(tfn, "none") || !tfn[0]) {
			just_piped = True;
			if (!appres.trace_monitor) {
				popup_an_error("Must specify a trace file "
				    "name");
				free(tfn);
				goto done;
			}
		}

		if (appres.trace_monitor) {
			if (pipe(pipefd) < 0) {
				popup_an_errno(errno, "pipe() failed");
				Free(tfn);
				goto done;
			}
			pipefile = fdopen(pipefd[1], "w");
			if (pipefile == NULL) {
				popup_an_errno(errno, "fdopen() failed");
				(void) close(pipefd[0]);
				(void) close(pipefd[1]);
				Free(tfn);
				goto done;
			}
			(void) SETLINEBUF(pipefile);
			(void) fcntl(pipefd[1], F_SETFD, 1);
		}

		if (just_piped) {
			tracef = pipefile;
		} else
#endif /*]*/
		{
		    	Boolean append = False;

#if defined(X3270_DISPLAY) /*[*/
			tracef_pipe = pipefile;
#endif /*]*/
			/* Get the trace file maximum. */
			get_tracef_max();

			/* Open and configure the file. */
			if ((devfd = get_devfd(tfn)) >= 0)
				tracef = fdopen(dup(devfd), "a");
			else if (!strncmp(tfn, ">>", 2)) {
			    	append = True;
				tracef = fopen(tfn + 2, "a");
			} else
				tracef = fopen(tfn, "w");
			if (tracef == (FILE *)NULL) {
				popup_an_errno(errno, "%s", tfn);
#if defined(X3270_DISPLAY) /*[*/
				fclose(tracef_pipe);
				(void) close(pipefd[0]);
				(void) close(pipefd[1]);
#endif /*]*/
				Free(tfn);
				goto done;
			}
			tracef_size = ftello(tracef);
			Replace(tracefile_name,
				NewString(append? tfn + 2: tfn));
			(void) SETLINEBUF(tracef);
#if !defined(_WIN32) /*[*/
			(void) fcntl(fileno(tracef), F_SETFD, 1);
#endif /*]*/
		}
	}

#if defined(X3270_DISPLAY) /*[*/
	/* Start the monitor window */
	if (tracef != stdout && appres.trace_monitor) {
		switch (tracewindow_pid = fork_child()) {
		    case 0:	/* child process */
			{
				char cmd[64];

				(void) snprintf(cmd, sizeof(cmd), "cat <&%d",
					pipefd[0]);
				(void) execlp("xterm", "xterm",
				    "-title", just_piped? "trace": tfn,
				    "-sb", "-e", "/bin/sh", "-c",
				    cmd, CN);
			}
			(void) perror("exec(xterm) failed");
			_exit(1);
		    default:	/* parent */
			(void) close(pipefd[0]);
			++children;
			break;
		    case -1:	/* error */
			popup_an_errno(errno, "fork() failed");
			break;
		}
	}
#endif /*]*/

#if defined(_WIN32) && defined(C3270) /*[*/
	/* Start the monitor window. */
	if (tracef != stdout && appres.trace_monitor && is_installed) {
		STARTUPINFO startupinfo;
		PROCESS_INFORMATION process_information;
		char *path;
		char *args;

	    	(void) memset(&startupinfo, '\0', sizeof(STARTUPINFO));
		startupinfo.cb = sizeof(STARTUPINFO);
		startupinfo.lpTitle = tfn;
		(void) memset(&process_information, '\0',
			      sizeof(PROCESS_INFORMATION));
		path = xs_buffer("%scatf.exe", instdir);
		args = xs_buffer("\"%scatf.exe\" \"%s\"", instdir, tfn);
		if (CreateProcess(
		    path,
		    args,
		    NULL,
		    NULL,
		    FALSE,
		    CREATE_NEW_CONSOLE,
		    NULL,
		    NULL,
		    &startupinfo,
		    &process_information) == 0) {
		    	popup_an_error("CreateProcess(%s) failed: %s",
				path, win32_strerror(GetLastError()));
			Free(path);
			Free(args);
		} else {
			Free(path);
		    	Free(args);
			tracewindow_handle = process_information.hProcess;
			CloseHandle(process_information.hThread);
		}
	}
#endif /*]*/

	Free(tfn);

	/* We're really tracing, turn the flag on. */
	appres.toggle[trace_reason].value = True;
	appres.toggle[trace_reason].changed = True;
	menubar_retoggle(&appres.toggle[trace_reason], trace_reason);

	/* Display current status. */
	buf = create_tracefile_header("started");
	do_ts = False;
	wtrace("%s", buf);
	Free(buf);

done:
#if defined(X3270_DISPLAY) /*[*/
	if (w)
		XtPopdown(trace_shell);
#endif /*]*/
	return;
}
예제 #14
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;
}
예제 #15
0
파일: glue.c 프로젝트: hharte/c3270
/*
 * Validate a resource that is fetched explicitly, rather than via appres.
 */
static int
valid_explicit(const char *resname, unsigned len)
{
	static struct {
	    char *name;
	    enum { V_FLAT, V_WILD, V_COLOR } type;
	} explicit_resources[] =  {
	    { ResKeymap,			V_WILD },
	    { ResAssocCommand,			V_FLAT },
	    { ResLuCommandLine,			V_FLAT },
	    { ResPrintTextScreensPerPage,	V_FLAT },
#if defined(_WIN32) /*[*/
	    { ResPrinterCodepage,		V_FLAT },
	    { ResPrinterCommand,		V_FLAT },
	    { ResPrinterName, 			V_FLAT },
	    { ResPrintTextFont, 		V_FLAT },
	    { ResPrintTextHorizontalMargin,	V_FLAT },
	    { ResPrintTextOrientation,		V_FLAT },
	    { ResPrintTextSize, 		V_FLAT },
	    { ResPrintTextVerticalMargin,	V_FLAT },
	    { ResHostColorForDefault,		V_FLAT },
	    { ResHostColorForIntensified,	V_FLAT },
	    { ResHostColorForProtected,		V_FLAT },
	    { ResHostColorForProtectedIntensified,V_FLAT },
	    { ResConsoleColorForHostColor,	V_COLOR },
#else /*][*/
	    { ResPrinterCommand,		V_FLAT },
	    { ResPrintTextCommand,		V_FLAT },
	    { ResCursesColorForDefault,		V_FLAT },
	    { ResCursesColorForIntensified,	V_FLAT },
	    { ResCursesColorForProtected,	V_FLAT },
	    { ResCursesColorForProtectedIntensified,V_FLAT },
	    { ResCursesColorForHostColor,	V_COLOR },
#endif /*]*/
	    { NULL, V_WILD }
	};
	int i;
	int j;

	for (i = 0; explicit_resources[i].name != CN; i++) {
		unsigned sl = strlen(explicit_resources[i].name);

	    	switch (explicit_resources[i].type) {
		case V_FLAT:
		    /* Exact match. */
		    if (len == sl &&
			!strncmp(explicit_resources[i].name, resname, sl))
			return 0;
		    break;
		case V_WILD:
		    /* xxx.* match. */
		    if (len > sl + 1 &&
			resname[sl] == '.' &&
			!strncmp(explicit_resources[i].name, resname, sl))
			return 0;
		    break;
		case V_COLOR:
		    /* xxx<host-color> or xxx<host-color-index> match. */
		    for (j = 0; host_color[j].name != CN; j++) {
			    char *x;

			    x = xs_buffer("%s%s", explicit_resources[i].name,
				    host_color[j].name);
			    if (strlen(x) == len &&
				!strncmp(x, resname, len)) {
				    Free(x);
				    return 0;
			    }
			    Free(x);
			    x = xs_buffer("%s%d", explicit_resources[i].name,
				    host_color[j].index);
			    if (strlen(x) == len &&
				!strncmp(x, resname, len)) {
				    Free(x);
				    return 0;
			    }
			    Free(x);
		    }
		    break;
		}
	}

	return -1;

}
예제 #16
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;
}