Exemple #1
0
/* 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();
}
Exemple #2
0
/* 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);
	}
}
Exemple #3
0
/*
 * 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;
    }
}
Exemple #4
0
/* 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;
}
Exemple #5
0
/*
 * Write to the trace file, varargs style.
 * This is the only function that actually does output to the trace file --
 * all others are wrappers around this function.
 */
static void
vwtrace(const char *fmt, va_list args)
{
	if (tracef_bufptr != CN) {
		tracef_bufptr += vsprintf(tracef_bufptr, fmt, args); /* XXX */
	} else if (tracef != NULL) {
		int n2w, nw;
		char buf[16384];
		struct timeval tv;
		time_t t;
		struct tm *tm;

		/* Start with a timestamp. */
		if (do_ts) {
			(void) gettimeofday(&tv, NULL);
			t = tv.tv_sec;
			tm = localtime(&t);
			n2w = snprintf(buf, sizeof(buf),
				"%d%02d%02d.%02d%02d%02d.%03d ",
				tm->tm_year + 1900,
				tm->tm_mon + 1,
				tm->tm_mday,
				tm->tm_hour,
				tm->tm_min,
				tm->tm_sec,
				(int)(tv.tv_usec / 1000L));
			(void) fwrite(buf, n2w, 1, tracef);
			fflush(tracef);
			if (tracef_pipe != NULL) {
				(void) fwrite(buf, n2w, 1, tracef_pipe);
				fflush(tracef);
			}
			do_ts = False;
		}

		(void) vsnprintf(buf, sizeof(buf), fmt, args);
		n2w = strlen(buf);
		if (n2w > 0 && buf[n2w - 1] == '\n')
		    	do_ts = True;

		nw = fwrite(buf, n2w, 1, tracef);
		if (nw == 1) {
			fflush(tracef);
		} else {
			if (errno != EPIPE
#if defined(EILSEQ) /*[*/
					   && errno != EILSEQ
#endif /*]*/
					                     )
				popup_an_errno(errno,
				    "Write to trace file failed");
#if defined(EILSEQ) /*[*/
			if (errno != EILSEQ)
#endif /*]*/
			{
				stop_tracing();
				return;
			}
		}
		tracef_size = ftello(tracef);
		if (tracef_pipe != NULL) {
			nw = fwrite(buf, n2w, 1, tracef_pipe);
			if (nw != 1) {
				(void) fclose(tracef_pipe);
				tracef_pipe = NULL;
			} else {
			    	fflush(tracef_pipe);
			}
		}
	}
}
Exemple #6
0
/* Start tracing, using the specified file. */
void
tracefile_ok(const char *tfn)
{
    int devfd = -1;
#if !defined(_WIN32) /*[*/
    int pipefd[2];
    bool just_piped = false;
#endif /*]*/
    char *buf;
    char *stfn;

    stfn = do_subst(tfn, DS_VARS | DS_TILDE | DS_UNIQUE);
    if (strchr(stfn, '\'') ||
	((int)strlen(stfn) > 0 && stfn[strlen(stfn)-1] == '\\')) {
	popup_an_error("Illegal file name: %s", tfn);
	Free(stfn);
	goto done;
    }

    tracef_max = 0;

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

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

	if (appres.trace_monitor) {
	    if (pipe(pipefd) < 0) {
		popup_an_errno(errno, "pipe() failed");
		Free(stfn);
		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(stfn);
		goto done;
	    }
	    (void) SETLINEBUF(pipefile);
	    (void) fcntl(pipefd[1], F_SETFD, 1);
	}

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

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

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

    /* Start the monitor window. */
    if (tracef != stdout && appres.trace_monitor && product_has_display()) {
#if !defined(_WIN32) /*[*/
	start_trace_window(just_piped? NULL: stfn, pipefd);
#else /*][*/
	if (windirs_flags && GD_CATF) {
	    start_trace_window(stfn);
	}
#endif /*]*/
    }

    Free(stfn);

    /* We're really tracing, turn the flag on. */
    set_toggle(trace_reason, true);
    menubar_retoggle(trace_reason);

    /* Display current status. */
    buf = create_tracefile_header("started");
    wtrace(false, "%s", buf);
    Free(buf);
done:
    return;
}
Exemple #7
0
/*
 * Write to the trace file, varargs style.
 * This is the only function that actually does output to the trace file --
 * all others are wrappers around this function.
 */
