4 * Licence: http://www.opensource.org/licenses/bsd-license.php
5 * author: mac@calmar.ws
7 * Modified for use in Conky by Brenden Matthews
10 * scanning from top to bottom on a mbox
11 * The output as follows:
12 * F: FROM_LENGHT S: SUBJECT_LENGHT
13 * (PRINT_MAILS or -n NR times)
25 #define SUBJECT_WIDTH 22
31 struct ring_list *previous;
32 struct ring_list *next;
35 void mbox_scan(char *args, char *output, size_t max_len)
38 int from_width, subject_width, print_mails;
39 char buf[text_buffer_size];
41 char *substr = strstr(args, "-n");
43 if (sscanf(substr, "-n %i", &print_mails) != 1) {
44 print_mails = PRINT_MAILS;
47 print_mails = PRINT_MAILS;
49 substr = strstr(args, "-fw");
51 if (sscanf(substr, "-fw %i", &from_width) != 1) {
52 from_width = FROM_WIDTH;
55 from_width = FROM_WIDTH;
57 substr = strstr(args, "-sw");
59 if (sscanf(substr, "-sw %i", &subject_width) != 1) {
60 subject_width = SUBJECT_WIDTH;
63 subject_width = SUBJECT_WIDTH;
65 char current_mail_spool[text_buffer_size];
66 if (args[strlen(args) - 1] == '"') { // encapsulated with "'s
67 // find first occurrence of "
68 strncpy(current_mail_spool, args, text_buffer_size);
69 char *start = strchr(current_mail_spool, '"') + 1;
70 start[(long)(strrchr(current_mail_spool, '"') - start)] = '\0';
71 strncpy(current_mail_spool, start, text_buffer_size);
73 char *tmp = strtok(args, " ");
76 tmp = strtok(NULL, " ");
81 strncpy(current_mail_spool, start, text_buffer_size);
83 //printf("'%s', %i, %i, %i\n", current_mail_spool, subject_width, from_width, print_mails);
84 if (strlen(current_mail_spool) < 1) {
85 CRIT_ERR("Usage: ${mboxscan [-n <number of messages to print>] [-fw <from width>] [-sw <subject width>] mbox}");
90 if (stat(current_mail_spool, &statbuf)) {
91 CRIT_ERR("can't stat %s: %s", current_mail_spool, strerror(errno));
93 /* end - argument checking */
95 /* build up double-linked ring-list to hold data, while scanning down the mbox */
96 struct ring_list *curr=0, *prev=0, *start=0;
98 for (i = 0; i < print_mails; i++) {
99 curr = (struct ring_list *)malloc(sizeof(struct ring_list));
100 curr->from = (char *)malloc(sizeof(char[from_width + 1]));
101 curr->subject = (char *)malloc(sizeof(char[subject_width + 1]));
102 curr->from[0] = '\0';
103 curr->subject[0] = '\0';
108 curr->previous = prev;
114 /* connect end to start for an endless loop-ring */
115 start->previous = curr;
121 fp = fopen(current_mail_spool, "r");
126 flag = 1; /* frist find a "From " to set it to 0 for header-sarchings */
128 if (fgets(buf, text_buffer_size, fp) == NULL)
131 if (strncmp(buf, "From ", 5) == 0) {
135 while (strchr(buf, '\n') == NULL && !feof(fp))
136 fgets(buf, text_buffer_size, fp);
138 flag = 0; /* in the headers now */
142 if (flag == 1) { /* in the body, so skip */
146 if (buf[0] == '\n') {
147 /* beyond the headers now (empty line), skip until \n */
148 /* then search for new mail ("From ") */
149 while (strchr(buf, '\n') == NULL && !feof(fp))
150 fgets(buf, text_buffer_size, fp);
151 flag = 1; /* in the body now */
155 if ((strncmp(buf, "X-Status: ", 10) == 0)
156 || (strncmp(buf, "Status: R", 9) == 0)) {
158 /* Mail was read or something, so skip that message */
159 flag = 1; /* search for next From */
160 curr->subject[0] = '0';
162 curr = curr->previous; /* (will get current again on new 'From ' finding) */
164 while (strchr(buf, '\n') == NULL && !feof(fp))
165 fgets(buf, text_buffer_size, fp);
169 /* that covers ^From: and ^from: */
170 if (strncmp(buf + 1, "rom: ", 5) == 0) {
173 u = 6; /* no "From: " string needed, so skip */
176 if (buf[u] == '"') { /* no quotes around names */
181 if (buf[u] == '<' && i > 1) { /* some are: From: <foo@bar.com> */
183 curr->from[i] = '\0';
185 while (strchr(buf, '\n') == NULL && !feof(fp))
186 fgets(buf, text_buffer_size, fp);
190 if (buf[u] == '\n') {
191 curr->from[i] = '\0';
195 if (buf[u] == '\0') {
196 curr->from[i] = '\0';
200 if (i >= from_width) {
201 curr->from[i] = '\0';
203 while (strchr(buf, '\n') == NULL && !feof(fp))
204 fgets(buf, text_buffer_size, fp);
208 /* nothing special so just set it */
209 curr->from[i++] = buf[u++];
213 /* that covers ^Subject and ^subject */
214 if (strncmp(buf + 1, "ubject: ", 8) == 0) {
217 u = 9; /* no "Subject: " string needed, so skip */
220 if (buf[u] == '\n') {
221 curr->subject[i] = '\0';
224 if (buf[u] == '\0') {
225 curr->subject[i] = '\0';
228 if (i >= subject_width) {
229 curr->subject[i] = '\0';
232 while (strchr(buf, '\n') == NULL && !feof(fp))
233 fgets(buf, text_buffer_size, fp);
237 /* nothing special so just set it */
238 curr->subject[i++] = buf[u++];
248 while (curr->from[0] != '\0') {
249 snprintf(buf, text_buffer_size, "F: %-*s S: %-*s\n", from_width, curr->from, subject_width, curr->subject);
250 strncat(output, buf, max_len - strlen(output));
251 /* printf("F: %-*s", from_width, curr->from);
252 printf(" S: %-*s\n", subject_width, curr->subject);*/
255 struct ring_list *old = curr;
257 curr = curr->previous;