You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
mblaze/mgenmid.c

127 lines
2.8 KiB
C

#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/time.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"
#include "xpledge.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("profile");
struct message *config = blaze822(f);
xpledge("stdio rpath dns", "");
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"
" ${MBLAZE:-$HOME/.mblaze}/profile\n"
" or add a FQDN to /etc/hosts.\n");
exit(1);
}
struct timeval tp;
gettimeofday(&tp, (struct timezone *)0);
uint64_t rnd1, rnd2;
int rndfd = open("/dev/urandom", O_RDONLY);
if (rndfd >= 0) {
unsigned char rndb[16];
if (read(rndfd, rndb, sizeof rndb) != sizeof rndb)
goto fallback;
close(rndfd);
int i;
for (i = 0, rnd1 = 0; i < 8; i++)
rnd1 = rnd1*256 + rndb[i];
for (i = 0, rnd2 = 0; i < 8; i++)
rnd2 = rnd2*256 + rndb[i+8];
} else {
fallback:
srand48(tp.tv_sec ^ tp.tv_usec ^ getpid());
rnd1 = ((uint64_t)lrand48() << 32) + lrand48();
rnd2 = ((uint64_t)lrand48() << 32) + lrand48();
}
rnd1 ^= ((uint64_t)tp.tv_sec * 1000000LL + tp.tv_usec);
rnd1 |= (1ULL << 63); // set highest bit to force full width
rnd2 |= (1ULL << 63); // set highest bit to force full width
putchar('<');
printb36(rnd1);
putchar('.');
printb36(rnd2);
putchar('@');
fputs(host, stdout);
putchar('>');
putchar('\n');
return 0;
}