📄 bookmark.c
字号:
* host name.
*/
byHostName = *bmp;
byHostNameFlag = bmabbrLen;
} else if ((cp = strchr(bmp->name, '.')) != NULL) {
/* See if it matched part of the hostname. */
if (ISTRNEQ(bmp->name, "ftp", 3)) {
cp = cp + 1;
} else if (ISTRNEQ(bmp->name, "www", 3)) {
cp = cp + 1;
} else {
cp = bmp->name;
}
if (ISTRNEQ(cp, bmabbr, bmabbrLen)) {
/* Remember this one, it matched a full
* host name.
*/
byHostAbbr = *bmp;
byHostAbbrFlag = bmabbrLen;
}
}
}
if (gBookmarkMatchMode == 0) {
/* Only use a bookmark when the exact
* bookmark name was used.
*/
if (exactMatch != 0) {
result = 0;
}
} else {
/* Pick the best match, if any. */
if (byBmNameFlag != 0) {
/* *bmp is already set. */
result = 0;
} else if (byBmAbbrFlag != 0) {
result = 0;
*bmp = byBmAbbr;
} else if (byHostNameFlag != 0) {
result = 0;
*bmp = byHostName;
} else if (byHostAbbrFlag != 0) {
result = 0;
*bmp = byHostAbbr;
}
}
if (result != 0)
memset(bmp, 0, sizeof(Bookmark));
CloseBookmarkFile(fp);
return (result);
} /* GetBookmark */
static int
BookmarkSortProc(const void *a, const void *b)
{
return (ISTRCMP((*(Bookmark *)a).bookmarkName, (*(Bookmark *)b).bookmarkName));
} /* BookmarkSortProc */
static int
BookmarkSearchProc(const void *key, const void *b)
{
return (ISTRCMP((char *) key, (*(Bookmark *)b).bookmarkName));
} /* BookmarkSearchProc */
BookmarkPtr
SearchBookmarkTable(const char *key)
{
return ((BookmarkPtr) bsearch(key, gBookmarkTable, (size_t) gNumBookmarks, sizeof(Bookmark), BookmarkSearchProc));
} /* SearchBookmarkTable */
void
SortBookmarks(void)
{
if ((gBookmarkTable == NULL) || (gNumBookmarks < 2))
return;
/* Sorting involves swapping entire Bookmark structures.
* Normally the proper thing to do is to use an array
* of pointers to Bookmarks and sort them, but even
* these days a large bookmark list can be sorted in
* the blink of an eye.
*/
qsort(gBookmarkTable, (size_t) gNumBookmarks, sizeof(Bookmark), BookmarkSortProc);
} /* SortBookmarks */
int
LoadBookmarkTable(void)
{
int i, nb;
FILE *infp;
infp = OpenBookmarkFile(&nb);
if (infp == NULL) {
nb = 0;
}
if ((nb != gNumBookmarks) && (gBookmarkTable != NULL)) {
/* Re-loading the table from disk. */
gBookmarkTable = (Bookmark *) realloc(gBookmarkTable, (size_t) (nb + 1) * sizeof(Bookmark));
memset(gBookmarkTable, 0, (nb + 1) * sizeof(Bookmark));
} else {
gBookmarkTable = calloc((size_t) (nb + 1), (size_t) sizeof(Bookmark));
}
if (gBookmarkTable == NULL) {
CloseBookmarkFile(infp);
return (-1);
}
for (i=0; i<nb; i++) {
if (GetNextBookmark(infp, gBookmarkTable + i) < 0) {
break;
}
}
gNumBookmarks = i;
CloseBookmarkFile(infp);
SortBookmarks();
return (0);
} /* LoadBookmarkTable */
/* Some characters need to be escaped so the file is editable and can
* be parsed correctly the next time it is read.
*/
static char *
BmEscapeTok(char *dst, size_t dsize, char *src)
{
char *dlim = dst + dsize - 1;
char *dst0 = dst;
int c;
while ((c = *src) != '\0') {
src++;
if ((c == '\\') || (c == ',') || (c == '$')) {
/* These need to be escaped. */
if ((dst + 1) < dlim) {
*dst++ = '\\';
*dst++ = c;
}
} else if (!isprint(c)) {
/* Escape non-printing characters. */
if ((dst + 2) < dlim) {
(void) sprintf(dst, "$%02x", c);
dst += 3;
}
} else {
if (dst < dlim)
*dst++ = c;
}
}
*dst = '\0';
return (dst0);
} /* BmEscapeTok */
/* Converts a Bookmark into a text string, and writes it to the saved
* bookmarks file.
*/
static int
WriteBmLine(Bookmark *bmp, FILE *outfp, int savePassword)
{
char tok[256];
char pass[160];
if (fprintf(outfp, "%s", bmp->bookmarkName) < 0) return (-1) ;/*1*/
if (fprintf(outfp, ",%s", BmEscapeTok(tok, sizeof(tok), bmp->name)) < 0) return (-1) ;/*2*/
if (fprintf(outfp, ",%s", BmEscapeTok(tok, sizeof(tok), bmp->user)) < 0) return (-1) ;/*3*/
if ((bmp->pass[0] != '\0') && (savePassword == 1)) {
(void) memcpy(pass, kPasswordMagic, kPasswordMagicLen);
ToBase64(pass + kPasswordMagicLen, bmp->pass, strlen(bmp->pass), 1);
if (fprintf(outfp, ",%s", pass) < 0) return (-1) ;/*4*/
} else {
if (fprintf(outfp, ",%s", "") < 0) return (-1) ;/*4*/
}
if (fprintf(outfp, ",%s", BmEscapeTok(tok, sizeof(tok), bmp->acct)) < 0) return (-1) ;/*5*/
if (fprintf(outfp, ",%s", BmEscapeTok(tok, sizeof(tok), bmp->dir)) < 0) return (-1) ;/*6*/
if (fprintf(outfp, ",%c", bmp->xferType) < 0) return (-1) ;/*7*/
if (fprintf(outfp, ",%u", (unsigned int) bmp->port) < 0) return (-1) ;/*8*/
if (fprintf(outfp, ",%lu", (unsigned long) bmp->lastCall) < 0) return (-1) ;/*9*/
if (fprintf(outfp, ",%d", bmp->hasSIZE) < 0) return (-1) ;/*10*/
if (fprintf(outfp, ",%d", bmp->hasMDTM) < 0) return (-1) ;/*11*/
if (fprintf(outfp, ",%d", bmp->hasPASV) < 0) return (-1) ;/*12*/
if (fprintf(outfp, ",%d", bmp->isUnix) < 0) return (-1) ;/*13*/
if (fprintf(outfp, ",%s", bmp->lastIP) < 0) return (-1) ;/*14*/
if (fprintf(outfp, ",%s", BmEscapeTok(tok, sizeof(tok), bmp->comment)) < 0) return (-1) ;/*15*/
if (fprintf(outfp, ",%s", "") < 0) return (-1) ;/*16*/
if (fprintf(outfp, ",%s", "") < 0) return (-1) ;/*17*/
if (fprintf(outfp, ",%s", "") < 0) return (-1) ;/*18*/
if (fprintf(outfp, ",%s", "") < 0) return (-1) ;/*19*/
if (fprintf(outfp, ",%c", bmp->xferMode) < 0) return (-1) ;/*20*/
if (fprintf(outfp, ",%d", bmp->hasUTIME) < 0) return (-1) ;/*21*/
if (fprintf(outfp, ",%s", BmEscapeTok(tok, sizeof(tok), bmp->ldir)) < 0) return (-1) ;/*22*/
if (fprintf(outfp, "\n") < 0) return (-1) ;
if (fflush(outfp) < 0) return (-1);
return (0);
} /* WriteBmLine */
static int
SwapBookmarkFiles(void)
{
char pidStr[32];
char pathName[256], path2[256];
(void) OurDirectoryPath(path2, sizeof(path2), kBookmarkFileName);
(void) OurDirectoryPath(pathName, sizeof(pathName), kTmpBookmarkFileName);
(void) sprintf(pidStr, "-%u.txt", (unsigned int) getpid());
(void) STRNCAT(pathName, pidStr);
(void) remove(path2);
if (rename(pathName, path2) < 0) {
return (-1);
}
return (0);
} /* SwapBookmarkFiles */
/* Saves a Bookmark structure into the bookmarks file. */
FILE *
OpenTmpBookmarkFile(int nb)
{
FILE *outfp;
char pidStr[32];
char pathName[256], path2[256];
if (gOurDirectoryPath[0] == '\0')
return (NULL); /* Don't create in root directory. */
(void) OurDirectoryPath(path2, sizeof(path2), kBookmarkFileName);
(void) OurDirectoryPath(pathName, sizeof(pathName), kTmpBookmarkFileName);
(void) sprintf(pidStr, "-%u.txt", (unsigned int) getpid());
(void) STRNCAT(pathName, pidStr);
outfp = fopen(pathName, FOPEN_WRITE_TEXT);
if (outfp == NULL) {
(void) fprintf(stderr, "Could not save bookmark.\n");
perror(pathName);
return (NULL);
}
(void) chmod(pathName, 00600);
if (nb > 0) {
if (fprintf(outfp, "NcFTP bookmark-file version: %d\nNumber of bookmarks: %d\n", kBookmarkVersion, nb) < 0) {
(void) fprintf(stderr, "Could not save bookmark.\n");
perror(pathName);
(void) fclose(outfp);
return (NULL);
}
} else {
if (fprintf(outfp, "NcFTP bookmark-file version: %d\nNumber of bookmarks: ??\n", kBookmarkVersion) < 0) {
(void) fprintf(stderr, "Could not save bookmark.\n");
perror(pathName);
(void) fclose(outfp);
return (NULL);
}
}
return (outfp);
} /* OpenTmpBookmarkFile */
int
SaveBookmarkTable(void)
{
int i;
FILE *outfp;
int nb;
if ((gNumBookmarks < 1) || (gBookmarkTable == NULL))
return (0); /* Nothing to save. */
/* Get a count of live bookmarks. */
for (i=0, nb=0; i<gNumBookmarks; i++) {
if (gBookmarkTable[i].deleted == 0)
nb++;
}
outfp = OpenTmpBookmarkFile(nb);
if (outfp == NULL) {
return (-1);
}
for (i=0; i<gNumBookmarks; i++) {
if (gBookmarkTable[i].deleted == 0) {
if (WriteBmLine(gBookmarkTable + i, outfp, 1) < 0) {
CloseBookmarkFile(outfp);
return (-1);
}
}
}
CloseBookmarkFile(outfp);
if (SwapBookmarkFiles() < 0) {
return (-1);
}
return (0);
} /* SaveBookmarkTable */
/* Saves a Bookmark structure into the bookmarks file. */
int
PutBookmark(Bookmark *bmp, int savePassword)
{
FILE *infp, *outfp;
char line[256];
char bmAbbr[64];
int replaced = 0;
size_t len;
outfp = OpenTmpBookmarkFile(0);
if (outfp == NULL)
return (-1);
(void) STRNCPY(bmAbbr, bmp->bookmarkName);
(void) STRNCAT(bmAbbr, ",");
len = strlen(bmAbbr);
/* This may fail the first time we ever save a bookmark. */
infp = OpenBookmarkFile(NULL);
if (infp != NULL) {
while (FGets(line, sizeof(line), infp) != NULL) {
if (strncmp(line, bmAbbr, len) == 0) {
/* Replace previous entry. */
if (WriteBmLine(bmp, outfp, savePassword) < 0) {
(void) fprintf(stderr, "Could not save bookmark.\n");
perror("reason");
(void) fclose(outfp);
}
replaced = 1;
} else {
if (fprintf(outfp, "%s\n", line) < 0) {
(void) fprintf(stderr, "Could not save bookmark.\n");
perror("reason");
(void) fclose(outfp);
return (-1);
}
}
}
CloseBookmarkFile(infp);
}
if (replaced == 0) {
/* Add it as a new bookmark. */
if (WriteBmLine(bmp, outfp, savePassword) < 0) {
(void) fprintf(stderr, "Could not save bookmark.\n");
perror("reason");
(void) fclose(outfp);
return (-1);
}
}
if (fclose(outfp) < 0) {
(void) fprintf(stderr, "Could not save bookmark.\n");
perror("reason");
return (-1);
}
if (SwapBookmarkFiles() < 0) {
(void) fprintf(stderr, "Could not rename bookmark file.\n");
perror("reason");
return (-1);
}
return (0);
} /* PutBookmark */
/* Tries to generate a bookmark abbreviation based off of the hostname. */
void
DefaultBookmarkName(char *dst, size_t siz, char *src)
{
char str[128];
const char *token;
const char *cp;
(void) STRNCPY(str, src);
/* Pick the first "significant" part of the hostname. Usually
* this is the first word in the name, but if it's something like
* ftp.unl.edu, we would want to choose "unl" and not "ftp."
*/
token = str;
if ((token = strtok(str, ".")) == NULL)
token = str;
else if ((ISTRNEQ(token, "ftp", 3)) || (ISTRNEQ(token, "www", 3))) {
if ((token = strtok(NULL, ".")) == NULL)
token = "";
}
for (cp = token; ; cp++) {
if (*cp == '\0') {
/* Token was all digits, like an IP address perhaps. */
token = "";
}
if (!isdigit((int) *cp))
break;
}
(void) Strncpy(dst, token, siz);
} /* DefaultBookmarkName */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -