diff options
Diffstat (limited to 'src/qbiff.c')
-rw-r--r-- | src/qbiff.c | 141 |
1 files changed, 141 insertions, 0 deletions
diff --git a/src/qbiff.c b/src/qbiff.c new file mode 100644 index 0000000..b9b55bf --- /dev/null +++ b/src/qbiff.c @@ -0,0 +1,141 @@ +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include "hasutmp.h" +#ifdef HASUTMP +#include <utmp.h> +#ifndef UTMP_FILE +#ifdef _PATH_UTMP +#define UTMP_FILE _PATH_UTMP +#else +#define UTMP_FILE "/etc/utmp" +#endif +#endif +#else +#include <utmpx.h> +#endif +#include "stralloc.h" +#include "buffer.h" +#include "open.h" +#include "byte.h" +#include "str.h" +#include "headerbody.h" +#include "hfield.h" +#include "env.h" +#include "exit.h" + +buffer b; +#ifdef HASUTMP +char bufutmp[sizeof(struct utmp) * 16]; +int fdutmp; +#endif +char buftty[1024]; +int fdtty; + +#ifdef HASUTMP +struct utmp ut; +char line[sizeof(ut.ut_line) + 1]; +#else +struct utmpx *ut; +char line[sizeof(ut->ut_line) + 1]; +#endif + +stralloc woof = {0}; +stralloc tofrom = {0}; +stralloc text = {0}; + +void doit(char *s, int n) +{ + if (!stralloc_catb(&text,s,n)) _exit(0); + if (text.len > 78) text.len = 78; +} + +void dobody(stralloc *h) { doit(h->s,h->len); } + +void doheader(stralloc *h) +{ + int i; + + if (hfield_known(h->s,h->len) == H_SUBJECT) { + i = hfield_skipname(h->s,h->len); + doit(h->s + i,h->len - i); + } +} + +void finishheader() { ; } + +int main() +{ + char *user; + char *sender; + char *userext; + struct stat st; + int i; + + if (chdir("/dev") == -1) _exit(0); + + if (!(user = env_get("USER"))) _exit(0); + if (!(sender = env_get("SENDER"))) _exit(0); + if (!(userext = env_get("LOCAL"))) _exit(0); +#ifdef HASUTMP + if (str_len(user) > sizeof(ut.ut_name)) _exit(0); +#else + if (str_len(user) > sizeof(ut->ut_user)) _exit(0); +#endif + + if (!stralloc_copys(&tofrom,"*** TO <")) _exit(0); + if (!stralloc_cats(&tofrom,userext)) _exit(0); + if (!stralloc_cats(&tofrom,"> FROM <")) _exit(0); + if (!stralloc_cats(&tofrom,sender)) _exit(0); + if (!stralloc_cats(&tofrom,">")) _exit(0); + + for (i = 0; i < tofrom.len; ++i) + if ((tofrom.s[i] < 32) || (tofrom.s[i] > 126)) + tofrom.s[i] = '_'; + + if (!stralloc_copys(&text," ")) _exit(0); + if (headerbody(buffer_0,doheader,finishheader,dobody) == -1) _exit(0); + + for (i = 0; i < text.len; ++i) + if ((text.s[i] < 32) || (text.s[i] > 126)) + text.s[i] = '/'; + + if (!stralloc_copys(&woof,"\015\n\007")) _exit(0); + if (!stralloc_cat(&woof,&tofrom)) _exit(0); + if (!stralloc_cats(&woof,"\015\n")) _exit(0); + if (!stralloc_cat(&woof,&text)) _exit(0); + if (!stralloc_cats(&woof,"\015\n")) _exit(0); + +#ifdef HASUTMP + fdutmp = open_read(UTMP_FILE); + if (fdutmp == -1) _exit(0); + buffer_init(&b,read,fdutmp,bufutmp,sizeof(bufutmp)); + + while (buffer_get(&b,&ut,sizeof(ut)) == sizeof(ut)) + if (!str_diffn(ut.ut_name,user,sizeof(ut.ut_name))) { +#else + while ((ut = getutxent()) != 0) + if (ut->ut_type == USER_PROCESS && !str_diffn(ut->ut_user,user,sizeof(ut->ut_user))) { +#endif +#ifdef HASUTMP + byte_copy(line,sizeof(ut.ut_line),ut.ut_line); + line[sizeof(ut.ut_line)] = 0; +#else + byte_copy(line,sizeof(ut->ut_line),ut->ut_line); + line[sizeof(ut->ut_line)] = 0; +#endif + if (line[0] == '/') continue; + if (!line[0]) continue; + if (line[str_chr(line,'.')]) continue; + + fdtty = open_append(line); + if (fdtty == -1) continue; + if (fstat(fdtty,&st) == -1) { close(fdtty); continue; } + if (!(st.st_mode & 0100)) { close(fdtty); continue; } + if (st.st_uid != getuid()) { close(fdtty); continue; } + buffer_init(&b,write,fdtty,buftty,sizeof(buftty)); + buffer_putflush(&b,woof.s,woof.len); + close(fdtty); + } + _exit(0); +} |