static void
vwtrace(bool do_ts, const char *fmt, va_list args)
{
    size_t n2w_left, n2w, nw;
    char *ts;
    char *buf = NULL;
    char *bp;

    /* Ugly hack to write into a memory buffer. */
    if (tracef_bufptr != NULL) {
	if (do_ts) {
	    tracef_bufptr += sprintf(tracef_bufptr, "%s", gen_ts());
	}
	tracef_bufptr += vsprintf(tracef_bufptr, fmt, args);
	return;
    }

    if (tracef == NULL) {
	return;
    }

    ts = NULL;

    buf = xs_vbuffer(fmt, args);
    n2w_left = strlen(buf);
    bp = buf;

    while (n2w_left > 0) {
	char *nl;
	bool wrote_nl = false;

	if (do_ts && !wrote_ts) {
	    if (ts == NULL) {
		ts = gen_ts();
	    }
	    (void) fwrite(ts, strlen(ts), 1, tracef);
	    fflush(tracef);
	    if (tracef_pipe != NULL) {
		(void) fwrite(ts, strlen(ts), 1, tracef_pipe);
		fflush(tracef);
	    }
	    wrote_ts = true;
	}

	nl = strchr(bp, '\n');
	if (nl != NULL) {
	    wrote_nl = true;
	    n2w = nl - bp + 1;
	} else {
	    n2w = n2w_left;
	}

	nw = fwrite(bp, n2w, 1, tracef);
	if (nw == 1) {
	    fflush(tracef);
	} else {
	    if (errno != EPIPE && !IS_EILSEQ(errno)) {
		popup_an_errno(errno, "Write to trace file failed");
	    }
	    if (!IS_EILSEQ(errno)) {
		stop_tracing();
		goto done;
	    }
	}

	if (tracef_pipe != NULL) {
	    nw = fwrite(bp, n2w, 1, tracef_pipe);
	    if (nw != 1) {
		(void) fclose(tracef_pipe);
		tracef_pipe = NULL;
	    } else {
		fflush(tracef_pipe);
	    }
	}

	if (wrote_nl) {
	    wrote_ts = false;
	}

	bp += n2w;
	n2w_left -= n2w;
    }

    tracef_size = ftello(tracef);

done:
    if (buf != NULL) {
	Free(buf);
    }
    return;
}
Exemple #8
0
/*
 * Screen tracing callback.
 * Returns true for success, false for failure.
 */
static bool
screentrace_cb(tss_t how, ptype_t ptype, char *tfn)
{
	char *xtfn = NULL;
	int srv;

	if (how == TSS_FILE) {
		xtfn = do_subst(tfn, DS_VARS | DS_TILDE | DS_UNIQUE);
		screentracef = fopen(xtfn, "a");
	} else {
		/* Printer. */
#if !defined(_WIN32) /*[*/
		screentracef = popen(tfn, "w");
#else /*][*/
		int fd;

		fd = win_mkstemp(&screentrace_tmpfn, ptype);
		if (fd < 0) {
			popup_an_errno(errno, "%s", "(temporary file)");
			Free(tfn);
			return false;
		}
		screentracef = fdopen(fd, (ptype == P_GDI)? "wb+": "w");
#endif /*]*/
	}
	if (screentracef == NULL) {
		if (how == TSS_FILE)
			popup_an_errno(errno, "%s", xtfn);
		else
#if !defined(_WIN32) /*[*/
			popup_an_errno(errno, "%s", tfn);
#else /*][*/
			popup_an_errno(errno, "%s", "(temporary file)");
#endif /*]*/
		Free(xtfn);
#if defined(_WIN32) /*[*/
		Free(screentrace_tmpfn);
		screentrace_tmpfn = NULL;
#endif /*]*/
		return false;
	}
	if (how == TSS_FILE)
		Replace(screentrace_name, NewString(xtfn));
	else
		Replace(screentrace_name, NewString(tfn));
	Free(tfn);
	(void) SETLINEBUF(screentracef);
#if !defined(_WIN32) /*[*/
	(void) fcntl(fileno(screentracef), F_SETFD, 1);
#endif /*]*/
	srv = fprint_screen_start(screentracef, ptype,
		(how == TSS_PRINTER)? FPS_FF_SEP: 0,
		default_caption(), screentrace_name, &screentrace_fps);
	if (FPS_IS_ERROR(srv)) {
		if (srv == FPS_STATUS_ERROR) {
			popup_an_error("Screen trace start failed.");
		} else if (srv == FPS_STATUS_CANCEL) {
			popup_an_error("Screen trace canceled.");
		}
		fclose(screentracef);
		return false;
	}

	/* We're really tracing, turn the flag on. */
	set_toggle(SCREEN_TRACE, true);
	menubar_retoggle(SCREEN_TRACE);
	return true;
}
Exemple #9
0
/*
 * Start a file transfer, based on the contents of an ft_state structure.
 *
 * This function will fail if the file exists and the overwrite flag is not
 * set.
 *
 * Returns the local file pointer, or NULL if the transfer could not start.
 * If an error is detected, it will call popup_an_error() with an appropriate
 * message.
 */
