/* Copyright (C) 1998,2001 Free Software Foundation, Inc. This file is part of GNU Inetutils. GNU Inetutils is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. GNU Inetutils is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GNU Inetutils; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #undef MAX #define MAX(a,b) ( (a) > (b) ? (a) : (b) ) #define N_LINES 5 #define N_CHARS 256 extern char * ttymsg (struct iovec *iov, int iovcnt, char *line, int tmout); typedef struct { int ind; int max_size; char line[N_LINES][N_CHARS]; int size[N_LINES]; char buf[N_LINES*N_CHARS+3]; } LINE; static void init_line (LINE *lp) { memset (lp, 0, sizeof *lp); } static void format_line (LINE *lp, const char *fmt, ...) { va_list ap; int i = lp->ind; if (lp->ind >= N_LINES) return; lp->ind++; va_start (ap, fmt); lp->size[i] = vsnprintf (lp->line[i], sizeof lp->line[i], fmt, ap); lp->max_size = MAX (lp->max_size, lp->size[i]); va_end (ap); } static char * finish_line (LINE *lp) { int i; char *p; p = lp->buf; *p++ = '\a'; *p++ = '\r'; *p++ = '\n'; for (i = 0; i < lp->ind; i++) { char *q; int j; for (q = lp->line[i]; *q; q++) *p++ = *q; for (j = lp->size[i]; j < lp->max_size + 2; j++) *p++ = ' '; *p++ = '\r'; *p++ = '\n'; } *p = 0; return lp->buf; } static int print_mesg (char *tty, CTL_MSG *request, char *remote_machine) { time_t t; LINE ln; char *buf; struct tm *tm; struct iovec iovec; char *cp; time (&t); tm = localtime (&t); init_line (&ln); format_line (&ln, ""); format_line (&ln, "Message from Talk_Daemon@%s at %d:%02d ...", hostname, tm->tm_hour , tm->tm_min); format_line (&ln, "talk: connection requested by %s@%s", request->l_name, remote_machine); format_line (&ln, "talk: respond with: talk %s@%s", request->l_name, remote_machine); format_line (&ln, ""); format_line (&ln, ""); buf = finish_line (&ln); iovec.iov_base = buf; iovec.iov_len = strlen (buf); if ((cp = ttymsg (&iovec, 1, tty, RING_WAIT - 5)) != NULL) { syslog(LOG_CRIT, "%s", cp); return FAILED; } return SUCCESS; } /* See if the user is accepting messages. If so, announce that a talk is requested. */ int announce (CTL_MSG *request, char *remote_machine) { char *ttypath; int len; struct stat st; int rc; len = sizeof (PATH_DEV) + strlen (request->r_tty) + 2; ttypath = malloc (len); if (!ttypath) { syslog (LOG_CRIT, "out of memory"); exit (1); } sprintf (ttypath, "%s/%s", PATH_DEV, request->r_tty); rc = stat (ttypath, &st); free (ttypath); if (rc < 0 || (st.st_mode & S_IWGRP) == 0) return PERMISSION_DENIED; return print_mesg (request->r_tty, request, remote_machine); }