View | Details | Raw Unified | Return to bug 79232
Collapse All | Expand All

(-)Makefile (+1 lines)
Lines 3-7 Link Here
3
3
4
PROG=	comsat
4
PROG=	comsat
5
MAN=	comsat.8
5
MAN=	comsat.8
6
WARNS?=	6
6
7
7
.include <bsd.prog.mk>
8
.include <bsd.prog.mk>
(-)comsat.c (-49 / +52 lines)
Lines 85-91 Link Here
85
void reapchildren(int);
85
void reapchildren(int);
86
86
87
int
87
int
88
main(int argc, char *argv[])
88
main(int __unused argc, char __unused *argv[])
89
{
89
{
90
	struct sockaddr_in from;
90
	struct sockaddr_in from;
91
	socklen_t fromlen;
91
	socklen_t fromlen;
Lines 99-118 Link Here
99
	openlog("comsat", LOG_PID, LOG_DAEMON);
99
	openlog("comsat", LOG_PID, LOG_DAEMON);
100
	if (chdir(_PATH_MAILDIR)) {
100
	if (chdir(_PATH_MAILDIR)) {
101
		syslog(LOG_ERR, "chdir: %s: %m", _PATH_MAILDIR);
101
		syslog(LOG_ERR, "chdir: %s: %m", _PATH_MAILDIR);
102
		(void) recv(0, msgbuf, sizeof(msgbuf) - 1, 0);
102
		recv(0, msgbuf, sizeof(msgbuf) - 1, 0);
103
		exit(1);
103
		exit(1);
104
	}
104
	}
105
	if ((uf = open(_PATH_UTMP, O_RDONLY, 0)) < 0) {
105
	if ((uf = open(_PATH_UTMP, O_RDONLY, 0)) < 0) {
106
		syslog(LOG_ERR, "open: %s: %m", _PATH_UTMP);
106
		syslog(LOG_ERR, "open: %s: %m", _PATH_UTMP);
107
		(void) recv(0, msgbuf, sizeof(msgbuf) - 1, 0);
107
		recv(0, msgbuf, sizeof(msgbuf) - 1, 0);
108
		exit(1);
108
		exit(1);
109
	}
109
	}
110
	(void)time(&lastmsgtime);
110
	time(&lastmsgtime);
111
	(void)gethostname(hostname, sizeof(hostname));
111
	if (gethostname(hostname, sizeof(hostname)) == -1)
112
	   err(1, "gehostname");
112
	onalrm(0);
113
	onalrm(0);
113
	(void)signal(SIGALRM, onalrm);
114
	signal(SIGALRM, onalrm);
114
	(void)signal(SIGTTOU, SIG_IGN);
115
	signal(SIGTTOU, SIG_IGN);
115
	(void)signal(SIGCHLD, reapchildren);
116
	signal(SIGCHLD, reapchildren);
116
	for (;;) {
117
	for (;;) {
117
		cc = recv(0, msgbuf, sizeof(msgbuf) - 1, 0);
118
		cc = recv(0, msgbuf, sizeof(msgbuf) - 1, 0);
118
		if (cc <= 0) {
119
		if (cc <= 0) {
Lines 125-153 Link Here
125
			continue;
126
			continue;
126
		sigblock(sigmask(SIGALRM));
127
		sigblock(sigmask(SIGALRM));
127
		msgbuf[cc] = '\0';
128
		msgbuf[cc] = '\0';
128
		(void)time(&lastmsgtime);
129
		time(&lastmsgtime);
129
		mailfor(msgbuf);
130
		mailfor(msgbuf);
130
		sigsetmask(0L);
131
		sigsetmask(0L);
131
	}
132
	}
132
}
133
}
133
134
134
void
135
void
135
reapchildren(int signo)
136
reapchildren(int __unused signo)
136
{
137
{
137
	while (wait3(NULL, WNOHANG, NULL) > 0);
138
	while (wait3(NULL, WNOHANG, NULL) > 0);
138
}
139
}
139
140
140
void
141
void
141
onalrm(int signo)
142
onalrm(int __unused signo)
142
{
143
{
143
	static u_int utmpsize;		/* last malloced size for utmp */
144
	static size_t utmpsize;		/* last malloced size for utmp */
144
	static u_int utmpmtime;		/* last modification time for utmp */
145
	static time_t utmpmtime;	/* last modification time for utmp */
145
	struct stat statbf;
146
	struct stat statbf;
146
147
147
	if (time(NULL) - lastmsgtime >= MAXIDLE)
148
	if (time(NULL) - lastmsgtime >= MAXIDLE)
148
		exit(0);
149
		exit(0);
149
	(void)alarm((u_int)15);
150
	alarm(15);
150
	(void)fstat(uf, &statbf);
151
	if (fstat(uf, &statbf) == -1)
152
	   err(1, "fstat");
151
	if (statbf.st_mtime > utmpmtime) {
153
	if (statbf.st_mtime > utmpmtime) {
152
		utmpmtime = statbf.st_mtime;
154
		utmpmtime = statbf.st_mtime;
153
		if (statbf.st_size > utmpsize) {
155
		if (statbf.st_size > utmpsize) {
Lines 157-163 Link Here
157
				exit(1);
159
				exit(1);
158
			}
160
			}
159
		}
161
		}
160
		(void)lseek(uf, (off_t)0, SEEK_SET);
162
		if (lseek(uf, 0, SEEK_SET) == -1)
163
		   err(1, "lseek");
161
		nutmp = read(uf, utmp, (size_t)statbf.st_size)/sizeof(struct utmp);
164
		nutmp = read(uf, utmp, (size_t)statbf.st_size)/sizeof(struct utmp);
162
	}
165
	}
163
}
166
}
Lines 181-191 Link Here
181
		file = name;
