#pragma prototyped
#include "common.h"
int warnflag;
char *leftypath, *leftyoptions, *shellpath;
jmp_buf exitljbuf;
int idlerunmode;
fd_set inputfds;
#ifdef FEATURE_NETSCAPE
static int innetscape;
static char *nswin;
#endif
#ifndef FEATURE_MS
#define PATHDEL '/'
#define PATHSEP ':'
#define PATHSEPSTR ":"
#define PATHLEFTY "/../lib/lefty"
#else
#define PATHDEL '\\'
#define PATHSEP ';'
#define PATHSEPSTR ";"
#define PATHLEFTY "\\..\\lib\\lefty"
#endif
#ifdef FEATURE_X11
#define WINSYS "LEFTYWINSYS=X11"
#endif
#ifdef FEATURE_MS
#define WINSYS "LEFTYWINSYS=mswin"
#endif
#ifdef FEATURE_GTK
#ifdef FEATURE_MS
#define WINSYS "LEFTYWINSYS=mswin"
#else
#define WINSYS "LEFTYWINSYS=X11"
#endif
#endif
#include "g.h"
#include "gcommon.h"
#ifdef FEATURE_GTK
static int Gnocallbacks;
#else
#ifdef FEATURE_MS
extern int Gnocallbacks;
#endif
#endif
static char *pathp;
#define PATHINCR 10240
#define PATHSIZE sizeof (char)
static char *cmdp;
#define CMDINCR 4096
#define CMDSIZE sizeof (char)
static char *lpathp;
int init (char *aout) {
char *s1, *s2, c = 0;
int k;
#ifdef FEATURE_WIN32
#ifndef FEATURE_GTK
extern HANDLE hinstance;
char buf[260];
#endif
#endif
#ifdef FEATURE_NETSCAPE
if (getenv ("INNETSCAPE"))
innetscape = TRUE, nswin = getenv ("NSWIN");
#endif
if (!(pathp = malloc (PATHINCR * PATHSIZE)))
panic (POS, "init", "pathp malloc failed");
if (!(cmdp = malloc (CMDINCR * CMDSIZE)))
panic (POS, "init", "cmdp malloc failed");
shellpath = getenv ("PATH");
#if defined(FEATURE_GTK) || defined(FEATURE_X11)
if (!strchr (aout, PATHDEL)) {
leftypath = "";
if ((s1 = buildpath (aout, TRUE)))
aout = strdup (s1);
} else
aout = strdup (aout);
#else
GetModuleFileName (hinstance, buf, 260);
aout = buf;
#endif
if (!(s1 = strrchr (aout, PATHDEL)))
s1 = aout;
*s1 = 0;
if (!(leftypath = malloc (PATHINCR * PATHSIZE)))
panic (POS, "init", "leftypath malloc failed");
leftypath[0] = 0;
if ((s1 = getenv ("LEFTYPATH")))
strcat (leftypath, s1), strcat (leftypath, PATHSEPSTR);
if (*aout)
strcat (leftypath, aout), strcat (leftypath, PATHSEPSTR);
for (k = 0; k < 2; k++) {
if (k == 0)
s1 = aout;
else
s1 = shellpath;
while (s1) {
if ((s2 = strchr (s1, PATHSEP)))
c = *s2, *s2 = 0;
strcat (leftypath, s1);
strcat (leftypath, PATHLEFTY);
if (s2) {
*s2 = c, s1 = s2 + 1;
strcat (leftypath, PATHSEPSTR);
} else
s1 = NULL;
}
if (leftypath[0])
strcat (leftypath, PATHSEPSTR);
}
#ifdef LEFTYPATH
strcat (leftypath, LEFTYPATH), strcat (leftypath, PATHSEPSTR);
#endif
if (!(leftyoptions = getenv ("LEFTYOPTIONS")))
leftyoptions = "";
putenv (WINSYS);
return 0;
}
void term (void) {
if (lpathp)
free (lpathp);
if (pathp)
free (pathp);
if (cmdp)
free (cmdp);
}
char *buildpath (char *file, int flag) {
struct stat statbuf;
char *s1, *s2;
int mode, pathi, i;
#ifdef FEATURE_NETSCAPE
if (flag == FALSE && innetscape) {
#ifdef FEATURE_WIN32
HWND hwnd;
char *s;
if (!nswin) {
MessageBox ((HWND) NULL, "error: no peer window",
"Lefty Warning", MB_APPLMODAL);
return NULL;
}
hwnd = atol (nswin);
fprintf (stdout, "file %s\n", file);
if (fflush (stdout) == -1) {
MessageBox ((HWND) NULL, "Lost Connection to Netscape",
"Lefty Warning", MB_APPLMODAL);
return NULL;
}
SendMessage (hwnd, WM_USER, 12, 34);
fgets (pathp, PATHINCR - 1, stdin);
pathp[strlen (pathp) - 1] = 0;
if (pathp[0] == 0)
return NULL;
return pathp;
#else
Window window;
static XButtonEvent ev;
if (!nswin) {
fprintf (stderr, "error: no peer window\n");
return NULL;
}
window = strtol (nswin, NULL, 16);
fprintf (stdout, "file %s\n", file);
if (fflush (stdout) == -1) {
fprintf (stderr, "Lost Connection to Netscape\n");
return NULL;
}
ev.type = ButtonPress;
ev.window = window;
ev.x = -123, ev.y = -123;
XSendEvent (Gdisplay, window, False, 0, (XEvent *) &ev);
XFlush (Gdisplay);
fgets (pathp, PATHINCR - 1, stdin);
pathp[strlen (pathp) - 1] = 0;
if (pathp[0] == 0)
return NULL;
return pathp;
#endif
}
#endif
#ifndef FEATURE_MS
if (file && file[0] && strchr (file, PATHDEL))
return file;
mode = S_IRUSR | (flag ? S_IXUSR : 0);
for (i = 0; i < 2; i++) {
if (i == 0)
s1 = leftypath;
else
s1 = shellpath;
while (*s1) {
pathi = 0;
while (*s1 && *s1 != PATHSEP)
if (pathi < PATHINCR)
pathp[pathi++] = *s1++;
if (*s1)
s1++;
if (pathi + 3 + strlen (file) >= PATHINCR)
continue;
pathp[pathi++] = PATHDEL;
for (s2 = file; *s2; s2++)
pathp[pathi++] = *s2;
pathp[pathi] = '\000';
if (stat (pathp, &statbuf) == 0 && (statbuf.st_mode & mode))
return pathp;
}
}
#else
if (file && file[0] && strchr (file, PATHDEL))
return file;
mode = ~0;
for (i = 0; i < 2; i++) {
if (i == 0)
s1 = leftypath;
else
s1 = shellpath;
while (*s1) {
pathi = 0;
while (*s1 && *s1 != PATHSEP)
if (pathi < PATHINCR)
pathp[pathi++] = *s1++;
if (*s1)
s1++;
if (pathi + 7 + strlen (file) >= PATHINCR)
continue;
pathp[pathi++] = PATHDEL;
for (s2 = file; *s2; s2++)
pathp[pathi++] = *s2;
if (flag) {
pathp[pathi++] = '.';
pathp[pathi++] = 'e';
pathp[pathi++] = 'x';
pathp[pathi++] = 'e';
}
pathp[pathi] = '\000';
if (stat (pathp, &statbuf) == 0 && (statbuf.st_mode & mode))
return pathp;
}
}
#endif
return NULL;
}
char *buildcommand (char *path, char *host, int infd, int outfd, char *fmt) {
char buf[10];
char *s1, *s2;
int bufi;
cmdp[0] = '\000';
for (bufi = 0, s1 = fmt; *s1; s1++) {
if (*s1 == '%') {
if (*(s1 + 1) == 'e') {
s1++;
if (bufi + strlen (path) >= CMDINCR)
return NULL;
for (s2 = path; *s2; s2++)
cmdp[bufi++] = *s2;
continue;
} else if (*(s1 + 1) == 'i') {
if (infd == -1)
buf[0] = '%', buf[1] = 'd', buf[2] = '\000';
else
sprintf (buf, "%d", infd);
s1++;
if (bufi + strlen (buf) >= CMDINCR)
return NULL;
for (s2 = buf; *s2; s2++)
cmdp[bufi++] = *s2;
continue;
} else if (*(s1 + 1) == 'o') {
if (outfd == -1)
buf[0] = '%', buf[1] = 'd', buf[2] = '\000';
else
sprintf (buf, "%d", outfd);
s1++;
if (bufi + strlen (buf) >= CMDINCR)
return NULL;
for (s2 = buf; *s2; s2++)
cmdp[bufi++] = *s2;
continue;
} else if (*(s1 + 1) == 'h') {
s1++;
if (bufi + strlen (host) >= CMDINCR)
return NULL;
for (s2 = host; *s2; s2++)
cmdp[bufi++] = *s2;
continue;
}
}
if (bufi + 1 >= CMDINCR)
return NULL;
cmdp[bufi++] = *s1;
}
if (bufi + 1 >= CMDINCR)
return NULL;
cmdp[bufi] = '\000';
return &cmdp[0];
}
void warning (char *file, int line, char *func, char *fmt, ...) {
va_list args;
#ifndef FEATURE_MS
if (!warnflag)
return;
va_start(args, fmt);
fprintf (stderr, "warning: (file %s, line %d, func %s) ", file, line, func);
vfprintf (stderr, fmt, args);
fprintf (stderr, "\n");
va_end(args);
#else
char buf[256];
if (!warnflag)
return;
va_start(args, fmt);
vsprintf (buf, fmt, args);
Gnocallbacks = TRUE;
MessageBox ((HWND) NULL, buf, "Lefty Warning", MB_APPLMODAL);
Gnocallbacks = FALSE;
va_end(args);
#endif
}
void panic (char *file, int line, char *func, char *fmt, ...) {
va_list args;
#ifndef FEATURE_MS
va_start(args, fmt);
fprintf (stderr, "panic: (file %s, line %d, func %s) ", file, line, func);
vfprintf (stderr, fmt, args);
fprintf (stderr, "\n");
fflush (stdout);
va_end(args);
#else
char buf[256];
va_start(args, fmt);
vsprintf (buf, fmt, args);
Gnocallbacks = TRUE;
MessageBox ((HWND) NULL, buf, "Lefty PANIC", MB_APPLMODAL);
Gnocallbacks = FALSE;
va_end(args);
#endif
abort ();
}
void panic2 (char *file, int line, char *func, char *fmt, ...) {
va_list args;
#ifndef FEATURE_MS
va_start(args, fmt);
fprintf (stderr, "panic: (file %s, line %d, func %s) ", file, line, func);
vfprintf (stderr, fmt, args);
fprintf (stderr, "\n");
perror ("");
fflush (stdout);
va_end(args);
#else
char buf[256];
va_start(args, fmt);
vsprintf (buf, fmt, args);
Gnocallbacks = TRUE;
MessageBox ((HWND) NULL, buf, "Lefty PANIC", MB_APPLMODAL);
Gnocallbacks = FALSE;
va_end(args);
#endif
abort ();
}
#ifdef FEATURE_MS
int printf (const char *fmt, ...) {
va_list args;
char buf[256];
int l;
va_start(args, fmt);
vsprintf (buf, fmt, args);
l = strlen (buf);
if (buf[l - 1] == '\n')
buf[l - 1] = 0;
if (buf[0]) {
Gnocallbacks = TRUE;
MessageBox ((HWND) NULL, buf, "Lefty printf", MB_APPLMODAL);
Gnocallbacks = FALSE;
}
va_end(args);
}
#endif