FILE *
ft_go(ft_conf_t *p)
{
    FILE *f;
    varbuf_t r;
    unsigned flen;

    /* Adjust the DFT buffer size. */
    p->dft_buffersize = set_dft_buffersize(p->dft_buffersize);

    /* See if the local file can be overwritten. */
    if (p->receive_flag && !p->append_flag && !p->allow_overwrite) {
	f = fopen(p->local_filename, p->ascii_flag? "r": "rb");
	if (f != NULL) {
	    (void) fclose(f);
	    popup_an_error("Transfer: File exists");
	    return NULL;
	}
    }

    /* Open the local file. */
    f = fopen(p->local_filename, ft_local_fflag(p));
    if (f == NULL) {
	popup_an_errno(errno, "Local file '%s'", p->local_filename);
	return NULL;
    }

    /* Build the ind$file command */
    vb_init(&r);
    vb_appendf(&r, "IND\\e005BFILE %s %s %s",
	    p->receive_flag? "GET": "PUT",
	    p->host_filename,
	    (p->host_type != HT_TSO)? "(": "");
    if (p->ascii_flag) {
	vb_appends(&r, "ASCII");
    } else if (p->host_type == HT_CICS) {
	vb_appends(&r, "BINARY");
    }
    if (p->ascii_flag && p->cr_flag) {
	vb_appends(&r, " CRLF");
    } else if (p->host_type == HT_CICS) {
	vb_appends(&r, " NOCRLF");
    }
    if (p->append_flag && !p->receive_flag) {
	vb_appends(&r, " APPEND");
    }
    if (!p->receive_flag) {
	if (p->host_type == HT_TSO) {
	    if (p->recfm != DEFAULT_RECFM) {
		/* RECFM Entered, process */
		vb_appends(&r, " RECFM(");
		switch (p->recfm) {
		case RECFM_FIXED:
		    vb_appends(&r, "F");
		    break;
		case RECFM_VARIABLE:
		    vb_appends(&r, "V");
		    break;
		case RECFM_UNDEFINED:
		    vb_appends(&r, "U");
		    break;
		default:
		    break;
		};
		vb_appends(&r, ")");
		if (p->lrecl) {
		    vb_appendf(&r, " LRECL(%d)", p->lrecl);
		}
		if (p->blksize) {
		    vb_appendf(&r, " BLKSIZE(%d)", p->blksize);
		}
	    }
	    if (p->units != DEFAULT_UNITS) {
		/* Space Entered, processs it */
		vb_appendf(&r, " SPACE(%d", p->primary_space);
		if (p->secondary_space) {
		    vb_appendf(&r, ",%d", p->secondary_space);
		}
		vb_appends(&r, ")");
		switch (p->units) {
		case TRACKS:
		    vb_appends(&r, " TRACKS");
		    break;
		case CYLINDERS:
		    vb_appends(&r, " CYLINDERS");
		    break;
		case AVBLOCK:
		    vb_appendf(&r, " AVBLOCK(%d)", p->avblock);
		    break;
		default:
		    break;
		}
	    }
	} else if (p->host_type == HT_VM) {
	    if (p->recfm != DEFAULT_RECFM) {
		vb_appends(&r, " RECFM ");
		switch (p->recfm) {
		case RECFM_FIXED:
		    vb_appends(&r, "F");
		    break;
		case RECFM_VARIABLE:
		    vb_appends(&r, "V");
		    break;
		default:
		    break;
		};

		if (p->lrecl) {
		    vb_appendf(&r, " LRECL %d", p->lrecl);
		}
	    }
	}
    }
    vb_appends(&r, "\\n");

    /* Erase the line and enter the command. */
    flen = kybd_prime();
    if (!flen || flen < vb_len(&r) - 1) {
	vb_free(&r);
	if (f != NULL) {
	    fclose(f);
	    if (p->receive_flag && !p->append_flag) {
		unlink(p->local_filename);
	    }
	}
	popup_an_error("%s", get_message("ftUnable"));
	return NULL;
    }
    (void) emulate_input(vb_buf(&r), vb_len(&r), false);
    vb_free(&r);

    /* Now proceed with this context. */
    ftc = p;

    /* Finish common initialization. */
    fts.last_cr = false;
    fts.is_cut = false;
    fts.last_dbcs = false;
    fts.dbcs_state = FT_DBCS_NONE;

    ft_state = FT_AWAIT_ACK;
    idle_ft_start();

    return f;
}