9 #define MIN(a, b) ((a) < (b) ? (a) : (b))
10 #define MAXLINE (1 << 7)
11 #define BUFSIZE (1 << 12)
12 #define PAGER "pgmail"
14 static char buf
[BUFSIZE
];
18 static int read_line(char *dst
, int size
)
22 int cur_len
= MIN(len
- cur
, size
- nw
- 1);
23 char *nl
= memchr(buf
+ cur
, '\n', cur_len
);
24 int nr
= nl
? nl
- buf
- cur
+ 1 : cur_len
;
26 memcpy(dst
+ nw
, buf
+ cur
, nr
);
31 if (nl
|| nw
== size
- 1)
34 if ((len
= read(STDIN_FILENO
, buf
, BUFSIZE
)) <= 0)
40 static void till_eol(char *s
)
43 while (*s
&& *s
!= '\r' && *s
!= '\n')
49 static char *cut_int(char *dst
, char *s
)
59 static void cmd_page(struct mbox
*mbox
, char *args
)
66 args
= cut_int(num
, args
);
69 if (n
< 0 && n
>= mbox
->n
)
71 mail
= &mbox
->mails
[n
];
74 if (!(pid
= fork())) {
75 char *args
[] = {PAGER
, NULL
};
77 dup2(fds
[0], STDIN_FILENO
);
82 write(fds
[1], mail
->head
, mail
->len
);
84 waitpid(pid
, NULL
, 0);
87 static char *cut_cmd(char *dst
, char *s
)
96 static void cmd_head(struct mbox
*mbox
, char *args
)
99 int n
= MIN(mbox
->n
, 10);
100 for (i
= 0; i
< n
; i
++)
101 if (mbox
->mails
[i
].subject
)
102 till_eol(mbox
->mails
[i
].subject
);
105 static void loop(struct mbox
*mbox
)
109 while (read_line(line
, sizeof(line
)) > 0) {
110 char *args
= cut_cmd(cmd
, line
);
111 int len
= strlen(cmd
);
112 if (!strncmp("header", cmd
, len
))
113 cmd_head(mbox
, args
);
114 if (!strncmp("page", cmd
, len
))
115 cmd_page(mbox
, args
);
116 if (!strncmp("quit", cmd
, len
))
118 if (!strncmp("x", cmd
, len
) || !strncmp("exit", cmd
, len
))
123 int main(int argc
, char *argv
[])
127 char *filename
= NULL
;
129 if (!strcmp("-f", argv
[i
]))
130 filename
= argv
[++i
];
132 mbox
= mbox_alloc(filename
);