9 #define MIN(a, b) ((a) < (b) ? (a) : (b))
10 #define BUFSIZE (1 << 12)
11 #define PAGER "pgmail"
13 static char buf
[BUFSIZE
];
17 static int read_line(char *dst
, int size
)
21 int cur_len
= MIN(len
- cur
, size
- nw
- 1);
22 char *nl
= memchr(buf
+ cur
, '\n', cur_len
);
23 int nr
= nl
? nl
- buf
- cur
+ 1 : cur_len
;
25 memcpy(dst
+ nw
, buf
+ cur
, nr
);
30 if (nl
|| nw
== size
- 1)
33 if ((len
= read(STDIN_FILENO
, buf
, BUFSIZE
)) <= 0)
39 static void till_eol(char *s
)
42 while (*s
&& *s
!= '\r' && *s
!= '\n')
48 static void cmd_page(struct mbox
*mbox
, char *args
)
53 mail
= &mbox
->mails
[0];
55 if (!(pid
= fork())) {
56 char *args
[] = {PAGER
, NULL
};
58 dup2(fds
[0], STDIN_FILENO
);
63 write(fds
[1], mail
->head
, mail
->len
);
65 waitpid(pid
, NULL
, 0);
68 static char *cut_cmd(char *dst
, char *s
)
77 static void cmd_head(struct mbox
*mbox
, char *args
)
80 int n
= MIN(mbox
->n
, 10);
81 for (i
= 0; i
< n
; i
++)
82 if (mbox
->mails
[i
].subject
)
83 till_eol(mbox
->mails
[i
].subject
);
86 static void loop(struct mbox
*mbox
)
90 while (read_line(line
, sizeof(line
)) > 0) {
91 char *args
= cut_cmd(cmd
, line
);
92 int len
= strlen(cmd
);
93 if (!strncmp("header", cmd
, len
))
95 if (!strncmp("page", cmd
, len
))
97 if (!strncmp("quit", cmd
, len
))
99 if (!strncmp("x", cmd
, len
) || !strncmp("exit", cmd
, len
))
104 int main(int argc
, char *argv
[])
108 char *filename
= NULL
;
110 if (!strcmp("-f", argv
[i
]))
111 filename
= argv
[++i
];
113 mbox
= mbox_alloc(filename
);