#include #include #include #include #include #include "HsFFI.h" struct session; struct session *c_newSession(); void c_freeSession(struct session*); struct page; struct page *c_initialReferer(); void *c_fetchURL(struct session*, char*, struct page*, char*); //struct page **c_fetchURLs(struct session*, struct page*, char**); // FIXME segfaults. void c_freePage(struct page*); char *c_renderDoc(struct session*, struct page*); char **c_extractLinks(struct page*); char **c_docLinksAndRendering(struct session*, struct page*); // FIXME segfaults. void write_links(FILE *dest, char **links) { for (int i = 0; strcmp(links[i], " ") != 0; i++) { fprintf(dest, "%s%c", links[i], (i % 3) == 2 ? '\n' : '\t'); } } int main(int argc, char **argv) { hs_init(&argc, &argv); char *mimes = "text/html text/xml application/xml application/xhtml+xml text/plain"; FILE *fd_ssml = NULL; FILE *fd_links = NULL; int c; opterr = 0; while ((c = getopt(argc, argv, "xs::l::h")) != -1) { switch (c) { case 'x': mimes = "text/xml application/xml application/xhtml+xml text/html text/plain"; break; case 's': fd_ssml = optarg != NULL ? fopen(optarg, "w") : stdout; if (fd_ssml == NULL) { fprintf(stderr, "Failed to open file %s\n", optarg); hs_exit(); return -1; } break; case 'l': fd_links = optarg != NULL ? fopen(optarg, "w") : stdout; if (fd_links == NULL) { fprintf(stderr, "Failed to open file %s\n", optarg); hs_exit(); return -1; } break; case '?': fprintf(stderr, "Invalid flag %c\n\n", optopt); case 'h': fprintf(stderr, "USAGE: rhapsode [FLAGS] URL...\n"); fprintf(stderr, "\t-x\tX(HT)ML\tIndicates to expect an X(HT)ML file.\n"); fprintf(stderr, "\t-s\tsilent/SSML\tWrites SSML to the specified file or stdout.\n"); fprintf(stderr, "\t\t\thttps://xkcd.com/1692/\n"); fprintf(stderr, "\t-l\tlinks\tWrite extracted links to specifed file or stdout as TSV.\n"); fprintf(stderr, "\t-h\thelp\tOutputs this usage information to stderr.\n"); fprintf(stderr, "\t\t\tIf both -s & -l are enabled without an argument, writes to stderr instead.\n"); hs_exit(); return c == 'h' ? 0 : -1; } } if (fd_ssml == stdout && fd_links == stdout) fd_links = stderr; if (fd_ssml == NULL && fd_links == NULL) fd_ssml = stdout; struct session *session = c_newSession(); struct page *referer = c_initialReferer(); for (int i = optind; i < argc; i++) { printf("%s\n", argv[i]); struct page *page = c_fetchURL(session, mimes, referer, argv[i]); char *ssml = c_renderDoc(session, page); char **links = c_extractLinks(page); if (fd_ssml != NULL) fprintf(fd_ssml, "%s\n", ssml); if (fd_links != NULL) write_links(fd_links, links); c_freePage(page); } c_freePage(referer); c_freeSession(session); hs_exit(); }