|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* $LynxId: LYJump.c,v 1.52 2018/03/18 19:17:00 tom Exp $
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
#include <HTUtils.h>
|
|
Packit |
f574b8 |
#include <HTAlert.h>
|
|
Packit |
f574b8 |
#include <LYUtils.h>
|
|
Packit |
f574b8 |
#include <LYStrings.h>
|
|
Packit |
f574b8 |
#include <LYGlobalDefs.h>
|
|
Packit |
f574b8 |
#include <LYJump.h>
|
|
Packit |
f574b8 |
#include <LYKeymap.h>
|
|
Packit |
f574b8 |
#include <GridText.h>
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
#include <LYLeaks.h>
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
#ifdef _WINDOWS
|
|
Packit |
f574b8 |
#include <stdlib.h> /* bsearch() */
|
|
Packit |
f574b8 |
#endif
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
#ifdef VMS
|
|
Packit |
f574b8 |
#include <fab.h>
|
|
Packit |
f574b8 |
#endif /* VMS */
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
struct JumpTable *JThead = NULL;
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
static int LYCompare(const void *e1, const void *e2);
|
|
Packit |
f574b8 |
static unsigned LYRead_Jumpfile(struct JumpTable *jtp);
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
void LYJumpTable_free(void)
|
|
Packit |
f574b8 |
{
|
|
Packit |
f574b8 |
struct JumpTable *cur = JThead;
|
|
Packit |
f574b8 |
struct JumpTable *next;
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
while (cur) {
|
|
Packit |
f574b8 |
next = cur->next;
|
|
Packit |
f574b8 |
FREE(cur->msg);
|
|
Packit |
f574b8 |
FREE(cur->file);
|
|
Packit |
f574b8 |
FREE(cur->shortcut);
|
|
Packit |
f574b8 |
if (cur->history) {
|
|
Packit |
f574b8 |
LYFreeStringList(cur->history);
|
|
Packit |
f574b8 |
cur->history = NULL;
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
FREE(cur->table);
|
|
Packit |
f574b8 |
FREE(cur->mp);
|
|
Packit |
f574b8 |
FREE(cur);
|
|
Packit |
f574b8 |
cur = next;
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
JThead = NULL;
|
|
Packit |
f574b8 |
return;
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* Utility for listing shortcuts, making any repeated
|
|
Packit |
f574b8 |
* shortcut the most current in the list. - FM
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
void LYAddJumpShortcut(HTList *historyp, char *shortcut)
|
|
Packit |
f574b8 |
{
|
|
Packit |
f574b8 |
char *tmp = NULL;
|
|
Packit |
f574b8 |
char *old;
|
|
Packit |
f574b8 |
HTList *cur = historyp;
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
if (!historyp || isEmpty(shortcut))
|
|
Packit |
f574b8 |
return;
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
StrAllocCopy(tmp, shortcut);
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
while (NULL != (old = (char *) HTList_nextObject(cur))) {
|
|
Packit |
f574b8 |
if (!strcmp(old, tmp)) {
|
|
Packit |
f574b8 |
HTList_removeObject(historyp, old);
|
|
Packit |
f574b8 |
FREE(old);
|
|
Packit |
f574b8 |
break;
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
HTList_addObject(historyp, tmp);
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
return;
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
BOOL LYJumpInit(char *config)
|
|
Packit |
f574b8 |
{
|
|
Packit |
f574b8 |
struct JumpTable *jtp;
|
|
Packit |
f574b8 |
char *cp;
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* Create a JumpTable structure.
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
jtp = typecalloc(struct JumpTable);
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
if (jtp == NULL) {
|
|
Packit |
f574b8 |
outofmem(__FILE__, "LYJumpInit");
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* config is JUMPFILE:path[:optional_key[:optional_prompt]]
|
|
Packit |
f574b8 |
*
|
|
Packit |
f574b8 |
* Skip JUMPFILE.
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
cp = strtok(config, ":\n");
|
|
Packit |
f574b8 |
if (!cp) {
|
|
Packit |
f574b8 |
FREE(jtp);
|
|
Packit |
f574b8 |
return FALSE;
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* Get the path.
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
cp = strtok(NULL, ":\n");
|
|
Packit |
f574b8 |
if (!cp) {
|
|
Packit |
f574b8 |
FREE(jtp);
|
|
Packit |
f574b8 |
return FALSE;
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
StrAllocCopy(jtp->file, cp);
|
|
Packit |
f574b8 |
#ifdef LY_FIND_LEAKS
|
|
Packit |
f574b8 |
if (!JThead)
|
|
Packit |
f574b8 |
atexit(LYJumpTable_free);
|
|
Packit |
f574b8 |
#endif /* LY_FIND_LEAKS */
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* Get the key, if present.
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
cp = strtok(NULL, ":\n");
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* If no key, check whether we are resetting the default jumps file.
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
if (!cp && JThead) {
|
|
Packit |
f574b8 |
struct JumpTable *jtptmp = JThead;
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
jumpfile = jtp->file;
|
|
Packit |
f574b8 |
FREE(jtp);
|
|
Packit |
f574b8 |
while (jtptmp && jtptmp->key)
|
|
Packit |
f574b8 |
jtptmp = jtptmp->next;
|
|
Packit |
f574b8 |
if (!jtptmp)
|
|
Packit |
f574b8 |
return FALSE;
|
|
Packit |
f574b8 |
StrAllocCopy(jtptmp->file, jumpfile);
|
|
Packit |
f574b8 |
StrAllocCopy(jtptmp->msg, jumpprompt);
|
|
Packit |
f574b8 |
return TRUE;
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* If a key is present and we have no default, create one,
|
|
Packit |
f574b8 |
* using the path from config, and the current jumpprompt.
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
if (cp && !JThead) {
|
|
Packit |
f574b8 |
JThead = jtp;
|
|
Packit |
f574b8 |
StrAllocCopy(JThead->msg, jumpprompt);
|
|
Packit |
f574b8 |
if (isEmpty(jumpfile))
|
|
Packit |
f574b8 |
StrAllocCopy(jumpfile, JThead->file);
|
|
Packit |
f574b8 |
jtp = typecalloc(struct JumpTable);
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
if (jtp == NULL) {
|
|
Packit |
f574b8 |
outofmem(__FILE__, "LYJumpInit");
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
StrAllocCopy(jtp->file, JThead->file);
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* Complete the initialization of config.
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
if (cp) {
|
|
Packit |
f574b8 |
jtp->key = remap(cp, "JUMP", FALSE); /* key is present, (re)map it */
|
|
Packit |
f574b8 |
cp = strtok(NULL, "\n"); /* get prompt, if present */
|
|
Packit |
f574b8 |
if (non_empty(cp))
|
|
Packit |
f574b8 |
StrAllocCopy(jtp->msg, cp); /* prompt is present, load it */
|
|
Packit |
f574b8 |
else
|
|
Packit |
f574b8 |
cp = NULL;
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
if (!cp) /* no prompt, use default */
|
|
Packit |
f574b8 |
StrAllocCopy(jtp->msg, jumpprompt);
|
|
Packit |
f574b8 |
if (jtp->msg[strlen(jtp->msg) - 1] != ' ') /* ensure a trailing space */
|
|
Packit |
f574b8 |
StrAllocCat(jtp->msg, " ");
|
|
Packit |
f574b8 |
jtp->history = HTList_new();
|
|
Packit |
f574b8 |
jtp->next = JThead;
|
|
Packit |
f574b8 |
JThead = jtp;
|
|
Packit |
f574b8 |
return TRUE;
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
char *LYJump(int key)
|
|
Packit |
f574b8 |
{
|
|
Packit |
f574b8 |
static bstring *buf = NULL;
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
JumpDatum seeking;
|
|
Packit |
f574b8 |
JumpDatum *found;
|
|
Packit |
f574b8 |
char *bp, *cp;
|
|
Packit |
f574b8 |
struct JumpTable *jtp;
|
|
Packit |
f574b8 |
int ch;
|
|
Packit |
f574b8 |
RecallType recall;
|
|
Packit |
f574b8 |
int ShortcutTotal;
|
|
Packit |
f574b8 |
int ShortcutNum;
|
|
Packit |
f574b8 |
BOOLEAN FirstShortcutRecall = TRUE;
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
if (!JThead)
|
|
Packit |
f574b8 |
return NULL;
|
|
Packit |
f574b8 |
jtp = JThead;
|
|
Packit |
f574b8 |
while (jtp && jtp->key && jtp->key != key)
|
|
Packit |
f574b8 |
jtp = jtp->next;
|
|
Packit |
f574b8 |
if (!jtp) {
|
|
Packit |
f574b8 |
char *msg = 0;
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
HTSprintf0(&msg, KEY_NOT_MAPPED_TO_JUMP_FILE, key);
|
|
Packit |
f574b8 |
HTAlert(msg);
|
|
Packit |
f574b8 |
FREE(msg);
|
|
Packit |
f574b8 |
return NULL;
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
if (!jtp->table)
|
|
Packit |
f574b8 |
jtp->nel = LYRead_Jumpfile(jtp);
|
|
Packit |
f574b8 |
if (jtp->nel == 0)
|
|
Packit |
f574b8 |
return NULL;
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
if (!jump_buffer || isEmpty(jtp->shortcut)) {
|
|
Packit |
f574b8 |
BStrCopy0(buf, "");
|
|
Packit |
f574b8 |
} else if (non_empty(jtp->shortcut)) {
|
|
Packit |
f574b8 |
size_t len = (size_t) BStrLen(buf);
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
if (strlen(jtp->shortcut) > len) {
|
|
Packit |
f574b8 |
jtp->shortcut[len] = '\0';
|
|
Packit |
f574b8 |
BStrCopy0(buf, jtp->shortcut);
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
ShortcutTotal = (jtp->history ? HTList_count(jtp->history) : 0);
|
|
Packit |
f574b8 |
if (jump_buffer && !isBEmpty(buf)) {
|
|
Packit |
f574b8 |
recall = ((ShortcutTotal > 1) ? RECALL_URL : NORECALL);
|
|
Packit |
f574b8 |
ShortcutNum = 0;
|
|
Packit |
f574b8 |
FirstShortcutRecall = FALSE;
|
|
Packit |
f574b8 |
} else {
|
|
Packit |
f574b8 |
recall = ((ShortcutTotal >= 1) ? RECALL_URL : NORECALL);
|
|
Packit |
f574b8 |
ShortcutNum = ShortcutTotal;
|
|
Packit |
f574b8 |
FirstShortcutRecall = TRUE;
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
statusline(jtp->msg);
|
|
Packit |
f574b8 |
if ((ch = LYgetBString(&buf, FALSE, 0, recall)) < 0) {
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* User cancelled the Jump via ^G. - FM
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
HTInfoMsg(CANCELLED);
|
|
Packit |
f574b8 |
return NULL;
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
check_recall:
|
|
Packit |
f574b8 |
bp = buf->str;
|
|
Packit |
f574b8 |
if (TOUPPER(key) == 'G' && StrNCmp(buf->str, "o ", 2) == 0)
|
|
Packit |
f574b8 |
bp++;
|
|
Packit |
f574b8 |
bp = LYSkipBlanks(bp);
|
|
Packit |
f574b8 |
if (*bp == '\0' &&
|
|
Packit |
f574b8 |
!(recall && (ch == UPARROW_KEY || ch == DNARROW_KEY))) {
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* User cancelled the Jump via a zero-length string. - FM
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
BStrCopy0(buf, "");
|
|
Packit |
f574b8 |
StrAllocCopy(jtp->shortcut, buf->str);
|
|
Packit |
f574b8 |
HTInfoMsg(CANCELLED);
|
|
Packit |
f574b8 |
return NULL;
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
#ifdef PERMIT_GOTO_FROM_JUMP
|
|
Packit |
f574b8 |
if (StrChr(bp, ':') || StrChr(bp, '/')) {
|
|
Packit |
f574b8 |
char *temp = NULL;
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
LYJumpFileURL = FALSE;
|
|
Packit |
f574b8 |
if (no_goto) {
|
|
Packit |
f574b8 |
BStrCopy0(buf, "");
|
|
Packit |
f574b8 |
StrAllocCopy(jtp->shortcut, buf->str);
|
|
Packit |
f574b8 |
HTUserMsg(RANDOM_URL_DISALLOWED);
|
|
Packit |
f574b8 |
return NULL;
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
HTSprintf0(&temp, "Go %s", bp);
|
|
Packit |
f574b8 |
BStrCopy0(buf, temp);
|
|
Packit |
f574b8 |
FREE(temp);
|
|
Packit |
f574b8 |
return (bp = buf->str);
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
#endif /* PERMIT_GOTO_FROM_JUMP */
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
if (recall && ch == UPARROW_KEY) {
|
|
Packit |
f574b8 |
if (FirstShortcutRecall) {
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* Use last Shortcut in the list. - FM
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
FirstShortcutRecall = FALSE;
|
|
Packit |
f574b8 |
ShortcutNum = 0;
|
|
Packit |
f574b8 |
} else {
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* Go back to the previous Shortcut in the list. - FM
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
ShortcutNum++;
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
if (ShortcutNum >= ShortcutTotal)
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* Roll around to the last Shortcut in the list. - FM
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
ShortcutNum = 0;
|
|
Packit |
f574b8 |
if ((cp = (char *) HTList_objectAt(jtp->history,
|
|
Packit |
f574b8 |
ShortcutNum)) != NULL) {
|
|
Packit |
f574b8 |
BStrCopy0(buf, cp);
|
|
Packit |
f574b8 |
if (jump_buffer && jtp->shortcut &&
|
|
Packit |
f574b8 |
!strcmp(buf->str, jtp->shortcut)) {
|
|
Packit |
f574b8 |
_statusline(EDIT_CURRENT_SHORTCUT);
|
|
Packit |
f574b8 |
} else if ((jump_buffer && ShortcutTotal == 2) ||
|
|
Packit |
f574b8 |
(!jump_buffer && ShortcutTotal == 1)) {
|
|
Packit |
f574b8 |
_statusline(EDIT_THE_PREV_SHORTCUT);
|
|
Packit |
f574b8 |
} else {
|
|
Packit |
f574b8 |
_statusline(EDIT_A_PREV_SHORTCUT);
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
if ((ch = LYgetBString(&buf, FALSE, 0, recall)) < 0) {
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* User cancelled the jump via ^G.
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
HTInfoMsg(CANCELLED);
|
|
Packit |
f574b8 |
return NULL;
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
goto check_recall;
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
} else if (recall && ch == DNARROW_KEY) {
|
|
Packit |
f574b8 |
if (FirstShortcutRecall) {
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* Use the first Shortcut in the list. - FM
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
FirstShortcutRecall = FALSE;
|
|
Packit |
f574b8 |
ShortcutNum = ShortcutTotal - 1;
|
|
Packit |
f574b8 |
} else {
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* Advance to the next Shortcut in the list. - FM
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
ShortcutNum--;
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
if (ShortcutNum < 0)
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* Roll around to the first Shortcut in the list. - FM
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
ShortcutNum = ShortcutTotal - 1;
|
|
Packit |
f574b8 |
if ((cp = (char *) HTList_objectAt(jtp->history,
|
|
Packit |
f574b8 |
ShortcutNum)) != NULL) {
|
|
Packit |
f574b8 |
BStrCopy0(buf, cp);
|
|
Packit |
f574b8 |
if (jump_buffer && jtp->shortcut &&
|
|
Packit |
f574b8 |
!strcmp(buf->str, jtp->shortcut)) {
|
|
Packit |
f574b8 |
_statusline(EDIT_CURRENT_SHORTCUT);
|
|
Packit |
f574b8 |
} else if ((jump_buffer && ShortcutTotal == 2) ||
|
|
Packit |
f574b8 |
(!jump_buffer && ShortcutTotal == 1)) {
|
|
Packit |
f574b8 |
_statusline(EDIT_THE_PREV_SHORTCUT);
|
|
Packit |
f574b8 |
} else {
|
|
Packit |
f574b8 |
_statusline(EDIT_A_PREV_SHORTCUT);
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
if ((ch = LYgetBString(&buf, FALSE, 0, recall)) < 0) {
|
|
Packit |
f574b8 |
/*
|
|
Packit |
f574b8 |
* User cancelled the jump via ^G.
|
|
Packit |
f574b8 |
*/
|
|
Packit |
f574b8 |
HTInfoMsg(CANCELLED);
|
|
Packit |
f574b8 |
return NULL;
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
goto check_recall;
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
seeking.key = bp;
|
|
Packit |
f574b8 |
found = (JumpDatum *) bsearch((char *) &seeking, (char *) jtp->table,
|
|
Packit |
f574b8 |
(size_t) jtp->nel, sizeof(JumpDatum), LYCompare);
|
|
Packit |
f574b8 |
if (!found) {
|
|
Packit |
f574b8 |
user_message("Unknown target '%s'", buf->str);
|
|
Packit |
f574b8 |
LYSleepAlert();
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
StrAllocCopy(jtp->shortcut, bp);
|
|
Packit |
f574b8 |
LYAddJumpShortcut(jtp->history, jtp->shortcut);
|
|
Packit |
f574b8 |
return found ? found->url : NULL;
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
static unsigned LYRead_Jumpfile(struct JumpTable *jtp)
|
|
Packit |
f574b8 |
{
|
|
Packit |
f574b8 |
struct stat st;
|
|
Packit |
f574b8 |
unsigned int nel;
|
|
Packit |
f574b8 |
char *mp;
|
|
Packit |
f574b8 |
int fd;
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
#ifdef VMS
|
|
Packit |
f574b8 |
int blocksize = 1024;
|
|
Packit |
f574b8 |
FILE *fp;
|
|
Packit |
f574b8 |
BOOL IsStream_LF = TRUE;
|
|
Packit |
f574b8 |
#endif /* VMS */
|
|
Packit |
f574b8 |
char *cp;
|
|
Packit |
f574b8 |
unsigned i;
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
if (isEmpty(jtp->file))
|
|
Packit |
f574b8 |
return 0;
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
CTRACE((tfp, "Read Jumpfile %s\n", jtp->file));
|
|
Packit |
f574b8 |
if (stat(jtp->file, &st) < 0) {
|
|
Packit |
f574b8 |
HTAlert(CANNOT_LOCATE_JUMP_FILE);
|
|
Packit |
f574b8 |
return 0;
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
/* allocate storage to read entire file */
|
|
Packit |
f574b8 |
if ((mp = typecallocn(char, (size_t) st.st_size + 1)) == NULL) {
|
|
Packit |
f574b8 |
HTAlert(OUTOF_MEM_FOR_JUMP_FILE);
|
|
Packit |
f574b8 |
return 0;
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
#ifdef VMS
|
|
Packit |
f574b8 |
if (st.st_fab_rfm != (char) FAB$C_STMLF) {
|
|
Packit |
f574b8 |
/** It's a record-oriented file. **/
|
|
Packit |
f574b8 |
IsStream_LF = FALSE;
|
|
Packit |
f574b8 |
if ((fp = fopen(jtp->file, "r", "mbc=32")) == NULL) {
|
|
Packit |
f574b8 |
HTAlert(CANNOT_OPEN_JUMP_FILE);
|
|
Packit |
f574b8 |
FREE(mp);
|
|
Packit |
f574b8 |
return 0;
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
} else if ((fd = open(jtp->file, O_RDONLY, "mbc=32")) < 0)
|
|
Packit |
f574b8 |
#else
|
|
Packit |
f574b8 |
if ((fd = open(jtp->file, O_RDONLY)) < 0)
|
|
Packit |
f574b8 |
#endif /* VMS */
|
|
Packit |
f574b8 |
{
|
|
Packit |
f574b8 |
HTAlert(CANNOT_OPEN_JUMP_FILE);
|
|
Packit |
f574b8 |
FREE(mp);
|
|
Packit |
f574b8 |
return 0;
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
#ifdef VMS
|
|
Packit |
f574b8 |
if (IsStream_LF) {
|
|
Packit |
f574b8 |
/** Handle as a stream. **/
|
|
Packit |
f574b8 |
#endif /* VMS */
|
|
Packit |
f574b8 |
if (read(fd, mp, (size_t) st.st_size) != st.st_size) {
|
|
Packit |
f574b8 |
HTAlert(ERROR_READING_JUMP_FILE);
|
|
Packit |
f574b8 |
FREE(mp);
|
|
Packit |
f574b8 |
close(fd);
|
|
Packit |
f574b8 |
return 0;
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
mp[st.st_size] = '\0';
|
|
Packit |
f574b8 |
close(fd);
|
|
Packit |
f574b8 |
#ifdef VMS
|
|
Packit |
f574b8 |
} else {
|
|
Packit |
f574b8 |
/** Handle as a series of records. **/
|
|
Packit |
f574b8 |
if (fgets(mp, blocksize, fp) == NULL) {
|
|
Packit |
f574b8 |
HTAlert(ERROR_READING_JUMP_FILE);
|
|
Packit |
f574b8 |
FREE(mp);
|
|
Packit |
f574b8 |
close(fd);
|
|
Packit |
f574b8 |
return 0;
|
|
Packit |
f574b8 |
} else {
|
|
Packit |
f574b8 |
while (fgets(mp + strlen(mp), blocksize, fp) != NULL) {
|
|
Packit |
f574b8 |
;
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
LYCloseInput(fp);
|
|
Packit |
f574b8 |
close(fd);
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
#endif /* VMS */
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
/* quick scan for approximate number of entries */
|
|
Packit |
f574b8 |
nel = 0;
|
|
Packit |
f574b8 |
cp = mp;
|
|
Packit |
f574b8 |
while ((cp = StrChr(cp, '\n')) != NULL) {
|
|
Packit |
f574b8 |
nel++;
|
|
Packit |
f574b8 |
cp++;
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
jtp->table = (JumpDatum *) malloc((nel + 1) * sizeof(JumpDatum));
|
|
Packit |
f574b8 |
if (jtp->table == NULL) {
|
|
Packit |
f574b8 |
HTAlert(OUTOF_MEM_FOR_JUMP_TABLE);
|
|
Packit |
f574b8 |
FREE(mp);
|
|
Packit |
f574b8 |
return 0;
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
cp = jtp->mp = mp;
|
|
Packit |
f574b8 |
for (i = 0; i < nel;) {
|
|
Packit |
f574b8 |
if (StrNCmp(cp, "
|
|
Packit |
f574b8 |
cp = StrChr(cp, '\n');
|
|
Packit |
f574b8 |
if (cp == NULL)
|
|
Packit |
f574b8 |
break;
|
|
Packit |
f574b8 |
cp++;
|
|
Packit |
f574b8 |
continue;
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
cp = LYstrstr(cp, "");
|
|
Packit |
f574b8 |
if (cp == NULL)
|
|
Packit |
f574b8 |
break;
|
|
Packit |
f574b8 |
cp += 4;
|
|
Packit |
f574b8 |
jtp->table[i].key = cp;
|
|
Packit |
f574b8 |
cp = LYstrstr(cp, "");
|
|
Packit |
f574b8 |
if (cp == NULL)
|
|
Packit |
f574b8 |
break;
|
|
Packit |
f574b8 |
*cp = '\0';
|
|
Packit |
f574b8 |
cp += 4;
|
|
Packit |
f574b8 |
cp = LYstrstr(cp, "href=\"");
|
|
Packit |
f574b8 |
if (cp == NULL)
|
|
Packit |
f574b8 |
break;
|
|
Packit |
f574b8 |
cp += 6;
|
|
Packit |
f574b8 |
jtp->table[i].url = cp;
|
|
Packit |
f574b8 |
cp = StrChr(cp, '"');
|
|
Packit |
f574b8 |
if (cp == NULL)
|
|
Packit |
f574b8 |
break;
|
|
Packit |
f574b8 |
*cp = '\0';
|
|
Packit |
f574b8 |
cp++;
|
|
Packit |
f574b8 |
cp = StrChr(cp, '\n');
|
|
Packit |
f574b8 |
if (cp == NULL)
|
|
Packit |
f574b8 |
break;
|
|
Packit |
f574b8 |
cp++;
|
|
Packit |
f574b8 |
CTRACE((tfp, "Read jumpfile[%u] key='%s', url='%s'\n",
|
|
Packit |
f574b8 |
i, jtp->table[i].key, jtp->table[i].url));
|
|
Packit |
f574b8 |
i++;
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
return i;
|
|
Packit |
f574b8 |
}
|
|
Packit |
f574b8 |
|
|
Packit |
f574b8 |
static int LYCompare(const void *e1, const void *e2)
|
|
Packit |
f574b8 |
{
|
|
Packit |
f574b8 |
return strcasecomp(((const JumpDatum *) e1)->key,
|
|
Packit |
f574b8 |
((const JumpDatum *) e2)->key);
|
|
Packit |
f574b8 |
}
|