ReactOS 0.4.15-dev-7788-g1ad9096
bookmark.c
Go to the documentation of this file.
1/* bookmark.c
2 *
3 * Copyright (c) 1992-2001 by Mike Gleason.
4 * All rights reserved.
5 *
6 */
7
8#include "syshdrs.h"
9
10#include "bookmark.h"
11#include "util.h"
12
13/*
14 * The ~/.ncftp/bookmarks file contains a list of sites
15 * the user wants to remember.
16 *
17 * Unlike previous versions of the program, we now open/close
18 * the file every time we need it; That way we can have
19 * multiple ncftp processes changing the file. There is still
20 * a possibility that two different processes could be modifying
21 * the file at the same time.
22 */
23
25int gLoadedBm = 0;
29
30extern char gOurDirectoryPath[];
31
32/* Converts a pre-loaded Bookmark structure into a RFC 1738
33 * Uniform Resource Locator.
34 */
35void
36BookmarkToURL(BookmarkPtr bmp, char *url, size_t urlsize)
37{
38 char pbuf[32];
39
40 /* //<user>:<password>@<host>:<port>/<url-path> */
41 /* Note that if an absolute path is given,
42 * you need to escape the first entry, i.e. /pub -> %2Fpub
43 */
44 (void) Strncpy(url, "ftp://", urlsize);
45 if (bmp->user[0] != '\0') {
46 (void) Strncat(url, bmp->user, urlsize);
47 if (bmp->pass[0] != '\0') {
48 (void) Strncat(url, ":", urlsize);
49 (void) Strncat(url, "PASSWORD", urlsize);
50 }
51 (void) Strncat(url, "@", urlsize);
52 }
53 (void) Strncat(url, bmp->name, urlsize);
54 if (bmp->port != 21) {
55 (void) sprintf(pbuf, ":%u", (unsigned int) bmp->port);
56 (void) Strncat(url, pbuf, urlsize);
57 }
58 if (bmp->dir[0] == '/') {
59 /* Absolute URL path, must escape first slash. */
60 (void) Strncat(url, "/%2F", urlsize);
61 (void) Strncat(url, bmp->dir + 1, urlsize);
62 (void) Strncat(url, "/", urlsize);
63 } else if (bmp->dir[0] != '\0') {
64 (void) Strncat(url, "/", urlsize);
65 (void) Strncat(url, bmp->dir, urlsize);
66 (void) Strncat(url, "/", urlsize);
67 }
68} /* BookmarkToURL */
69
70
71
72
73void
75{
76 (void) memset(bmp, 0, sizeof(Bookmark));
77
78 bmp->xferType = 'I';
79 bmp->xferMode = 'S'; /* Use FTP protocol default as ours too. */
84 bmp->isUnix = 1;
85 bmp->lastCall = (time_t) 0;
86 bmp->deleted = 0;
87} /* SetBookmarkDefaults */
88
89
90
91
92/* Used when converting hex strings to integral types. */
93static int
95{
96 switch (c) {
97 case '0':
98 case '1':
99 case '2':
100 case '3':
101 case '4':
102 case '5':
103 case '6':
104 case '7':
105 case '8':
106 case '9':
107 return (c - '0');
108 case 'a':
109 case 'b':
110 case 'c':
111 case 'd':
112 case 'e':
113 case 'f':
114 return (c - 'a' + 10);
115 case 'A':
116 case 'B':
117 case 'C':
118 case 'D':
119 case 'E':
120 case 'F':
121 return (c - 'A' + 10);
122
123 }
124 return (-1); /* Error. */
125} /* HexCharToNibble */
126
127
128
129
130
131/* Fills in a Bookmark structure based off of a line from the NcFTP
132 * "bookmarks" file.
133 */
134int
136{
137 char token[128];
138 char pass[128];
139 char *s, *d;
140 char *tokenend;
141 long L;
142 int i;
143 int result;
144 int n, n1, n2;
145
147 s = line;
148 tokenend = token + sizeof(token) - 1;
149 result = -1;
150 for (i=1; ; i++) {
151 if (*s == '\0')
152 break;
153 /* Some tokens may need to have a comma in them. Since this is a
154 * field delimiter, these fields use \, to represent a comma, and
155 * \\ for a backslash. This chunk gets the next token, paying
156 * attention to the escaped stuff.
157 */
158 for (d = token; *s != '\0'; ) {
159 if ((*s == '\\') && (s[1] != '\0')) {
160 if (d < tokenend)
161 *d++ = s[1];
162 s += 2;
163 } else if (*s == ',') {
164 ++s;
165 break;
166 } else if ((*s == '$') && (s[1] != '\0') && (s[2] != '\0')) {
167 n1 = HexCharToNibble(s[1]);
168 n2 = HexCharToNibble(s[2]);
169 if ((n1 >= 0) && (n2 >= 0)) {
170 n = (n1 << 4) | n2;
171 if (d < tokenend)
172 *(unsigned char *)d++ = (unsigned int) n;
173 }
174 s += 3;
175 } else {
176 if (d < tokenend)
177 *d++ = *s;
178 ++s;
179 }
180 }
181 *d = '\0';
182 switch(i) {
183 case 1: (void) STRNCPY(bmp->bookmarkName, token); break;
184 case 2: (void) STRNCPY(bmp->name, token); break;
185 case 3: (void) STRNCPY(bmp->user, token); break;
186 case 4: (void) STRNCPY(bmp->pass, token); break;
187 case 5: (void) STRNCPY(bmp->acct, token); break;
188 case 6: (void) STRNCPY(bmp->dir, token);
189 result = 0; /* Good enough to have these fields. */
190 break;
191 case 7:
192 if (token[0] != '\0')
193 bmp->xferType = (int) token[0];
194 break;
195 case 8:
196 /* Most of the time, we won't have a port. */
197 if (token[0] == '\0')
198 bmp->port = (unsigned int) kDefaultFTPPort;
199 else
200 bmp->port = (unsigned int) atoi(token);
201 break;
202 case 9:
203 (void) sscanf(token, "%lx", &L);
204 bmp->lastCall = (time_t) L;
205 break;
206 case 10: bmp->hasSIZE = atoi(token); break;
207 case 11: bmp->hasMDTM = atoi(token); break;
208 case 12: bmp->hasPASV = atoi(token); break;
209 case 13: bmp->isUnix = atoi(token);
210 result = 3; /* Version 3 had all fields to here. */
211 break;
212 case 14: (void) STRNCPY(bmp->lastIP, token); break;
213 case 15: (void) STRNCPY(bmp->comment, token); break;
214 case 16:
215 case 17:
216 case 18:
217 case 19:
218 break;
219 case 20: bmp->xferMode = token[0];
220 result = 7; /* Version 7 has all fields to here. */
221 break;
222 case 21: bmp->hasUTIME = atoi(token);
223 break;
224 case 22: (void) STRNCPY(bmp->ldir, token);
225 result = 8; /* Version 8 has all fields to here. */
226 break;
227 default:
228 result = 99; /* Version >8 ? */
229 goto done;
230 }
231 }
232done:
233
234 /* Decode password, if it was base-64 encoded. */
235 if (strncmp(bmp->pass, kPasswordMagic, kPasswordMagicLen) == 0) {
237 (void) STRNCPY(bmp->pass, pass);
238 }
239 return (result);
240} /* ParseHostLine */
241
242
243
244
245void
247{
248 if (fp != NULL)
249 (void) fclose(fp);
250} /* CloseBookmarkFile */
251
252
253
254
255
256int
258{
259 char line[512];
260
261 while (FGets(line, sizeof(line), fp) != NULL) {
262 if (ParseHostLine(line, bmp) >= 0)
263 return (0);
264 }
265 return (-1);
266} /* GetNextBookmark */
267
268
269
270
271/* Opens a NcFTP 2.x or 3.x style bookmarks file, and sets the file pointer
272 * so that it is ready to read the first data line.
273 */
274FILE *
275OpenBookmarkFile(int *numBookmarks0)
276{
277 char pathName[256], path2[256];
278 char line[256];
279 FILE *fp;
280 int version;
281 int numBookmarks;
282 Bookmark junkbm;
283
284 if (gOurDirectoryPath[0] == '\0')
285 return NULL; /* Don't create in root directory. */
286 (void) OurDirectoryPath(pathName, sizeof(pathName), kBookmarkFileName);
287 fp = fopen(pathName, FOPEN_READ_TEXT);
288 if (fp == NULL) {
289 /* See if it exists under the old name. */
291 if (rename(path2, pathName) == 0) {
292 /* Rename succeeded, now open it. */
293 fp = fopen(pathName, FOPEN_READ_TEXT);
294 if (fp == NULL)
295 return NULL;
296 }
297 return NULL; /* Okay to not have one yet. */
298 }
299
300 (void) _chmod(pathName, 00600);
301 if (FGets(line, sizeof(line), fp) == NULL) {
302 (void) fprintf(stderr, "%s: invalid format.\n", pathName);
303 (void) fclose(fp);
304 return NULL;
305 }
306
307 /* Sample line we're looking for:
308 * "NcFTP bookmark-file version: 8"
309 */
310 version = -1;
311 (void) sscanf(line, "%*s %*s %*s %d", &version);
313 if (version < 0) {
314 (void) fprintf(stderr, "%s: invalid format, or bad version.\n", pathName);
315 (void) fclose(fp);
316 return NULL;
317 }
318 (void) STRNCPY(path2, pathName);
319 (void) sprintf(line, ".v%d", version);
321 (void) rename(pathName, path2);
322 (void) fprintf(stderr, "%s: old version.\n", pathName);
323 (void) fclose(fp);
324 return NULL;
325 }
326
327 /* Sample line we're looking for:
328 * "Number of entries: 28" or "# # # 1"
329 */
330 numBookmarks = -1;
331
332 /* At the moment, we can't trust the number stored in the
333 * file. It's there for future use.
334 */
335 if (FGets(line, sizeof(line), fp) == NULL) {
336 (void) fprintf(stderr, "%s: invalid format.\n", pathName);
337 (void) fclose(fp);
338 return NULL;
339 }
340
341 if (numBookmarks0 == (int *) 0) {
342 /* If the caller doesn't care how many bookmarks are *really*
343 * in the file, then we can return now.
344 */
345 return(fp);
346 }
347
348 /* Otherwise, we have to read through the whole file because
349 * unfortunately the header line can't be trusted.
350 */
351 for (numBookmarks = 0; ; numBookmarks++) {
352 if (GetNextBookmark(fp, &junkbm) < 0)
353 break;
354 }
355
356 /* Now we have to re-open and re-position the file.
357 * We don't use rewind() because it doesn't always work.
358 * This introduces a race condition, but the bookmark
359 * functionality wasn't designed to be air-tight.
360 */
362 fp = fopen(pathName, FOPEN_READ_TEXT);
363 if (fp == NULL)
364 return (NULL);
365 if (FGets(line, sizeof(line), fp) == NULL) {
366 (void) fprintf(stderr, "%s: invalid format.\n", pathName);
367 (void) fclose(fp);
368 return NULL;
369 }
370
371 if (FGets(line, sizeof(line), fp) == NULL) {
372 (void) fprintf(stderr, "%s: invalid format.\n", pathName);
373 (void) fclose(fp);
374 return NULL;
375 }
376
377 /* NOW we're done. */
378 *numBookmarks0 = numBookmarks;
379 return (fp);
380} /* OpenBookmarkFile */
381
382
383
384
385/* Looks for a saved bookmark by the abbreviation given. */
386int
387GetBookmark(const char *const bmabbr, Bookmark *bmp)
388{
389 FILE *fp;
390 char line[512];
391 Bookmark byHostName;
392 Bookmark byHostAbbr;
393 Bookmark byBmAbbr;
394 size_t byBmNameFlag = 0;
395 size_t byBmAbbrFlag = 0;
396 size_t byHostNameFlag = 0;
397 size_t byHostAbbrFlag = 0;
398 int result = -1;
399 int exactMatch = 0;
400 size_t bmabbrLen;
401 char *cp;
402
404 if (fp == NULL)
405 return (-1);
406
407 bmabbrLen = strlen(bmabbr);
408 while (FGets(line, sizeof(line), fp) != NULL) {
409 if (ParseHostLine(line, bmp) < 0)
410 continue;
411 if (ISTREQ(bmp->bookmarkName, bmabbr)) {
412 /* Exact match, done. */
413 byBmNameFlag = bmabbrLen;
414 exactMatch = 1;
415 break;
416 } else if (ISTRNEQ(bmp->bookmarkName, bmabbr, bmabbrLen)) {
417 /* Remember this one, it matched an abbreviated
418 * bookmark name.
419 */
420 byBmAbbr = *bmp;
421 byBmAbbrFlag = bmabbrLen;
422 } else if (ISTREQ(bmp->name, bmabbr)) {
423 /* Remember this one, it matched a full
424 * host name.
425 */
426 byHostName = *bmp;
427 byHostNameFlag = bmabbrLen;
428 } else if ((cp = strchr(bmp->name, '.')) != NULL) {
429 /* See if it matched part of the hostname. */
430 if (ISTRNEQ(bmp->name, "ftp", 3)) {
431 cp = cp + 1;
432 } else if (ISTRNEQ(bmp->name, "www", 3)) {
433 cp = cp + 1;
434 } else {
435 cp = bmp->name;
436 }
437 if (ISTRNEQ(cp, bmabbr, bmabbrLen)) {
438 /* Remember this one, it matched a full
439 * host name.
440 */
441 byHostAbbr = *bmp;
442 byHostAbbrFlag = bmabbrLen;
443 }
444 }
445 }
446
447 if (gBookmarkMatchMode == 0) {
448 /* Only use a bookmark when the exact
449 * bookmark name was used.
450 */
451 if (exactMatch != 0) {
452 result = 0;
453 }
454 } else {
455 /* Pick the best match, if any. */
456 if (byBmNameFlag != 0) {
457 /* *bmp is already set. */
458 result = 0;
459 } else if (byBmAbbrFlag != 0) {
460 result = 0;
461 *bmp = byBmAbbr;
462 } else if (byHostNameFlag != 0) {
463 result = 0;
464 *bmp = byHostName;
465 } else if (byHostAbbrFlag != 0) {
466 result = 0;
467 *bmp = byHostAbbr;
468 }
469 }
470
471 if (result != 0)
472 memset(bmp, 0, sizeof(Bookmark));
473
475 return (result);
476} /* GetBookmark */
477
478
479
480
481static int
482BookmarkSortProc(const void *a, const void *b)
483{
484 return (ISTRCMP((*(Bookmark *)a).bookmarkName, (*(Bookmark *)b).bookmarkName));
485} /* BookmarkSortProc */
486
487
488
489static int
490BookmarkSearchProc(const void *key, const void *b)
491{
492 return (ISTRCMP((char *) key, (*(Bookmark *)b).bookmarkName));
493} /* BookmarkSearchProc */
494
495
496
499{
501} /* SearchBookmarkTable */
502
503
504
505
506void
508{
509 if ((gBookmarkTable == NULL) || (gNumBookmarks < 2))
510 return;
511
512 /* Sorting involves swapping entire Bookmark structures.
513 * Normally the proper thing to do is to use an array
514 * of pointers to Bookmarks and sort them, but even
515 * these days a large bookmark list can be sorted in
516 * the blink of an eye.
517 */
519} /* SortBookmarks */
520
521
522
523int
525{
526 int i, nb;
527 FILE *infp;
528
529 infp = OpenBookmarkFile(&nb);
530 if (infp == NULL) {
531 nb = 0;
532 }
533 if ((nb != gNumBookmarks) && (gBookmarkTable != NULL)) {
534 /* Re-loading the table from disk. */
535 gBookmarkTable = (Bookmark *) realloc(gBookmarkTable, (size_t) (nb + 1) * sizeof(Bookmark));
536 memset(gBookmarkTable, 0, (nb + 1) * sizeof(Bookmark));
537 } else {
538 gBookmarkTable = calloc((size_t) (nb + 1), (size_t) sizeof(Bookmark));
539 }
540
541 if (gBookmarkTable == NULL) {
542 CloseBookmarkFile(infp);
543 return (-1);
544 }
545
546 for (i=0; i<nb; i++) {
547 if (GetNextBookmark(infp, gBookmarkTable + i) < 0) {
548 break;
549 }
550 }
552
553 CloseBookmarkFile(infp);
555 return (0);
556} /* LoadBookmarkTable */
557
558
559
560
561/* Some characters need to be escaped so the file is editable and can
562 * be parsed correctly the next time it is read.
563 */
564static char *
565BmEscapeTok(char *dst, size_t dsize, char *src)
566{
567 char *dlim = dst + dsize - 1;
568 char *dst0 = dst;
569 int c;
570
571 while ((c = *src) != '\0') {
572 src++;
573 if ((c == '\\') || (c == ',') || (c == '$')) {
574 /* These need to be escaped. */
575 if ((dst + 1) < dlim) {
576 *dst++ = '\\';
577 *dst++ = c;
578 }
579 } else if (!isprint(c)) {
580 /* Escape non-printing characters. */
581 if ((dst + 2) < dlim) {
582 (void) sprintf(dst, "$%02x", c);
583 dst += 3;
584 }
585 } else {
586 if (dst < dlim)
587 *dst++ = c;
588 }
589 }
590 *dst = '\0';
591 return (dst0);
592} /* BmEscapeTok */
593
594
595
596
597/* Converts a Bookmark into a text string, and writes it to the saved
598 * bookmarks file.
599 */
600static int
601WriteBmLine(Bookmark *bmp, FILE *outfp, int savePassword)
602{
603 char tok[256];
604 char pass[160];
605
606 if (fprintf(outfp, "%s", bmp->bookmarkName) < 0) return (-1) ;/*1*/
607 if (fprintf(outfp, ",%s", BmEscapeTok(tok, sizeof(tok), bmp->name)) < 0) return (-1) ;/*2*/
608 if (fprintf(outfp, ",%s", BmEscapeTok(tok, sizeof(tok), bmp->user)) < 0) return (-1) ;/*3*/
609 if ((bmp->pass[0] != '\0') && (savePassword == 1)) {
611 ToBase64(pass + kPasswordMagicLen, bmp->pass, strlen(bmp->pass), 1);
612 if (fprintf(outfp, ",%s", pass) < 0) return (-1) ;/*4*/
613 } else {
614 if (fprintf(outfp, ",%s", "") < 0) return (-1) ;/*4*/
615 }
616 if (fprintf(outfp, ",%s", BmEscapeTok(tok, sizeof(tok), bmp->acct)) < 0) return (-1) ;/*5*/
617 if (fprintf(outfp, ",%s", BmEscapeTok(tok, sizeof(tok), bmp->dir)) < 0) return (-1) ;/*6*/
618 if (fprintf(outfp, ",%c", bmp->xferType) < 0) return (-1) ;/*7*/
619 if (fprintf(outfp, ",%u", (unsigned int) bmp->port) < 0) return (-1) ;/*8*/
620 if (fprintf(outfp, ",%lu", (unsigned long) bmp->lastCall) < 0) return (-1) ;/*9*/
621 if (fprintf(outfp, ",%d", bmp->hasSIZE) < 0) return (-1) ;/*10*/
622 if (fprintf(outfp, ",%d", bmp->hasMDTM) < 0) return (-1) ;/*11*/
623 if (fprintf(outfp, ",%d", bmp->hasPASV) < 0) return (-1) ;/*12*/
624 if (fprintf(outfp, ",%d", bmp->isUnix) < 0) return (-1) ;/*13*/
625 if (fprintf(outfp, ",%s", bmp->lastIP) < 0) return (-1) ;/*14*/
626 if (fprintf(outfp, ",%s", BmEscapeTok(tok, sizeof(tok), bmp->comment)) < 0) return (-1) ;/*15*/
627 if (fprintf(outfp, ",%s", "") < 0) return (-1) ;/*16*/
628 if (fprintf(outfp, ",%s", "") < 0) return (-1) ;/*17*/
629 if (fprintf(outfp, ",%s", "") < 0) return (-1) ;/*18*/
630 if (fprintf(outfp, ",%s", "") < 0) return (-1) ;/*19*/
631 if (fprintf(outfp, ",%c", bmp->xferMode) < 0) return (-1) ;/*20*/
632 if (fprintf(outfp, ",%d", bmp->hasUTIME) < 0) return (-1) ;/*21*/
633 if (fprintf(outfp, ",%s", BmEscapeTok(tok, sizeof(tok), bmp->ldir)) < 0) return (-1) ;/*22*/
634 if (fprintf(outfp, "\n") < 0) return (-1) ;
635 if (fflush(outfp) < 0) return (-1);
636 return (0);
637} /* WriteBmLine */
638
639
640
641static int
643{
644 char pidStr[32];
645 char pathName[256], path2[256];
646
648 (void) OurDirectoryPath(pathName, sizeof(pathName), kTmpBookmarkFileName);
649 (void) sprintf(pidStr, "-%u.txt", (unsigned int) getpid());
650 (void) STRNCAT(pathName, pidStr);
651
652 (void) remove(path2);
653 if (rename(pathName, path2) < 0) {
654 return (-1);
655 }
656 return (0);
657} /* SwapBookmarkFiles */
658
659
660
661
662
663
664/* Saves a Bookmark structure into the bookmarks file. */
665FILE *
667{
668 FILE *outfp;
669 char pidStr[32];
670 char pathName[256], path2[256];
671
672 if (gOurDirectoryPath[0] == '\0')
673 return (NULL); /* Don't create in root directory. */
674
676 (void) OurDirectoryPath(pathName, sizeof(pathName), kTmpBookmarkFileName);
677 (void) sprintf(pidStr, "-%u.txt", (unsigned int) getpid());
678 (void) STRNCAT(pathName, pidStr);
679
680 outfp = fopen(pathName, FOPEN_WRITE_TEXT);
681 if (outfp == NULL) {
682 (void) fprintf(stderr, "Could not save bookmark.\n");
683 perror(pathName);
684 return (NULL);
685 }
686 (void) _chmod(pathName, 00600);
687 if (nb > 0) {
688 if (fprintf(outfp, "NcFTP bookmark-file version: %d\nNumber of bookmarks: %d\n", kBookmarkVersion, nb) < 0) {
689 (void) fprintf(stderr, "Could not save bookmark.\n");
690 perror(pathName);
691 (void) fclose(outfp);
692 return (NULL);
693 }
694 } else {
695 if (fprintf(outfp, "NcFTP bookmark-file version: %d\nNumber of bookmarks: ??\n", kBookmarkVersion) < 0) {
696 (void) fprintf(stderr, "Could not save bookmark.\n");
697 perror(pathName);
698 (void) fclose(outfp);
699 return (NULL);
700 }
701 }
702
703 return (outfp);
704} /* OpenTmpBookmarkFile */
705
706
707
708
709int
711{
712 int i;
713 FILE *outfp;
714 int nb;
715
716 if ((gNumBookmarks < 1) || (gBookmarkTable == NULL))
717 return (0); /* Nothing to save. */
718
719 /* Get a count of live bookmarks. */
720 for (i=0, nb=0; i<gNumBookmarks; i++) {
721 if (gBookmarkTable[i].deleted == 0)
722 nb++;
723 }
724 outfp = OpenTmpBookmarkFile(nb);
725 if (outfp == NULL) {
726 return (-1);
727 }
728
729 for (i=0; i<gNumBookmarks; i++) {
730 if (gBookmarkTable[i].deleted == 0) {
731 if (WriteBmLine(gBookmarkTable + i, outfp, 1) < 0) {
732 CloseBookmarkFile(outfp);
733 return (-1);
734 }
735 }
736 }
737 CloseBookmarkFile(outfp);
738 if (SwapBookmarkFiles() < 0) {
739 return (-1);
740 }
741 return (0);
742} /* SaveBookmarkTable */
743
744
745
746/* Saves a Bookmark structure into the bookmarks file. */
747int
748PutBookmark(Bookmark *bmp, int savePassword)
749{
750 FILE *infp, *outfp;
751 char line[256];
752 char bmAbbr[64];
753 int replaced = 0;
754 size_t len;
755
756 outfp = OpenTmpBookmarkFile(0);
757 if (outfp == NULL)
758 return (-1);
759
760 (void) STRNCPY(bmAbbr, bmp->bookmarkName);
761 (void) STRNCAT(bmAbbr, ",");
762 len = strlen(bmAbbr);
763
764 /* This may fail the first time we ever save a bookmark. */
765 infp = OpenBookmarkFile(NULL);
766 if (infp != NULL) {
767 while (FGets(line, sizeof(line), infp) != NULL) {
768 if (strncmp(line, bmAbbr, len) == 0) {
769 /* Replace previous entry. */
770 if (WriteBmLine(bmp, outfp, savePassword) < 0) {
771 (void) fprintf(stderr, "Could not save bookmark.\n");
772 perror("reason");
773 (void) fclose(outfp);
774 }
775 replaced = 1;
776 } else {
777 if (fprintf(outfp, "%s\n", line) < 0) {
778 (void) fprintf(stderr, "Could not save bookmark.\n");
779 perror("reason");
780 (void) fclose(outfp);
781 return (-1);
782 }
783 }
784 }
785 CloseBookmarkFile(infp);
786 }
787
788 if (replaced == 0) {
789 /* Add it as a new bookmark. */
790 if (WriteBmLine(bmp, outfp, savePassword) < 0) {
791 (void) fprintf(stderr, "Could not save bookmark.\n");
792 perror("reason");
793 (void) fclose(outfp);
794 return (-1);
795 }
796 }
797
798 if (fclose(outfp) < 0) {
799 (void) fprintf(stderr, "Could not save bookmark.\n");
800 perror("reason");
801 return (-1);
802 }
803
804 if (SwapBookmarkFiles() < 0) {
805 (void) fprintf(stderr, "Could not rename bookmark file.\n");
806 perror("reason");
807 return (-1);
808 }
809 return (0);
810} /* PutBookmark */
811
812
813
814
815/* Tries to generate a bookmark abbreviation based off of the hostname. */
816void
817DefaultBookmarkName(char *dst, size_t siz, char *src)
818{
819 char str[128];
820 const char *token;
821 const char *cp;
822
823 (void) STRNCPY(str, src);
824
825 /* Pick the first "significant" part of the hostname. Usually
826 * this is the first word in the name, but if it's something like
827 * ftp.unl.edu, we would want to choose "unl" and not "ftp."
828 */
829 token = str;
830 if ((token = strtok(str, ".")) == NULL)
831 token = str;
832 else if ((ISTRNEQ(token, "ftp", 3)) || (ISTRNEQ(token, "www", 3))) {
833 if ((token = strtok(NULL, ".")) == NULL)
834 token = "";
835 }
836 for (cp = token; ; cp++) {
837 if (*cp == '\0') {
838 /* Token was all digits, like an IP address perhaps. */
839 token = "";
840 }
841 if (!isdigit((int) *cp))
842 break;
843 }
844 (void) Strncpy(dst, token, siz);
845} /* DefaultBookmarkName */
#define STRNCAT(d, s)
Definition: Strn.h:48
char * Strncat(char *const, const char *const, const size_t)
Definition: Strncat.c:13
char * Strncpy(char *const, const char *const, const size_t)
Definition: Strncpy.c:11
#define isdigit(c)
Definition: acclib.h:68
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define isprint(c)
Definition: acclib.h:73
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
char * strtok(char *String, const char *Delimiters)
Definition: utclib.c:338
char * strchr(const char *String, int ch)
Definition: utclib.c:501
#define STRNCPY(dst, src, n)
Definition: rdesktop.h:168
BookmarkPtr gBookmarkTable
Definition: bookmark.c:28
void CloseBookmarkFile(FILE *fp)
Definition: bookmark.c:246
int SaveBookmarkTable(void)
Definition: bookmark.c:710
int GetNextBookmark(FILE *fp, Bookmark *bmp)
Definition: bookmark.c:257
static int BookmarkSortProc(const void *a, const void *b)
Definition: bookmark.c:482
int ParseHostLine(char *line, BookmarkPtr bmp)
Definition: bookmark.c:135
FILE * OpenBookmarkFile(int *numBookmarks0)
Definition: bookmark.c:275
void SetBookmarkDefaults(BookmarkPtr bmp)
Definition: bookmark.c:74
static int HexCharToNibble(int c)
Definition: bookmark.c:94
int GetBookmark(const char *const bmabbr, Bookmark *bmp)
Definition: bookmark.c:387
void DefaultBookmarkName(char *dst, size_t siz, char *src)
Definition: bookmark.c:817
FILE * OpenTmpBookmarkFile(int nb)
Definition: bookmark.c:666
int LoadBookmarkTable(void)
Definition: bookmark.c:524
static int BookmarkSearchProc(const void *key, const void *b)
Definition: bookmark.c:490
int gNumBookmarks
Definition: bookmark.c:27
BookmarkPtr SearchBookmarkTable(const char *key)
Definition: bookmark.c:498
int PutBookmark(Bookmark *bmp, int savePassword)
Definition: bookmark.c:748
void BookmarkToURL(BookmarkPtr bmp, char *url, size_t urlsize)
Definition: bookmark.c:36
int gBookmarkMatchMode
Definition: bookmark.c:26
static char * BmEscapeTok(char *dst, size_t dsize, char *src)
Definition: bookmark.c:565
static int WriteBmLine(Bookmark *bmp, FILE *outfp, int savePassword)
Definition: bookmark.c:601
char gOurDirectoryPath[]
Definition: util.c:17
int gLoadedBm
Definition: bookmark.c:25
void SortBookmarks(void)
Definition: bookmark.c:507
static int SwapBookmarkFiles(void)
Definition: bookmark.c:642
Bookmark gBm
Definition: bookmark.c:24
#define kOldBookmarkFileName
Definition: bookmark.h:40
#define kBookmarkFileName
Definition: bookmark.h:37
#define kTmpBookmarkFileName
Definition: bookmark.h:39
#define kBookmarkVersion
Definition: bookmark.h:32
#define kBookmarkMinVersion
Definition: bookmark.h:33
#define realloc
Definition: debug_ros.c:6
#define NULL
Definition: types.h:112
static const WCHAR version[]
Definition: asmname.c:66
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
__kernel_time_t time_t
Definition: linux.h:252
GLdouble s
Definition: gl.h:2039
GLdouble n
Definition: glext.h:7729
GLenum src
Definition: glext.h:6340
const GLubyte * c
Definition: glext.h:8905
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLenum GLenum dst
Definition: glext.h:6340
GLenum GLsizei len
Definition: glext.h:6722
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
GLuint64EXT * result
Definition: glext.h:11304
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat token
Definition: glfuncs.h:210
_CRTIMP void __cdecl perror(_In_opt_z_ const char *_ErrMsg)
#define stderr
Definition: stdio.h:100
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
_Check_return_opt_ _CRTIMP int __cdecl fflush(_Inout_opt_ FILE *_File)
_Check_return_ _CRTIMP FILE *__cdecl fopen(_In_z_ const char *_Filename, _In_z_ const char *_Mode)
_Check_return_opt_ _CRTIMP int __cdecl fclose(_Inout_ FILE *_File)
_Check_return_ _CRTIMP int __cdecl sscanf(_In_z_ const char *_Src, _In_z_ _Scanf_format_string_ const char *_Format,...)
_Check_return_ int __cdecl atoi(_In_z_ const char *_Str)
#define d
Definition: ke_i.h:81
#define c
Definition: ke_i.h:80
POINT cp
Definition: magnifier.c:59
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define ISTRCMP
Definition: util.h:28
#define ISTREQ(a, b)
Definition: util.h:33
#define ISTRNEQ(a, b, s)
Definition: util.h:34
void ToBase64(void *dst0, const void *src0, size_t n, int terminate)
Definition: util.c:83
char * OurDirectoryPath(char *const dst, const size_t siz, const char *const fname)
Definition: util.c:486
void FromBase64(void *dst0, const void *src0, size_t n, int terminate)
Definition: util.c:128
#define kPasswordMagic
Definition: util.h:47
#define kPasswordMagicLen
Definition: util.h:48
#define sprintf(buf, format,...)
Definition: sprintf.c:55
BITMAP bmp
Definition: alphablend.c:62
static const WCHAR url[]
Definition: encode.c:1432
static const WCHAR path2[]
Definition: path.c:29
int remove
Definition: msacm.c:1366
#define FOPEN_READ_TEXT
Definition: syshdrs.h:82
#define FOPEN_WRITE_TEXT
Definition: syshdrs.h:83
#define kCommandAvailabilityUnknown
Definition: ncftp.h:379
#define kDefaultFTPPort
Definition: ncftp.h:312
char * FGets(char *, size_t, FILE *)
Definition: util.c:111
#define L(x)
Definition: ntvdm.h:50
#define calloc
Definition: rosglue.h:14
int n2
Definition: dwarfget.c:147
int n1
Definition: dwarfget.c:147
const WCHAR * str
_Check_return_ _CRTIMP int __cdecl _chmod(_In_z_ const char *_Filename, _In_ int _Mode)
_Check_return_ int __cdecl rename(_In_z_ const char *_OldFilename, _In_z_ const char *_NewFilename)
#define memset(x, y, z)
Definition: compat.h:39
void __cdecl qsort(_Inout_updates_bytes_(_NumOfElements *_SizeOfElements) void *_Base, _In_ size_t _NumOfElements, _In_ size_t _SizeOfElements, _In_ int(__cdecl *_PtFuncCompare)(const void *, const void *))
Definition: copy.c:22
Definition: parser.c:49
Definition: pbuf.h:79
#define bsearch
pass
Definition: typegen.h:25
#define getpid
Definition: wintirpc.h:52