184
		file = name;
182
	else
185
	else
183
		file = cp + 1;
186
		file = cp + 1;
184
	sprintf(buf, "%s/%.*s", _PATH_MAILDIR, (int)sizeof(utmp[0].ut_name),
187
	sprintf(buf, "%s/%.*s", _PATH_MAILDIR, sizeof(utmp[0].ut_name), name);
185
	    name);
186
	if (*file != '/') {
188
	if (*file != '/') {
187
		sprintf(buf2, "%s/%.*s", _PATH_MAILDIR,
189
		sprintf(buf2, "%s/%.*s", _PATH_MAILDIR,
188
		    (int)sizeof(utmp[0].ut_name), file);
190
		      sizeof(utmp[0].ut_name), file);
189
		file = buf2;
191
		file = buf2;
190
	}
192
	}
191
	folder = strcmp(buf, file);
193
	folder = strcmp(buf, file);
Lines 194-200 Link Here
194
			notify(utp, file, offset, folder);
196
			notify(utp, file, offset, folder);
195
}
197
}
196
198
197
static char *cr;
199
const char *cr = "\n";
198
200
199
void
201
void
200
notify(struct utmp *utp, char file[], off_t offset, int folder)
202
notify(struct utmp *utp, char file[], off_t offset, int folder)
Lines 202-211 Link Here
202
	FILE *tp;
204
	FILE *tp;
203
	struct stat stb;
205
	struct stat stb;
204
	struct termios tio;
206
	struct termios tio;
205
	char tty[20], name[sizeof(utmp[0].ut_name) + 1];
207
	char tty[20];
206
208
207
	(void)snprintf(tty, sizeof(tty), "%s%.*s",
209
	snprintf(tty, sizeof(tty), "%s%.*s",
208
	    _PATH_DEV, (int)sizeof(utp->ut_line), utp->ut_line);
210
	      _PATH_DEV, sizeof(utp->ut_line), utp->ut_line);
209
	if (strchr(tty + sizeof(_PATH_DEV) - 1, '/')) {
211
	if (strchr(tty + sizeof(_PATH_DEV) - 1, '/')) {
210
		/* A slash is an attempt to break security... */
212
		/* A slash is an attempt to break security... */
211
		syslog(LOG_AUTH | LOG_NOTICE, "'/' in \"%s\"", tty);
213
		syslog(LOG_AUTH | LOG_NOTICE, "'/' in \"%s\"", tty);
Lines 218-253 Link Here
218
	dsyslog(LOG_DEBUG, "notify %s on %s\n", utp->ut_name, tty);
220
	dsyslog(LOG_DEBUG, "notify %s on %s\n", utp->ut_name, tty);
219
	if (fork())
221
	if (fork())
220
		return;
222
		return;
221
	(void)signal(SIGALRM, SIG_DFL);
223
	signal(SIGALRM, SIG_DFL);
222
	(void)alarm((u_int)30);
224
	alarm(30);
223
	if ((tp = fopen(tty, "w")) == NULL) {
225
	if ((tp = fopen(tty, "w")) == NULL) {
224
		dsyslog(LOG_ERR, "%s: %s", tty, strerror(errno));
226
		dsyslog(LOG_ERR, "%s: %s", tty, strerror(errno));
225
		_exit(1);
227
		_exit(1);
226
	}
228
	}
227
	(void)tcgetattr(fileno(tp), &tio);
229
	if (tcgetattr(fileno(tp), &tio) == -1)
228
	cr = ((tio.c_oflag & (OPOST|ONLCR)) == (OPOST|ONLCR)) ?  "\n" : "\n\r";
230
	   err(1, "tcgetattr");
229
	(void)strncpy(name, utp->ut_name, sizeof(utp->ut_name));
230
	name[sizeof(name) - 1] = '\0';
231
	switch (stb.st_mode & (S_IXUSR | S_IXGRP)) {
231
	switch (stb.st_mode & (S_IXUSR | S_IXGRP)) {
232
	case S_IXUSR:
232
	case S_IXUSR:
233
	case (S_IXUSR | S_IXGRP):
233
	case (S_IXUSR | S_IXGRP):
234
		(void)fprintf(tp, 
234
		fprintf(tp, 
235
		    "%s\007New mail for %s@%.*s\007 has arrived%s%s%s:%s----%s",
235
		    "%s\007New mail for %s@%.*s\007 has arrived%s%s%s:%s----%s",
236
		    cr, name, (int)sizeof(hostname), hostname,
236
		    cr, utp->ut_name, sizeof(hostname), hostname,
237
		    folder ? cr : "", folder ? "to " : "", folder ? file : "",
237
		    folder ? cr : "", folder ? "to " : "", folder ? file : "",
238
		    cr, cr);
238
		    cr, cr);
239
		jkfprintf(tp, name, file, offset);
239
		jkfprintf(tp, utp->ut_name, file, offset);
240
		break;
240
		break;
241
	case S_IXGRP:
241
	case S_IXGRP:
242
		(void)fprintf(tp, "\007");
242
		fprintf(tp, "\007");
243
		(void)fflush(tp);      
243
		fflush(tp);      
244
		(void)sleep(1);
244
		sleep(1);
245
		(void)fprintf(tp, "\007");
245
		fprintf(tp, "\007");
246
		break;
246
		break;
247
	default:
247
	default:
248
		break;
248
		break;
249
	}	
249
	}	
250
	(void)fclose(tp);
250
	fclose(tp);
251
	_exit(0);
251
	_exit(0);
252
}
252
}
253
253
Lines 258-273 Link Here
258
	FILE *fi;
