commit 1628ee23e1202be018894a0d9e0b23f1dd6329a1
parent 109860e2aef53382f2c6c65747f03b95706f3d6c
Author: pancake@localhost.localdomain <unknown>
Date: Fri, 6 Nov 2009 21:13:06 +0100
* Various syntax fixes
* Add LICENSE and HISTORY files
Diffstat:
HISTORY | | | 9 | +++++++++ |
LICENSE | | | 22 | ++++++++++++++++++++++ |
dmc | | | 34 | +++++++++++++++++----------------- |
filter.c | | | 4 | ++-- |
mbox.c | | | 42 | +++++++++++++++++++----------------------- |
pop3.c | | | 3 | +-- |
smtp.c | | | 133 | ++++++++++++++++++++++++++++++++++++++----------------------------------------- |
sock.c | | | 128 | ++++++++++++++++++++++++++++++++++++++++---------------------------------------- |
8 files changed, 198 insertions(+), 177 deletions(-)
diff --git a/HISTORY b/HISTORY
@@ -0,0 +1,9 @@
+dmc history
+===========
+
+dmc was born as a proof of concept for a suckless email client after some
+discussions in the dev@ mailing list of www.suckless.org project.
+
+The first mail with ideas was sent in 2009-10-06.
+
+First usable release (0.1) was released in XXXX-XX-XX
diff --git a/LICENSE b/LICENSE
@@ -0,0 +1,22 @@
+MIT/X Consortium License
+
+© 2009 pancake <pancake at nopcode dot org>
+© 2009 nibble <nibble at gmail dot com>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
diff --git a/dmc b/dmc
@@ -1,6 +1,7 @@
#!/bin/sh
-# dmc - dynamic mail client
-# Copyleft 2009 -- pancake <at> nopcode <dot> org
+# See LICENSE file for copyright and license details.
+#---
+# dmc - dynamic mail client - pancake <at> nopcode <dot> org
VERSION="0.1"
COPYRIGHT="Copyleft -- pancake@nopcode.org"
@@ -41,7 +42,7 @@ start_account_daemons () {
i=$(($i+1))
sleep 1
done
- if [ "$i" = 0 ]; then
+ if [ $i = 0 ]; then
echo "No accounts defined in ~/.dmc/acc"
exit 1
fi
@@ -56,6 +57,7 @@ print_account_template () {
echo "PORT=110"
echo "#SEND=acc-name"
echo "SEND=!msmtp"
+ echo "ONLINE=0"
echo "MAIL=username@domain"
echo "USER='username'"
echo "PASS='password'"
@@ -171,20 +173,18 @@ case "$1" in
"push")
for a in ~/.dmc/acc/* ; do
. $a
- if [ -d ~/.dmc/box/${NAME}/out ]; then
- for b in ~/.dmc/box/${NAME}/out/* ; do
- if [ -f "$b" ]; then
- send_message "$b"
- if [ $? = 0 ]; then
- echo "Mail sent. local copy moved to ~/.dmc/box/${NAME}/sent"
- mkdir -p ~/.dmc/box/${NAME}/sent
- mv $b ~/.dmc/box/${NAME}/sent
- else
- echo "There was an error while sending the mail"
- fi
- fi
- done
- fi
+ [ ! -d ~/.dmc/box/${NAME}/out ] && continue
+ for b in ~/.dmc/box/${NAME}/out/* ; do
+ [ ! -f "$b" ] && continue
+ send_message "$b"
+ if [ $? = 0 ]; then
+ echo "Mail sent. local copy moved to ~/.dmc/box/${NAME}/sent"
+ mkdir -p ~/.dmc/box/${NAME}/sent
+ mv $b ~/.dmc/box/${NAME}/sent
+ else
+ echo "There was an error sending the mail"
+ fi
+ done
done
;;
"pull")
diff --git a/filter.c b/filter.c
@@ -10,12 +10,12 @@ int main(int argc, char **argv) {
for (i = 0; i < argc; i++)
if (!strcmp (argv[i], "-h")) {
- fprintf (stderr, "Usage: %s [-h] [headers | :] [-e] [new headers] < mail\n", argv[0]);
+ printf ("Usage: %s [-h] [headers | :] [-e] [new headers] < mail\n", argv[0]);
return 1;
} else if (!strcmp (argv[i], "-e"))
edit = i;
for (i = 0; i < argc; i++) {
- strncpy(argv2[i], argv[i], 1023);
+ strncpy (argv2[i], argv[i], 1023);
argv2[i][1023] = '\0';
}
memset (b, '\0', 1024);
diff --git a/mbox.c b/mbox.c
@@ -8,13 +8,14 @@
FILE *fd;
static char word[1024];
-static void mbox_ls () {
+// XXX maybe so many [1024] stuff. can this cause truncated mails?
+static void mbox_ls() {
char b[1024], from[1024], subject[1024], date[1024], *ptr;
int m = 0, headers = 1;
b[1023] = '\0';
fseek (fd, 0, SEEK_SET);
- while(fgets (b, 1023, fd)) {
+ while (fgets (b, 1023, fd)) {
if (b[0]=='\n') {
if (headers) {
printf ("%i %s %s %s\n", m++, from, date, subject);
@@ -48,23 +49,21 @@ static void mbox_ls () {
}
}
-static void mbox_cat (int idx, int body) {
+static void mbox_cat(int idx, int body) {
char b[1024];
int m = 0, headers = 1;
b[1023] = '\0';
fseek (fd, 0, SEEK_SET);
- while(fgets (b, 1023, fd)) {
+ while (fgets (b, 1023, fd)) {
if (b[0]=='\n') {
- if (headers)
- headers = 0;
- else {
+ if (!headers) {
fgets (b, 1023, fd);
if (!memcmp (b, "From ", 5)) {
headers = 1;
m++;
}
- }
+ } else headers = 0;
}
if (m == idx && (headers || body))
fputs (b, stdout);
@@ -76,36 +75,34 @@ static void mbox_rm (int idx) {
int m = 0, i = 0, headers = 1, size;
fseek(fd, 0, SEEK_END);
- size = ftell(fd);
+ size = ftell (fd);
if (!(buf = malloc (size)))
return;
b[1023] = '\0';
fseek (fd, 0, SEEK_SET);
- while(fgets (b, 1023, fd)) {
+ while (fgets (b, 1023, fd)) {
if (b[0]=='\n') {
- if (headers)
- headers = 0;
- else {
+ if (!headers) {
fgets (b, 1023, fd);
if (!memcmp (b, "From ", 5)) {
headers = 1;
if (++m == idx) {
- strcpy(buf + i, "\n");
+ strcpy (buf + i, "\n");
i += 1;
}
}
- }
+ } else headers = 0;
}
if (m != idx) {
- strcpy(buf + i, b);
- i += strlen(b);
+ strcpy (buf + i, b);
+ i += strlen (b);
}
}
fseek (fd, 0, SEEK_SET);
fwrite (buf, 1, i, fd);
fflush (fd);
- ftruncate (fileno(fd), i);
- free(buf);
+ ftruncate (fileno (fd), i);
+ free (buf);
}
static char *getword () {
@@ -146,10 +143,9 @@ int main (int argc, char **argv) {
if (argc>1) {
fd = fopen (argv[1], "r+");
if (fd != NULL) {
- ret = 0;
while (doword (getword ()));
- fclose (fd);
- } else fprintf (stderr, "Cannot open %s\n", argv[1]);
- } else fprintf (stderr, "Usage: dmc-mbox [mbox-file] 2> body > fifo < input\n");
+ ret = fclose (fd);
+ } else printf ("Cannot open %s\n", argv[1]);
+ } else printf ("Usage: dmc-mbox [mbox-file] 2> body > fifo < input\n");
return ret;
}
diff --git a/pop3.c b/pop3.c
@@ -107,8 +107,7 @@ int main(int argc, char **argv) {
if (argc>3)
ssl = (*argv[3]=='1');
if (sock_connect (argv[1], atoi (argv[2]), ssl) >= 0) {
- ret = 0;
- atexit (sock_close);
+ ret = atexit (sock_close);
waitreply (1);
while (doword (getword ()));
} else printf ("Cannot connect to %s %d\n", argv[1], atoi(argv[2]));
diff --git a/smtp.c b/smtp.c
@@ -11,81 +11,76 @@
#define BIND_4_COMPAT
static int resmx(const char *domain) {
- char host[NS_MAXDNAME+1];
- char last[NS_MAXDNAME+1];
- typedef union {
- HEADER head;
- char buf[PACKETSZ];
- } pkt_t;
- unsigned char buf[PACKETSZ];
- unsigned char *rrptr;
- pkt_t *pkt = (pkt_t *)buf;
- int querylen, len, n, exprc;
- int rrtype, antrrtype;
- int rrpayloadsz;
+ char host[NS_MAXDNAME+1];
+ char last[NS_MAXDNAME+1];
+ typedef union {
+ HEADER head;
+ char buf[PACKETSZ];
+ } pkt_t;
+ unsigned char buf[PACKETSZ];
+ unsigned char *rrptr;
+ pkt_t *pkt = (pkt_t *)buf;
+ int querylen, len, n, exprc;
+ int rrtype, antrrtype;
+ int rrpayloadsz;
- querylen = res_querydomain(domain, "", C_IN,T_MX,
- (void*)&buf, PACKETSZ);
+ querylen = res_querydomain (domain, "", C_IN,T_MX, (void*)&buf, PACKETSZ);
- if (ntohs(pkt->head.rcode) == NOERROR) {
- n = ntohs(pkt->head.ancount);
- if (n==0) {
- fprintf(stderr, "No MX found\n");
- return 1;
- }
+ if (ntohs (pkt->head.rcode) == NOERROR) {
+ n = ntohs (pkt->head.ancount);
+ if (n==0) {
+ fprintf(stderr, "No MX found\n");
+ return 1;
+ }
- /* expand DNS query */
- len = dn_expand( buf,
- buf+querylen, buf+sizeof(HEADER),
- host, sizeof(host));
+ /* expand DNS query */
+ len = dn_expand (buf,
+ buf + querylen, buf + sizeof(HEADER),
+ host, sizeof (host));
+ if (len<0) {
+ fprintf (stderr, "No MX found\n");
+ return 1;
+ }
- if (len<0) {
- fprintf(stderr, "No MX found\n");
- return 1;
- }
+ rrptr = buf + len + 4 + sizeof (HEADER);
- rrptr = buf+sizeof(HEADER)+4+len;
-
- while(rrptr < buf+querylen) {
- /* expand NAME resolved */
- exprc = dn_expand(buf,buf+querylen,rrptr,host,sizeof(host));
- if (exprc<0) {
- fprintf(stderr, "No MX found\n");
- return 1;
- }
- rrptr += exprc;
- rrtype = (rrptr[0]<<8|rrptr[1]);
- rrpayloadsz = (rrptr[8]<<8|rrptr[9]);
- rrptr += 10;
- switch(rrtype) {
- /* TODO support for IPv6: case T_AAAA: */
- case T_A:
- if (strcmp(host, last)) {
- printf("%s\n", host);
- if (--n==0) querylen=0;
- }
- break;
- }
- antrrtype = rrtype;
- rrptr += rrpayloadsz;
- }
- } else {
- printf("%s\n", domain);
- //fprintf(stderr, "No MX found\n");
- return 1;
- }
- return 0;
+ while (rrptr < buf+querylen) {
+ /* expand NAME resolved */
+ exprc = dn_expand (buf, buf+querylen, rrptr, host, sizeof (host));
+ if (exprc<0) {
+ fprintf (stderr, "No MX found\n");
+ return 1;
+ }
+ rrptr += exprc;
+ rrtype = (rrptr[0]<<8|rrptr[1]);
+ rrpayloadsz = (rrptr[8]<<8|rrptr[9]);
+ rrptr += 10;
+ switch (rrtype) {
+ /* TODO support for IPv6: case T_AAAA: */
+ case T_A:
+ if (strcmp (host, last)) {
+ printf ("%s\n", host);
+ if (--n==0) querylen=0;
+ }
+ break;
+ }
+ antrrtype = rrtype;
+ rrptr += rrpayloadsz;
+ }
+ } else {
+ printf ("%s\n", domain);
+ return 1;
+ }
+ return 0;
}
int main(int argc, char **argv) {
- if (argc>1) {
- char *ch = strchr(argv[1], '@');
- if (ch) return resmx(ch+1);
- else {
- /* do the daemon stuff here */
- fprintf(stderr, "TODO: SMTP protocol not yet implemented\n");
- }
- } else printf("Usage: dmc-smtp [user@domain] # Get MX for domain\n"
- "Usage: dmc-smtp fifo | nc host 25 > fifo\n");
- return 0;
+ if (argc>1) {
+ char *ch = strchr(argv[1], '@');
+ if (!ch) {
+ /* do the daemon stuff here */
+ fprintf (stderr, "TODO: SMTP protocol not yet implemented\n");
+ } else return resmx (ch+1);
+ } else printf ("Usage: dmc-smtp [user@domain] # Get MX for domain\n");
+ return 0;
}
diff --git a/sock.c b/sock.c
@@ -20,91 +20,91 @@ static int fd = -1;
int sock_ssl (int enable) {
#if HAVE_SSL
- int err;
- if (ssl) {
- // challenge, check cert, etc..
- sfd = SSL_new (ctx);
- SSL_set_fd (sfd, fd);
- err = SSL_connect (sfd);
- /* TODO: check cert */
- SSL_set_accept_state (sfd);
- }
- ssl = enable;
- return 1;
+ int err;
+ if (ssl) {
+ // challenge, check cert, etc..
+ sfd = SSL_new (ctx);
+ SSL_set_fd (sfd, fd);
+ err = SSL_connect (sfd);
+ /* TODO: check cert */
+ SSL_set_accept_state (sfd);
+ }
+ ssl = enable;
+ return 1;
#else
- return 0;
+ return 0;
#endif
}
// TODO: cleanup all those fd=-1
-int sock_connect (const char *host, int port, int ssl) {
- struct sockaddr_in sa;
- struct hostent *he;
- int s = socket (AF_INET, SOCK_STREAM, 0);
- sock_ssl (ssl);
- fd = -1;
- if (s != -1) {
- fd = s;
- memset (&sa, 0, sizeof (sa));
- sa.sin_family = AF_INET;
- he = (struct hostent *)gethostbyname (host);
- if (he != (struct hostent*)0) {
- sa.sin_addr = *((struct in_addr *)he->h_addr);
- sa.sin_port = htons (port);
- if (connect (fd, (const struct sockaddr*)&sa, sizeof (struct sockaddr)))
- fd = -1;
- } else fd = -1;
- if (fd == -1)
- close (s);
- } else fd = -1;
- return fd;
+int sock_connect(const char *host, int port, int ssl) {
+ struct sockaddr_in sa;
+ struct hostent *he;
+ int s = socket (AF_INET, SOCK_STREAM, 0);
+ sock_ssl (ssl);
+ fd = -1;
+ if (s != -1) {
+ fd = s;
+ memset (&sa, 0, sizeof (sa));
+ sa.sin_family = AF_INET;
+ he = (struct hostent *)gethostbyname (host);
+ if (he != (struct hostent*)0) {
+ sa.sin_addr = *((struct in_addr *)he->h_addr);
+ sa.sin_port = htons (port);
+ if (connect (fd, (const struct sockaddr*)&sa, sizeof (struct sockaddr)))
+ fd = -1;
+ } else fd = -1;
+ if (fd == -1)
+ close (s);
+ } else fd = -1;
+ return fd;
}
static int sock_ready() {
- struct pollfd fds[1];
- fds[0].fd = fd;
- fds[0].events = POLLIN|POLLPRI;
- fds[0].revents = POLLNVAL|POLLHUP|POLLERR;
- return poll((struct pollfd *)&fds, 1, 10);
+ struct pollfd fds[1];
+ fds[0].fd = fd;
+ fds[0].events = POLLIN|POLLPRI;
+ fds[0].revents = POLLNVAL|POLLHUP|POLLERR;
+ return poll((struct pollfd *)&fds, 1, 10);
}
-void sock_close () {
+void sock_close() {
#if HAVE_SSL
- SSL_free (sfd);
+ SSL_free (sfd);
#endif
- close (fd);
+ close (fd);
}
-int sock_write (const char *str) {
+int sock_write(const char *str) {
#if HAVE_SSL
- if (ssl)
- return SSL_write (sfd, str, strlen(str));
- else
+ if (ssl)
+ return SSL_write (sfd, str, strlen(str));
+ else
#endif
- return write (fd, str, strlen(str));
+ return write (fd, str, strlen(str));
}
-int sock_printf (const char *fmt, ...) {
- va_list ap;
- int ret = -1;
- char buf[1024];
- va_start (ap, fmt);
- vsnprintf (buf, 1023, fmt, ap);
- // XXX check len
- ret = sock_write (buf);
- va_end (ap);
- return ret;
+int sock_printf(const char *fmt, ...) {
+ va_list ap;
+ int ret = -1;
+ char buf[1024];
+ va_start (ap, fmt);
+ vsnprintf (buf, 1023, fmt, ap);
+ // XXX check len
+ ret = sock_write (buf);
+ va_end (ap);
+ return ret;
}
int sock_read (char *buf, int len) {
- int ret;
+ int ret;
#if HAVE_SSL
- if (ssl)
- ret = SSL_read (sfd, buf, len);
- else
+ if (ssl)
+ ret = SSL_read (sfd, buf, len);
+ else
#endif
- ret = read (fd, buf, len);
- if (ret>0)
- buf[ret] = '\0';
- return ret;
+ ret = read (fd, buf, len);
+ if (ret>0)
+ buf[ret] = '\0';
+ return ret;
}