add mgenmid

pull/2/head
Christian Neukirchen 8 years ago
parent 400c6793d6
commit 78fec302cb

@ -1,6 +1,6 @@
CFLAGS=-g -O1 -Wall -Wno-switch -Wextra -fstack-protector-strong -D_FORTIFY_SOURCE=2
ALL = maddr mdeliver mdirs mflag mhdr minc mlist mmime mpick mscan msed mseq mshow msort mthread
ALL = maddr mdeliver mdirs mflag mgenmid mhdr minc mlist mmime mpick mscan msed mseq mshow msort mthread
all: $(ALL)
@ -8,6 +8,7 @@ maddr: maddr.o blaze822.o seq.o rfc2047.o mymemmem.o
mdeliver: mdeliver.o blaze822.o mymemmem.o
mdirs: mdirs.o
mflag: mflag.o blaze822.o seq.o mymemmem.o
mgenmid: mgenmid.o blaze822.o seq.o mymemmem.o
mhdr: mhdr.o blaze822.o seq.o rfc2047.o mymemmem.o
minc: minc.o
mlist: mlist.o

@ -0,0 +1,58 @@
.Dd August 1, 2016
.Dt MGENMID 1
.Os
.Sh NAME
.Nm mgenmid
.Nd generate a Message-ID
.Sh SYNOPSIS
.Nm
.Sh DESCRIPTION
.Nm
generates a fresh Message-ID and prints it.
The Message-ID consists of a timestamp,
a random value,
and a fully qualified domain name.
.Pp
The fully qualified domain name is computed by:
.Bl -enum
.It
Using
.Sq Li "FQDN:"
from
.Pa "~/.santoku/profile"
(if set).
.It
Resolving the current hostname.
.It
Using the host part of the address in
.Sq Li "Local-Mailbox:"
from
.Pa "~/.santoku/profile"
(if set).
.El
.Pp
If these steps don't result in a fully qualified domain name,
.Nm
fails.
.Sh EXIT STATUS
.Ex -std
.Sh SEE ALSO
.Rs
.%A M. Curtin
.%A J. Zawinski
.%D July 1998
.%R draft-ietf-usefor-message-id-01.txt
.%T Recommendations for generating Message IDs
.Re
.Sh AUTHORS
.An Christian Neukirchen Aq Mt chneukirchen@gmail.com
.Sh LICENSE
.Nm
is in the public domain.
.Pp
To the extent possible under law,
the creator of this work
has waived all copyright and related or
neighboring rights to this work.
.Pp
.Lk http://creativecommons.org/publicdomain/zero/1.0/

@ -0,0 +1,115 @@
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <netdb.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include "blaze822.h"
void
printb36(uint64_t x)
{
static char const base36[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
char outbuf[16];
char *o = outbuf + sizeof outbuf;
*o = 0;
do { *--o = base36[x % 36]; } while (x /= 36);
fputs(o, stdout);
}
int main()
{
char hostbuf[1024];
char *host = 0;
char *f = blaze822_home_file(".santoku/profile");
struct message *config = blaze822(f);
if (config) // try FQDN: first
host = blaze822_hdr(config, "fqdn");
if (!host && gethostname(hostbuf, sizeof hostbuf) == 0) {
// termination not posix guaranteed
hostbuf[sizeof hostbuf - 1] = 0;
struct addrinfo hints = { .ai_family = AF_UNSPEC,
.ai_socktype = SOCK_STREAM,
.ai_flags = AI_CANONNAME };
struct addrinfo *info;
if (getaddrinfo(hostbuf, 0, &hints, &info) == 0) {
// sanity checks: no (null), at least one dot,
// doesn't start with localhost.
if (info &&
info->ai_canonname &&
strchr(info->ai_canonname, '.') &&
strncmp(info->ai_canonname, "localhost.", 10) != 0)
host = info->ai_canonname;
}
}
if (!host && config) {
// get address part of Local-Mailbox:
char *disp, *addr;
char *from = blaze822_hdr(config, "local-mailbox");
while (from && (from = blaze822_addr(from, &disp, &addr)))
if (addr) {
host = strchr(addr, '@');
if (host) {
host++;
break;
}
}
}
if (!host) {
fprintf(stderr,
"mgenmid: failed to find a FQDN for the Message-ID.\n"
" Define 'FQDN:' or 'Local-Mailbox:' in ~/.santoku/profile\n"
" or add a FQDN to /etc/hosts.\n");
exit(1);
}
struct timespec tp;
clock_gettime(CLOCK_REALTIME, &tp);
uint64_t rnd;
int rndfd = open("/dev/urandom", O_RDONLY);
if (rndfd >= 0) {
unsigned char rndb[8];
if (read(rndfd, rndb, sizeof rndb) != sizeof rndb)
goto fallback;
close(rndfd);
int i;
for (i = 0, rnd = 0; i < 8; i++)
rnd = rnd*256 + rndb[i];
} else {
fallback:
srand48(tp.tv_sec ^ tp.tv_nsec/1000 ^ getpid());
rnd = (lrand48() << 32) + lrand48();
}
rnd |= (1LL << 63); // set highest bit to force full width
putchar('<');
printb36(((uint64_t)tp.tv_sec << 16) + (tp.tv_nsec >> 16));
putchar('.');
printb36(rnd);
putchar('@');
fputs(host, stdout);
putchar('>');
putchar('\n');
return 0;
}
Loading…
Cancel
Save