258
	FILE *fi;
259
	int linecnt, charcnt, inheader;
259
	int linecnt, charcnt, inheader;
260
	struct passwd *p;
260
	struct passwd *p;
261
	unsigned char line[BUFSIZ];
261
	char line[BUFSIZ];
262
262
263
	/* Set effective uid to user in case mail drop is on nfs */
263
	/* Set effective uid to user in case mail drop is on nfs */
264
	if ((p = getpwnam(user)) != NULL)
264
	if ((p = getpwnam(user)) != NULL)
265
		(void) setuid(p->pw_uid);
265
		if (setuid(p->pw_uid) == -1)
266
		   err(1, "setuid");
266
267
267
	if ((fi = fopen(file, "r")) == NULL)
268
	if ((fi = fopen(file, "r")) == NULL)
268
		return;
269
		return;
269
270
270
	(void)fseeko(fi, offset, SEEK_CUR);
271
	if (fseeko(fi, offset, SEEK_CUR) == -1)
272
	   err(1, "fseeko");
271
	/*
273
	/*
272
	 * Print the first 7 lines or 560 characters of the new mail
274
	 * Print the first 7 lines or 560 characters of the new mail
273
	 * (whichever comes first).  Skip header crap other than
275
	 * (whichever comes first).  Skip header crap other than
Lines 288-299 Link Here
288
				continue;
290
				continue;
289
		}
291
		}
290
		if (linecnt <= 0 || charcnt <= 0) {
292
		if (linecnt <= 0 || charcnt <= 0) {
291
			(void)fprintf(tp, "...more...%s", cr);
293
			fprintf(tp, "...more...%s", cr);
292
			(void)fclose(fi);
294
			fclose(fi);
293
			return;
295
			return;
294
		}
296
		}
295
		/* strip weird stuff so can't trojan horse stupid terminals */
297
		/* strip weird stuff so can't trojan horse stupid terminals */
296
		for (cp = line; (ch = *cp) && ch != '\n'; ++cp, --charcnt) {
298
		for (cp = (unsigned char *)line; (ch = *cp) && ch != '\n'; 
299
		      ++cp, --charcnt) {
297
			/* disable upper controls and enable all other
300
			/* disable upper controls and enable all other
298
			   8bit codes due to lack of locale knowledge
301
			   8bit codes due to lack of locale knowledge
299
			 */
302
			 */
Lines 303-320 Link Here
303
			   ) {
306
			   ) {
304
				if (ch & 0x80) {
307
				if (ch & 0x80) {
305
					ch &= ~0x80;
308
					ch &= ~0x80;
306
					(void)fputs("M-", tp);
309
					fputs("M-", tp);
307
				}
310
				}
308
				if (iscntrl(ch)) {
311
				if (iscntrl(ch)) {
309
					ch ^= 0x40;
312
					ch ^= 0x40;
310
					(void)fputc('^', tp);
313
					fputc('^', tp);
311
				}
314
				}
312
			}
315
			}
313
			(void)fputc(ch, tp);
316
			fputc(ch, tp);
314
		}
317
		}
315
		(void)fputs(cr, tp);
318
		fputs(cr, tp);
316
		--linecnt;
319
		--linecnt;
317
	}
320
	}
318
	(void)fprintf(tp, "----%s\n", cr);
321
	fprintf(tp, "----%s\n", cr);
319
	(void)fclose(fi);
322
	fclose(fi);
320
}
323
}

Return to bug 79232