Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
/*
2
 * Mailbox checking code by Robert J. Gibson, adapted for PD ksh by
3
 * John R. MacMillan
4
 */
5
 
6
#include "config.h"
7
 
8
#ifdef KSH
9
#include "sh.h"
10
#include "ksh_stat.h"
11
#include "ksh_time.h"
12
 
13
#define MBMESSAGE	"you have mail in $_"
14
 
15
typedef struct mbox {
16
	struct mbox    *mb_next;	/* next mbox in list */
17
	char	       *mb_path;	/* path to mail file */
18
	char	       *mb_msg;		/* to announce arrival of new mail */
19
	time_t		mb_mtime;	/* mtime of mail file */
20
} mbox_t;
21
 
22
/*
23
 * $MAILPATH is a linked list of mboxes.  $MAIL is a treated as a
24
 * special case of $MAILPATH, where the list has only one node.  The
25
 * same list is used for both since they are exclusive.
26
 */
27
 
28
static mbox_t	*mplist;
29
static mbox_t	mbox;
30
static time_t	mlastchkd;	/* when mail was last checked */
31
static time_t	mailcheck_interval;
32
 
33
static void     munset      ARGS((mbox_t *mlist)); /* free mlist and mval */
34
static mbox_t * mballoc     ARGS((char *p, char *m)); /* allocate a new mbox */
35
static void     mprintit    ARGS((mbox_t *mbp));
36
 
37
void
38
mcheck()
39
{
40
	register mbox_t	*mbp;
41
	time_t		 now;
42
	struct tbl	*vp;
43
	struct stat	 stbuf;
44
 
45
	now = time((time_t *) 0);
46
	if (mlastchkd == 0)
47
		mlastchkd = now;
48
	if (now - mlastchkd >= mailcheck_interval) {
49
		mlastchkd = now;
50
 
51
		if (mplist)
52
			mbp = mplist;
53
		else if ((vp = global("MAIL")) && (vp->flag & ISSET))
54
			mbp = &mbox;
55
		else
56
			mbp = NULL;
57
 
58
		while (mbp) {
59
			if (mbp->mb_path && stat(mbp->mb_path, &stbuf) == 0
60
			    && S_ISREG(stbuf.st_mode))
61
			{
62
				if (stbuf.st_size
63
				    && mbp->mb_mtime != stbuf.st_mtime
64
				    && stbuf.st_atime <= stbuf.st_mtime)
65
					mprintit(mbp);
66
				mbp->mb_mtime = stbuf.st_mtime;
67
			} else {
68
				/*
69
				 * Some mail readers remove the mail
70
				 * file if all mail is read.  If file
71
				 * does not exist, assume this is the
72
				 * case and set mtime to zero.
73
				 */
74
				mbp->mb_mtime = 0;
75
			}
76
			mbp = mbp->mb_next;
77
		}
78
	}
79
}
80
 
81
void
82
mcset(interval)
83
	long interval;
84
{
85
	mailcheck_interval = interval;
86
}
87
 
88
void
89
mbset(p)
90
	register char	*p;
91
{
92
	struct stat	stbuf;
93
 
94
	if (mbox.mb_msg)
95
		afree((void *)mbox.mb_msg, APERM);
96
	if (mbox.mb_path)
97
		afree((void *)mbox.mb_path, APERM);
98
	/* Save a copy to protect from export (which munges the string) */
99
	mbox.mb_path = str_save(p, APERM);
100
	mbox.mb_msg = NULL;
101
	if (p && stat(p, &stbuf) == 0 && S_ISREG(stbuf.st_mode))
102
		mbox.mb_mtime = stbuf.st_mtime;
103
	else
104
		mbox.mb_mtime = 0;
105
}
106
 
107
void
108
mpset(mptoparse)
109
	register char	*mptoparse;
110
{
111
	register mbox_t	*mbp;
112
	register char	*mpath, *mmsg, *mval;
113
	char *p;
114
 
115
	munset( mplist );
116
	mplist = NULL;
117
	mval = str_save(mptoparse, APERM);
118
	while (mval) {
119
		mpath = mval;
120
		if ((mval = strchr(mval, PATHSEP)) != NULL) {
121
			*mval = '\0', mval++;
122
		}
123
		/* POSIX/bourne-shell say file%message */
124
		for (p = mpath; (mmsg = strchr(p, '%')); ) {
125
			/* a literal percent? (POSIXism) */
126
			if (mmsg[-1] == '\\') {
127
				/* use memmove() to avoid overlap problems */
128
				memmove(mmsg - 1, mmsg, strlen(mmsg) + 1);
129
				p = mmsg + 1;
130
				continue;
131
			}
132
			break;
133
		}
134
		/* at&t ksh says file?message */
135
		if (!mmsg && !Flag(FPOSIX))
136
			mmsg = strchr(mpath, '?');
137
		if (mmsg) {
138
			*mmsg = '\0';
139
			mmsg++;
140
		}
141
		mbp = mballoc(mpath, mmsg);
142
		mbp->mb_next = mplist;
143
		mplist = mbp;
144
	}
145
}
146
 
147
static void
148
munset(mlist)
149
register mbox_t	*mlist;
150
{
151
	register mbox_t	*mbp;
152
 
153
	while (mlist != NULL) {
154
		mbp = mlist;
155
		mlist = mbp->mb_next;
156
		if (!mlist)
157
			afree((void *)mbp->mb_path, APERM);
158
		afree((void *)mbp, APERM);
159
	}
160
}
161
 
162
static mbox_t *
163
mballoc(p, m)
164
	char	*p;
165
	char	*m;
166
{
167
	struct stat	stbuf;
168
	register mbox_t	*mbp;
169
 
170
	mbp = (mbox_t *)alloc(sizeof(mbox_t), APERM);
171
	mbp->mb_next = NULL;
172
	mbp->mb_path = p;
173
	mbp->mb_msg = m;
174
	if (stat(mbp->mb_path, &stbuf) == 0 && S_ISREG(stbuf.st_mode))
175
		mbp->mb_mtime = stbuf.st_mtime;
176
	else
177
		mbp->mb_mtime = 0;
178
	return(mbp);
179
}
180
 
181
static void
182
mprintit( mbp )
183
mbox_t	*mbp;
184
{
185
	struct tbl	*vp;
186
 
187
	/* Ignore setstr errors here (arbitrary) */
188
	setstr((vp = local("_", FALSE)), mbp->mb_path, KSH_RETURN_ERROR);
189
 
190
	shellf("%s\n", substitute(mbp->mb_msg ? mbp->mb_msg : MBMESSAGE, 0));
191
 
192
	unset(vp, 0);
193
}
194
#endif /* KSH */