/* SPDX-License-Identifier: GPL-3.0-or-later */ /* compile with `clang listgen.c -std=c89 -I/usr/include/libxml2 -lxml2' */ #define _XOPEN_SOURCE 500 #define _XOPEN_SOURCE_EXTENDED 500 #include #include #include #include #include #include #include #include #define SMALL 1024 /* 1.0KiB */ #define BIG 524288 /* 512KiB */ char *files_list[BIG]; char *filename; int i = 0; regex_t regex; int result; void help(char program[]) { fprintf(stderr, "Usage: %s /path/to/xml\n", program); fprintf(stderr, "For example, %s /srv/http/users/*/site-meta.xml\n", program); exit(EXIT_FAILURE); } char* get_child(const char *parent, const char *tag, xmlDocPtr doc, xmlNodePtr node) { /* get the content of a nested element */ static char out[BIG]; xmlNodePtr child_node = NULL; while (node != NULL) { if (!xmlStrcmp(node->name, (const xmlChar *)parent)) { child_node = node->children; break; } else { node = node->next; } } while (child_node != NULL) { if (!xmlStrcmp(child_node->name, (const xmlChar *)tag)) { sprintf(out, "%s", xmlNodeListGetString(doc, child_node->xmlChildrenNode, 1)); return out; } child_node = child_node->next; } return "NOT_FOUND"; } char* get_tag(const char* tag, xmlDocPtr doc, xmlNodePtr node) { /* get the content of an element */ static char out[BIG]; while (node != NULL) { if (!xmlStrcmp(node->name, (const xmlChar *)tag)) { sprintf(out, "%s", xmlNodeListGetString(doc, node->xmlChildrenNode, 1)); return out; } node = node->next; } return "NOT_FOUND"; } const char* gen_xhtml(const char* filename) { /* This function is more close to being the actual main one, it's where the HTML is generated. */ xmlDocPtr source = xmlReadFile(filename, NULL, 0); xmlNodePtr cur = NULL; static char out[BIG]; /* these just check if the file is really messed up */ if (source == NULL) { fprintf(stderr, "failed to parse file\n"); xmlFreeDoc(source); } else { cur = xmlDocGetRootElement(source); } if (cur == NULL) { fprintf(stderr, "empty\n"); xmlFreeDoc(source); exit(EXIT_FAILURE); } if (xmlStrcmp(cur->name, (const xmlChar *) "linklist")) { fprintf(stderr, "%s: root tag must be \n", filename); xmlFreeDoc(source); exit(EXIT_FAILURE); } cur = cur->xmlChildrenNode; strcat(out, "\n" "\n" "\n" " \n" " \n" " \n"); sprintf(out, "%s Midgard Link Directory - %s/", out, get_tag("network", source, cur)); sprintf(out, "%s%s/", out, get_tag("protocol", source, cur)); sprintf(out, "%s%s\n", out, get_tag("category", source, cur)); strcat(out, " \n" " \n" "
\n" "

linkdir

\n"); char *temp = get_tag("network", source, cur); if (!strcmp(temp, "i2p")) { strcat(out, " i2p\n" " tor\n" " ygg\n"); } else if (!strcmp(temp, "tor")) { strcat(out, " i2p\n" " tor\n" " ygg\n"); } else if (!strcmp(temp, "ygg")) { strcat(out, " i2p\n" " tor\n" " ygg\n"); } strcat(out, "
\n" " \n" "\n"); return out; } int add_to_array(const char *fpath, const struct stat *sb, int typeflag, struct FTW *ftwbuf) { result = regcomp(®ex, ".*.xml$", 0); result = regexec(®ex, fpath, 0, NULL, 0); if (!result) { files_list[i] = (char*) malloc (PATH_MAX); sprintf(files_list[i], "%s", fpath); i++; } return EXIT_SUCCESS; } int main(int argc, char *argv[]) { if (argc != 2) { help(argv[0]); } i = 0; nftw(argv[1], add_to_array, 20, 0); int file_count = i; for (i = 0; i < file_count; i++) { printf("[%05d]\t%s\n", i, files_list[i]); printf("%s", gen_xhtml(files_list[i])); } return 0; }