]> git.armaanb.net Git - mmenu.git/blob - mmenu.c
2dd8c75bbbdcb342ff7b1ff8b69400170f79f34a
[mmenu.git] / mmenu.c
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <stdbool.h>
4
5 #include <Xm/Text.h>
6 #include <curl/curl.h>
7
8 struct MemoryStruct {
9         char *memory;
10         size_t size;
11 };
12
13 static size_t
14 memback(void *contents, size_t size, size_t nmemb, void *userp)
15 {
16         size_t realsize = size * nmemb;
17         struct MemoryStruct *mem = (struct MemoryStruct *)userp;
18
19         char *ptr = realloc(mem->memory, mem->size + realsize + 1);
20         if(!ptr) {
21                 /* out of memory! */
22                 printf("not enough memory (realloc returned NULL)\n");
23                 return 0;
24         }
25
26         mem->memory = ptr;
27         memcpy(&(mem->memory[mem->size]), contents, realsize);
28         mem->size += realsize;
29         mem->memory[mem->size] = 0;
30
31         return realsize;
32 }
33
34 int
35 main(int argc, char *argv[])
36 {
37         // Get webpage
38         CURL *curl = curl_easy_init();
39         CURLcode res;
40
41         if (!curl) {
42                 fprintf(stderr, "ERROR: Failed to initialize cURL\n");
43                 exit(1);
44         }
45
46         struct MemoryStruct chunk;
47         chunk.memory = malloc(1);  // will be grown as needed by the realloc above
48         chunk.size = 0; // no data at this point
49
50         curl_easy_setopt(curl, CURLOPT_URL,
51                         "https://nobilis.nobles.edu/skyworld/castlemenu.php");
52         curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, memback);
53         curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
54         curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk);
55
56         printf("INFO: Fetching wepage\n");
57         res = curl_easy_perform(curl);
58
59         if (res != CURLE_OK) {
60                 fprintf(stderr,"ERROR: Could not fetch webpage\n%s\n",
61                                 curl_easy_strerror(res));
62                 exit(2);
63         }
64
65         curl_easy_cleanup(curl);
66
67         // Parse HTML
68         printf("INFO: Parsing HTML\n");
69         bool intag = false;
70         char *outp = (char *) malloc(strlen(chunk.memory) + 1); // TODO: Realloc?
71         strcpy(outp, "");
72
73         // Extract text from between HTML tags
74         for (int i = 345; i < strlen(chunk.memory); i++) {
75                 char c = chunk.memory[i];
76                 if (c == '<') intag = true;
77                 if (!intag) strncat(outp, &c, 1);
78                 if (c == '>') intag = false;
79         }
80
81         // Strip empty newlines
82         char *nl = (char *) malloc(strlen(outp));
83         strncpy(nl, "\0", 1);
84         for (int i = 0; i < strlen(outp) - 1; i++) {
85                 if (outp[i] == '\n' && outp[i+1] == '\n') i+=4;
86                 strncat(nl, &outp[i], 1);
87         }
88
89         // Initialize motif
90         Widget             toplevel;
91         XtAppContext       app;
92         Widget             text_w;
93         Arg                args[4];
94
95         XtSetLanguageProc (NULL, NULL, NULL);
96         toplevel = XtVaOpenApplication (&app, "Castle Menu", NULL, 0, &argc, argv,
97                         NULL, sessionShellWidgetClass, NULL);
98
99         // Set textbox settings
100         int n = 0;
101         XtSetArg(args[n], XmNvalue, nl);                    n++;
102         XtSetArg(args[n], XmNeditable, False);              n++;
103         XtSetArg(args[n], XmNcolumns, 80);                  n++;
104         XtSetArg(args[n], XmNcursorPositionVisible, False); n++;
105         text_w = XmCreateScrolledText(toplevel, "text", args, n);
106         free(outp);
107         free(nl);
108
109         // Display everything
110         XtManageChild(text_w);
111         XtRealizeWidget(toplevel);
112         XtAppMainLoop(app);
113 }