home *** CD-ROM | disk | FTP | other *** search
- /*
- * msave.c
- *
- * Copyright (c) 1993 Zik Saleeba <zik@zikzak.apana.org.au>
- *
- * This is an implementation of saved message viewing.
- * This implementation may be freely copied, modified, and
- * redistributed, provided that this comment is retained.
- */
-
- /* $Id: msave.c,v 1.1 1997/10/26 07:31:25 lukeh Exp $ */
-
- #include "common.h"
- #include "msend.h"
-
-
- #define STARTBUFSIZE 16384
-
-
- static FILE *msgfile;
- static char *text;
- static int textsize;
- static int bufsize;
- static char *(*textindex)[];
- static int nummsgs;
- static char savepath[PATH_MAX+1];
-
-
- /*
- * open, lock and read the file. Don't unlock here
- */
-
- void read_file(homedir)
- char *homedir;
- {
- int bytes;
-
- /* initialise the text buffer */
- text = malloc(STARTBUFSIZE);
- if (text == NULL) {
- fprintf(stderr, "Out of memory\n");
- exit(1);
- }
- bufsize = STARTBUFSIZE;
- textsize = 0;
- *text = '\0';
-
- savepath[PATH_MAX] = '\0';
- #ifdef SAVE_PATH
- {
- struct passwd *pwd;
- pwd = getpwuid(getuid());
- if (pwd == NULL) {
- fprintf(stderr, "You don't exist - go away.");
- exit(1);
- }
- strncpy(savepath, SAVE_PATH, PATH_MAX);
- strncat(savepath, "/", PATH_MAX);
- strncat(savepath, pwd->pw_name, PATH_MAX);
- }
- #else
- /* find the home directory */
- if (homedir == NULL) {
- homedir = (char *)getenv("HOME");
- if (homedir == NULL) {
- /* try the password file */
- struct passwd *pwd;
- pwd = getpwuid(getuid());
- if (pwd == NULL) {
- fprintf(stderr, "You don't exist - go away.");
- exit(1);
- }
- homedir = pwd->pw_dir;
- }
- }
- strncpy(savepath, homedir, PATH_MAX);
- strncat(savepath, "/.message", PATH_MAX);
- #endif
-
- /* open the message file */
- msgfile = fopen(savepath, "r+");
- if (msgfile == NULL)
- return; /* nothing in it */
-
- /* lock the file */
- #ifdef USE_LOCKFILES
- if (lock_file(savepath)) {
- fprintf(stderr, "Can't lock message file.\n");
- exit(1);
- }
- #else
- # ifdef USE_LOCKF
- lockf(fileno(msgfile), F_LOCK, 0);
- # else
- flock(fileno(msgfile), LOCK_EX);
- # endif
- #endif
-
- /* read in the entire text */
- do {
- bytes = fread(text+textsize, 1, bufsize-textsize, msgfile);
- if (bytes >= bufsize-textsize) {
- /* enlarge buffer and get more */
- textsize += bytes;
- bufsize *= 2;
- text = realloc(text, bufsize);
- if (text == NULL) {
- fprintf(stderr, "Out of memory\n");
- #ifdef USE_LOCKFILES
- unlock_file(savepath);
- #endif
- exit(1);
- }
- }
- else if (bytes > 0) {
- /* just store what we've got */
- textsize += bytes;
- }
- } while (bytes >= bufsize-textsize);
- *(text+textsize) = '\0'; /* null terminate */
- }
-
-
- /*
- * split the text into message-sized chunks
- */
-
- void index_text()
- {
- char *pos;
- int msgcount;
-
- /* count the messages */
- nummsgs = 0;
-
- if (!text) return;
-
- pos = text;
- while ( (pos = (char *)STRSTR(pos, MESSAGE_SEP)) != NULL) {
- nummsgs++;
- pos++;
- }
-
- /* allocate the index array */
- textindex = (char *(*)[])malloc(sizeof(char *) * nummsgs);
-
- /* fill in the index array and null terminate each message */
- pos = text;
- msgcount = 0;
- while ( (pos = (char *)STRSTR(pos, MESSAGE_SEP)) != NULL) {
- (*textindex)[msgcount++] = pos+strlen(MESSAGE_SEP);
- *pos++ = '\0';
- }
- }
-
-
- char *message_was_unread(msgno)
- int msgno;
- {
- char *pos;
-
- /* find "Unread" string */
- pos = (*textindex)[msgno] + 10;
- while (*pos == '*') /* skip '*'s */
- pos++;
- while (*pos == ' ') /* skip ' 's */
- pos++;
-
- if (strncmp(pos, "Unread message from", 19) == 0)
- return pos-2;
- else
- return NULL;
- }
-
-
- /*
- * display messages and mark them as read
- */
-
- void display_message(msgno)
- int msgno;
- {
- char *pos;
-
- /* display it */
- printf("%s\n", (*textindex)[msgno]);
-
- /* mark as read */
- if ( (pos = message_was_unread(msgno)) != NULL) {
- strncpy(pos, " A message arrived at", 21);
- fseek(msgfile, (long)pos - (long)text, SEEK_SET);
- fprintf(msgfile, " A message arrived at");
- }
- }
-
-
- void write_shorter(savemsgs)
- int savemsgs;
- {
- int msgcount;
-
- if (msgfile == NULL)
- return;
-
- if (nummsgs > savemsgs) {
- /* must shorten */
- rewind(msgfile);
- for (msgcount = nummsgs - savemsgs; msgcount < nummsgs; msgcount++)
- fprintf(msgfile, "%s%s", MESSAGE_SEP, (*textindex)[msgcount]);
- fflush(msgfile);
- ftruncate(fileno(msgfile), ftell(msgfile));
- }
- }
-
-
- void closeup()
- {
- if (msgfile) {
- fclose(msgfile);
- #ifdef USE_LOCKFILES
- unlock_file(savepath);
- #endif
- if (text) {
- free(text);
- free(textindex);
- }
- }
- }
-
-
- void last_message(showmsgs, savemsgs)
- int showmsgs;
- int savemsgs;
- {
- int msgcount;
- int first;
-
- read_file(NULL);
- index_text();
-
- /* choose 'all' by default */
- if (showmsgs == 0)
- first = nummsgs - 5;
- else {
- first = nummsgs - showmsgs;
- }
- if (first < 0)
- first = 0;
-
- /* display */
- for (msgcount = first; msgcount < nummsgs; msgcount++)
- display_message(msgcount);
-
- write_shorter(savemsgs);
- closeup();
- }
-
-
- void unread_message(savemsgs)
- int savemsgs;
- {
- int msgcount;
-
- read_file(NULL);
- index_text();
-
- for (msgcount = 0; msgcount < nummsgs; msgcount++) {
- if (message_was_unread(msgcount) != NULL)
- display_message(msgcount);
- }
-
- write_shorter(savemsgs);
- closeup();
- }
-
-
- int check_unread()
- {
- int msgcount;
- int numunread;
-
- read_file(NULL);
- index_text();
-
- /* how many unread messages are there? */
- numunread = 0;
- for (msgcount = 0; msgcount < nummsgs; msgcount++) {
- if (message_was_unread(msgcount) != NULL)
- numunread++;
- }
-
- /* display what we've found */
- if (numunread > 0) {
- printf("You have %d unread message%s from:",
- numunread, (numunread > 1) ? "s" : "");
- for (msgcount = 0; msgcount < nummsgs; msgcount++) {
- if (message_was_unread(msgcount) != NULL) {
- char *frompos = (char *)STRSTR((*textindex)[msgcount],
- "From: ");
- if (frompos != NULL) {
- putchar(' ');
- frompos += 6;
- while ( *frompos != ' ' &&
- *frompos != '\n' &&
- *frompos != '\0' )
- putchar(*frompos++);
- }
- }
- }
- printf(" (\"%s -u\" to read)\n", prog);
- }
-
- closeup();
- return (numunread == 0) ? 1 : 0;
- }
-
-
- void makeshort(savemsgs)
- int savemsgs;
- {
- read_file(NULL);
- index_text();
- write_shorter(savemsgs);
- closeup();
- }
-
-
- void expire(savemsgs)
- int savemsgs;
- {
- struct passwd *user;
-
- /* give a nasty message if we're not root */
- if (geteuid() != 0) {
- fprintf(stderr, "Only root can expire other people's messages.\n");
- exit(1);
- }
-
- /* set default messages */
- if (savemsgs == 0)
- savemsgs = 20;
-
- /* expire */
- while ( (user = getpwent()) != NULL) {
- read_file(user->pw_dir);
- index_text();
- if (nummsgs > 0) {
- /* bother to expire */
- write_shorter(savemsgs);
- }
- closeup();
- }
- }
-