• R/O
  • SSH
  • HTTPS

ogup: 提交


Commit MetaInfo

修訂43 (tree)
時間2021-12-08 02:47:57
作者mateuszviste

Log Message

menu entries "0" are also checked for self-referencing links + minor refactorizations

Change Summary

差異

--- trunk/gopherjoker/glist.c (revision 42)
+++ trunk/gopherjoker/glist.c (revision 43)
@@ -63,6 +63,23 @@
6363 }
6464
6565
66+/* allocate a gopherlist node with host:port filled in */
67+struct gopherlist *glist_node_alloc(const char *host, unsigned short port) {
68+ struct gopherlist *node;
69+
70+ /* alloc struct */
71+ node = calloc(1, sizeof(struct gopherlist) + strlen(host) + 1);
72+
73+ /* fill in fields */
74+ if (node != NULL) {
75+ strcpy(node->fqdn, host);
76+ node->port = port;
77+ }
78+
79+ return(node);
80+}
81+
82+
6683 /* add new host to glist, unless said host:port pair already exists there.
6784 * returns pointer to the new (or already existing) struct. NULL on error. */
6885 struct gopherlist *glist_addnewhostport(struct gopherlist **glist, const char *newhost, unsigned short newport, time_t failedsince) {
@@ -72,18 +89,17 @@
7289 node = glist_findhostport(*glist, newhost, newport);
7390 if (node != NULL) return(node);
7491
75- /* add it */
76- node = calloc(1, sizeof(struct gopherlist) + strlen(newhost));
92+ /* create new node */
93+ node = glist_node_alloc(newhost, newport);
7794 if (node == NULL) return(NULL);
78- /* */
79- strcpy(node->fqdn, newhost);
80- node->port = newport;
95+
96+ /* fill failedsince */
8197 node->failedsince = failedsince;
82- node->prev = NULL;
83- node->next = *glist;
84- if (*glist != NULL) (*glist)->prev = node;
85- *glist = node;
86- return(*glist);
98+
99+ /* attach the newly created node to glist */
100+ glist_node_chain(glist, node);
101+
102+ return(node);
87103 }
88104
89105
@@ -95,17 +111,23 @@
95111 }
96112
97113
98-struct gopherlist *glist_node_unchain(struct gopherlist *glist, struct gopherlist *node) {
114+/* insert node into a glist */
115+void glist_node_chain(struct gopherlist **glist, struct gopherlist *node) {
116+ node->prev = NULL;
117+ node->next = *glist;
118+ if (*glist != NULL) (*glist)->prev = node;
119+ *glist = node;
120+}
121+
122+
123+void glist_node_unchain(struct gopherlist **glist, struct gopherlist *node) {
99124 if (node->prev == NULL) {
100- glist = node->next;
101- glist->prev = NULL;
102- return(glist);
125+ *glist = node->next;
126+ if (*glist != NULL) (*glist)->prev = NULL;
127+ } else {
128+ node->prev->next = node->next;
129+ if (node->next != NULL) node->next->prev = node->prev;
103130 }
104- node->prev->next = node->next;
105- if (node->next != NULL) {
106- node->next->prev = node->prev;
107- }
108- return(glist);
109131 }
110132
111133
--- trunk/gopherjoker/glist.h (revision 42)
+++ trunk/gopherjoker/glist.h (revision 43)
@@ -29,6 +29,9 @@
2929
3030 struct gopherlist *glist_findhostport(struct gopherlist *glist, const char *host, const unsigned short port);
3131
32+/* allocate a gopherlist node with host:port filled in */
33+struct gopherlist *glist_node_alloc(const char *host, unsigned short port);
34+
3235 /* add new host to glist, unless said host:port pair already exists there.
3336 * returns pointer to the new (or already existing) struct. NULL on error. */
3437 struct gopherlist *glist_addnewhostport(struct gopherlist **glist, const char *newhost, unsigned short newport, time_t failedsince);
@@ -35,8 +38,11 @@
3538
3639 void glist_node_free(struct gopherlist **node);
3740
38-struct gopherlist *glist_node_unchain(struct gopherlist *glist, struct gopherlist *node);
41+/* insert node into a glist */
42+void glist_node_chain(struct gopherlist **glist, struct gopherlist *node);
3943
44+void glist_node_unchain(struct gopherlist **glist, struct gopherlist *node);
45+
4046 struct gopherlist *glist_node_dup(struct gopherlist *node);
4147
4248 #endif
--- trunk/gopherjoker/gopherjoker.c (revision 42)
+++ trunk/gopherjoker/gopherjoker.c (revision 43)
@@ -54,12 +54,19 @@
5454 #define TTLINIT 64
5555 #define CHECKPERIOD (3600 * 24)
5656 #define CHECKPERIOD_FAST (3600 * 2)
57-#define NOJOB_SLEEP 10 /* how long to sleep if there is nothing to do */
57+#define NOJOB_SLEEP 60 /* how long to sleep if there is nothing to do */
5858
5959 static int WAITPERIOD = WAITPERIOD_DEFAULT;
6060 static int SAVEPERIOD = SAVEPERIOD_DEFAULT;
6161
6262
63+struct gopher_entry {
64+ char host[128];
65+ char selector[128];
66+ unsigned short port;
67+ char itemtype;
68+};
69+
6370 /**************** FUNCTIONS ****************/
6471
6572
@@ -306,43 +313,52 @@
306313 long i;
307314 struct gopherlist *res = NULL;
308315 struct gopherlist *node;
316+ int n;
309317
310318 /* DEBUG */
311- printf("------------------------------------------------\n");
312- for (i = 0; i < menulen; i++) printf("%c", menu[i]);
313- printf("------------------------------------------------\n");
319+ printf("*\t*\t*\t*\t*\t*\t*\n");
320+ n = 0;
321+ for (i = 0; i < menulen; i++) {
322+ printf("%c", menu[i]);
323+ if ((menu[i] == '\n') && (++n >= 8)) break; /* limit debug output to 8 lines */
324+ }
325+ printf("*\t*\t*\t*\t*\t*\t*\n");
314326
315327 /* iterate line by line */
316328 for (i = 0; i < menulen; i++) {
317- if (menu[i] == '1') {
318- char host[64];
319- char selector[128];
320- unsigned short port;
329+ char host[64];
330+ char selector[128];
331+ unsigned short port;
332+ char type;
321333
322- if (gopher_menu_parseline(host, sizeof(host), &port, selector, sizeof(selector), menu + i, menulen - i) == 0) {
323- /* validate host name */
324- if (ishostvalid(host) != 0) continue;
325- /* */
326- node = calloc(1, sizeof(struct gopherlist) + strlen(host));
327- if (node == NULL) {
328- glist_free(res);
329- printf("ERR: OUT OF MEMORY\n");
330- return(NULL);
331- }
332- node->port = port;
333- strcpy(node->fqdn, host);
334- node->next = res;
335- node->selector = strdup(selector);
336- if (res != NULL) res->prev = node;
337- res = node;
338- }
334+ /* skip to next line (unless I only started) */
335+ if (i > 0) {
336+ while ((i < menulen) && (menu[i] != '\n')) i++;
337+ while ((i < menulen) && (menu[i] == '\n')) i++;
339338 }
340- /* skip to next line */
341- for (;;) {
342- i++;
343- if (i >= menulen) break;
344- if (menu[i] == '\n') break;
339+ if (i >= menulen) break;
340+
341+ type = menu[i];
342+
343+ if ((type != '0') && (type != '1')) continue;
344+
345+ if (gopher_menu_parseline(host, sizeof(host), &port, selector, sizeof(selector), menu + i, menulen - i) != 0) continue;
346+
347+ /* validate host name */
348+ if (ishostvalid(host) != 0) continue;
349+
350+ /* alloc a new node */
351+ node = glist_node_alloc(host, port);
352+ if (node == NULL) {
353+ glist_free(res);
354+ printf("ERR: OUT OF MEMORY\n");
355+ return(NULL);
345356 }
357+
358+ /* attach the newly created node to glist */
359+ glist_node_chain(&res, node);
360+
361+ if (menu[i] == '1') node->selector = strdup(selector);
346362 }
347363
348364 return(res);
@@ -406,12 +422,32 @@
406422 }
407423
408424
425+static void mark_server_down(struct gopherlist **glist, const char *host, unsigned short port) {
426+ struct gopherlist *gnode;
409427
428+ gnode = glist_findhostport(*glist, host, port);
429+
430+ if (gnode == NULL) {
431+ printf("INTERNAL ERROR: tried to remove a server that is not found in glist ('%s' + port %u)\n", host, port);
432+ } else if (gnode->failedsince == 0) {
433+ /* server was working at some point in the past, but not anymore */
434+ gnode->failedsince = time(NULL);
435+ gnode->nextcheck = time(NULL) + CHECKPERIOD_FAST;
436+ printf("server %s:%u went down -> flaged as failed since now (%s)\n", gnode->fqdn, gnode->port, epoch2human(gnode->failedsince));
437+ } else if (time(NULL) > gnode->failedsince + MAXFAILTIME) {
438+ /* remove server from the list */
439+ printf("server removed due to long-time failure: %s:%u (failed since %s)\n", gnode->fqdn, gnode->port, epoch2human(gnode->failedsince));
440+ glist_node_unchain(glist, gnode);
441+ glist_node_free(&gnode);
442+ }
443+}
444+
445+
410446 /**************** MAIN ****************/
411447
412448 int main(int argc, char **argv) {
413449 time_t nextaction = 0;
414- time_t nextdbsave = 0;
450+ time_t nextdbsave;
415451 struct gopherlist *glist, *mlist, *gnode;
416452 struct gopherlist *curhost = NULL;
417453 char curhost_ipaddr[64];
@@ -433,6 +469,8 @@
433469 return(1);
434470 }
435471
472+ nextdbsave = time(NULL) + SAVEPERIOD;
473+
436474 /* load db file */
437475 glist = loaddb(dbfile);
438476
@@ -441,7 +479,7 @@
441479
442480 for (;;) {
443481
444- printf("\n\n\n\n--- [%s] ---\n", epoch2human(time(NULL)));
482+ printf("\n\n\n--- [%s] ---\n", epoch2human(time(NULL)));
445483
446484 /* do not browse too fast */
447485 while (time(NULL) < nextaction) sleep(1);
@@ -480,20 +518,7 @@
480518 if (bufflen < 1) { /* fail */
481519 printf("failed\n");
482520 /* if it was about root selector, see if it's time to drop the server */
483- if (curhost->selector == NULL) {
484- gnode = glist_findhostport(glist, curhost->fqdn, curhost->port);
485- if (gnode->failedsince == 0) {
486- /* server was working at some point in the past, but not anymore */
487- gnode->failedsince = time(NULL);
488- gnode->nextcheck = time(NULL) + CHECKPERIOD_FAST;
489- printf("server %s:%u went down -> flaged as failed since now (%s)\n", gnode->fqdn, gnode->port, epoch2human(gnode->failedsince));
490- } else if (time(NULL) > curhost->failedsince + MAXFAILTIME) {
491- /* remove server from the list */
492- printf("server removed due to long-time failure: %s:%u (failed since %s)\n", gnode->fqdn, gnode->port, epoch2human(gnode->failedsince));
493- glist = glist_node_unchain(glist, gnode);
494- glist_node_free(&gnode);
495- }
496- }
521+ if (curhost->selector == NULL) mark_server_down(&glist, curhost->fqdn, curhost->port);
497522 glist_node_free(&curhost);
498523 continue;
499524 }
@@ -504,14 +529,9 @@
504529 mlist = menu2gopherlist(buff, bufflen);
505530 if (mlist == NULL) {
506531 printf("ERR: no entries found in menu\n");
507- /* if no '1' menu entries at all AND this was main menu AND got at least
508- * 64 bytes of data AND it port=70, then add server's IP address */
509- if ((curhost->selector == NULL) && (bufflen >= 64) && (curhost->port == 70)) {
510- printf(" (keeping server in list as %s)\n", curhost_ipaddr);
511- glist_addnewhostport(&glist, curhost_ipaddr, curhost->port, 0);
512- }
532+ /* if it was about root selector, consider lack of entries as a down state */
533+ if (curhost->selector == NULL) mark_server_down(&glist, curhost->fqdn, curhost->port);
513534 /* */
514- glist_free(mlist);
515535 glist_node_free(&curhost);
516536 continue;
517537 }
@@ -527,7 +547,8 @@
527547 if (glist_findhostport(mlist, curhost->fqdn, curhost->port) == NULL) {
528548 printf("ERR: main menu contains no link to self, dropping host:port '%s':%u\n", curhost->fqdn, curhost->port);
529549 gnode = glist_findhostport(glist, curhost->fqdn, curhost->port);
530- glist = glist_node_unchain(glist, gnode);
550+ glist_node_unchain(&glist, gnode);
551+ glist_node_free(&gnode);
531552 glist_node_free(&curhost);
532553 glist_free(mlist);
533554 continue;
@@ -538,6 +559,16 @@
538559 gnode = glist_findhostport(glist, curhost->fqdn, curhost->port);
539560 gnode->failedsince = 0;
540561
562+ /* curate the mlist by removing all entries with a NULL selector (these are not spider-able) */
563+ for (gnode = mlist; gnode != NULL; ) {
564+ struct gopherlist *g = gnode;
565+ gnode = gnode->next;
566+ if (g->selector != NULL) continue;
567+ /* drop the node */
568+ glist_node_unchain(&mlist, g);
569+ glist_node_free(&g);
570+ }
571+
541572 /* choose a random entry from mlist */
542573 gnode = pickrandhostfromlist(mlist);
543574 if (gnode == NULL) {
Show on old repository browser