home *** CD-ROM | disk | FTP | other *** search
- #ifndef lint
- static char *RCSid = "$Header: /fsys4/usr/source/users/msg/Common/RCS/deliver.c,v 1.4 90/12/29 21:59:07 jmsellen Exp $";
- #endif
-
- /* deliver.c
- Deliver a message to a user on this machine.
- */
-
- /*
- * Old revision log:
- *
- * Revision 1.4 87/06/04 12:49:47 jmsellens
- * Changes to put the msg save file in /usr/tmp
- * rationalized the code a little, added the NO_STAT error condition
- *
- * Revision 1.3 87/04/13 09:46:09 sahayman
- * Make sure to do answerback() on unsuccessful messages (mesg n)
- * as well as successful.
- *
- * Revision 1.2 87/04/06 02:16:30 sahayman
- * Print a "However ... " message when unable to deliver to some
- * ttys but able to deliver to others.
- *
- */
- #include "msg.h"
- #include <setjmp.h>
- #include <signal.h>
- #include <ctype.h>
-
- static jmp_buf timeout;
-
-
- static
- wakeup()
- {
- longjmp( timeout, 1 );
- }
-
-
-
- int
- deliver( sender, user, message, fromroot )
- char *sender, *user, *message;
- {
- struct utmp ut;
- FILE *fp, *term;
- char terminal[40]; /* should be enough ... */
- int found = 0, errcode = 0;
- int however = 0; /* Should we print a "however ...." msg */
- struct stat sbuf;
- char line[sizeof(ut.ut_line)+5];
- char successful_line[sizeof(ut.ut_line)+5];
- int (*osig)();
- #ifdef SAVEMSG
- int uid = -1;
- #endif
-
- successful_line[0] = '\0';
-
- if ( (fp=fopen( UTMP, "r" )) == FPNULL ) {
- errmsg( NO_UTMP, hostname, syserr() );
- return( NO_UTMP );
- }
- /* keep on until end of file in case s/he's signed on more than once */
- while ( fread( &ut, sizeof(struct utmp), 1, fp ) == 1 ) {
- if ( strncmp( user, ut.ut_name, sizeof(ut.ut_name) ) != 0 )
- continue;
- #ifdef SYSV_UTMP
- if ( ut.ut_type != USER_PROCESS )
- continue;
- #endif
- found++;
- (void) strncpy( line, ut.ut_line, sizeof(ut.ut_line) );
- line[sizeof(ut.ut_line)] = '\0';
- (void) sprintf( terminal, "%s%s", DEV, line );
- /* stat it to see if we're allowed to write */
- if ( stat(terminal,&sbuf) == 0 ) {
- #ifdef SAVEMSG
- uid = sbuf.st_uid;
- #endif
- if ( ((sbuf.st_mode&ALLOW)==0) && !fromroot ) {
- errmsg( MESG_OFF, user, hostname, line );
- however++;
- errcode++;
- } else {
- if ( setjmp( timeout ) ) {
- errmsg( TIMEOUT, user, hostname, line );
- however++;
- } else {
- osig = signal(SIGALRM, wakeup);
- alarm( 5 );
- if ( (term=fopen(terminal,"w")) != NULL ) {
- fprintf(term, "\n\007%s: %s\n", sender, message);
- /* we need this fflush() or else it would hang in the
- fclose() after we've dealt with the alarm() */
- fflush( term );
- strcpy( successful_line, line );
- }
- }
- alarm( 0 );
- signal(SIGALRM, osig);
- if (term == NULL) {
- errmsg( NO_WRITE, user, hostname, line, syserr() );
- however++;
- errcode++;
- } else
- fclose( term );
- }
- #ifdef ANSWERBACK
- answerback( ANSWER, user, line );
- #endif
- } else {
- errmsg( NO_STAT, terminal, user, hostname, syserr() );
- however++;
- errcode++;
- }
- }
- (void) fclose( fp );
- #ifdef SAVEMSG
- /* note that these saves it even if mesg n was set */
- if ( found && uid != -1 )
- savemsg( uid, user, sender, message );
- #endif
- if ( !found ) {
- errmsg( NOT_ON, user, hostname );
- errcode++;
- }
- /*
- * A message like "so-and-so (ttyxx) is not receiving messages"
- * is not too helpful when they are receiving messages
- * on another terminal. So mention that.
- * ..sah 87/04/06
- */
-
- if ( however && successful_line[0] ) {
- errmsg( HOWEVER, user, hostname, successful_line );
- }
- return( errcode );
- }
-
-
- #define DEL (127)
-
- sanitize( mbuf, copy )
- char *mbuf;
- char *copy;
- {
- char *p, *r;
- /*
- * Remove control characters to prevent nasties.
- * Previously allowed isspace(*p), but having a \r in a message
- * is asking for forgeries. isprint() is sufficient.
- * (And good programmers always use isascii() first, right?)
- */
- for ( p = mbuf, r = copy; *p; p++,r++ ) {
- if ( ! isascii( *p ) ) {
- *r++ = '\\';
- *p = toascii( *p );
- }
- if ( ! isprint(*p) ) {
- if ( *p == '\t' )
- *r = ' ';
- else if ( iscntrl( *p ) ) {
- *r++ = '^';
- if ( *p == DEL )
- *r = '?';
- else
- *r = *p + '@';
- } else /* this shouldn't happen, but what the hell */
- *r = 'X';
- } else
- *r = *p;
- }
- }
-