/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
/*
* Copyright 1988-2003 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* Copyright 2012 Joyent, Inc. All rights reserved.
*
* Copyright (c) 2013 Gary Mills
*/
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <grp.h>
#include <unistd.h>
#include <string.h>
#include <ctype.h>
#include <utmpx.h>
#include <dirent.h>
#include <pwd.h>
#include <fcntl.h>
#include <time.h>
#include <errno.h>
#include <locale.h>
#include <syslog.h>
#include <limits.h>
#include <libzonecfg.h>
#include <zone.h>
#include <libcontract.h>
/*
* Use the full lengths from utmpx for user and line.
*/
static char *infile;
static int gflag;
static char *grpname;
static void sendmes_tozone(zoneid_t, int);
static int chkgrp(char *);
static char *copy_str_till(char *, char *, char, int);
static int init_template(void);
int contract_abandon_id(ctid_t);
int
{
FILE *f;
char *term_name;
int c;
int aflag = 0;
int errflg = 0;
int zflg = 0;
int Zflg = 0;
switch (c) {
case 'a':
aflag++;
break;
case 'g':
if (gflag) {
"Only one group allowed\n");
return (1);
}
grpname);
return (1);
}
gflag++;
break;
case 'z':
zflg++;
"is invalid", zonename);
return (1);
}
break;
case 'Z':
Zflg++;
break;
case '?':
errflg++;
break;
}
if (errflg) {
"Usage: wall [-a] [-g group] [-z zone] [-Z] [files...]\n");
return (1);
}
return (1);
}
return (2);
}
/*
* Get the name of the terminal wall is running from.
*/
/*
* skip the leading "/dev/" in term_name
*/
}
if (who[0] == '?') {
}
f = stdin;
if (infile) {
if (f == NULL) {
return (1);
}
}
size_t n;
break;
break;
ptr += n;
}
(void) fclose(f);
/*
* If the request is from the rwall daemon then use the caller's
* name and host. We determine this if all of the following is true:
* 1) First 5 characters are "From "
* 2) Next non-white characters are of the form "name@host:"
*/
char *cp;
if (rwho[0] != '\0') {
MAXNAMLEN + 1);
if (rsystm[0] != '\0') {
sizeof (who));
}
}
}
}
if (zflg != 0) {
if ((zoneidlist =
return (errno);
nzids = 1;
} else if (Zflg != 0) {
return (errno);
nzids *= 2;
nzids_saved = nzids;
(void) free(zoneidlist);
return (errno);
}
if (nzids > nzids_saved) {
goto again;
}
}
} else
return (0);
}
/*
* Copy src to destination upto but not including the delim.
* Leave dst empty if delim not found or whitespace encountered.
* Return pointer to next character (delim, whitespace, or '\0')
*/
static char *
{
int i = 0;
dst[0] = '\0';
return (src);
}
dst[i] = '\0';
return (src);
}
}
dst[0] = '\0';
return (src);
}
static void
int i = 0;
struct utmpx *p;
root[0] = '\0';
return;
}
} else {
(void) utmpxname(UTMPX_FILE);
}
setutxent();
if (p->ut_type != USER_PROCESS)
continue;
/*
* if (-a option OR NOT pty window login), send the message
*/
}
endutxent();
(void) alarm(60);
do {
i = (int)wait((int *)0);
}
/*
* Note to future maintainers: with the change of wall to use the
* getutxent() API, the forked children (created by this function)
* must call _exit as opposed to exit. This is necessary to avoid
* unwanted fflushing of getutxent's stdio stream (caused by atexit
* processing).
*/
static void
{
int i;
char *s;
char *bp;
int ibp;
FILE *f;
tmpl_fd = init_template();
if (tmpl_fd == -1) {
"process contract");
return;
}
}
while ((i = (int)fork()) == -1) {
(void) alarm(60);
(void) wait((int *)0);
(void) alarm(0);
}
if (i)
return;
"%s\n", zonename);
}
if (zoneenter)
(void) ct_tmpl_clear(tmpl_fd);
if (gflag)
_exit(0);
(void) alarm(60);
s = &device[0];
/* check if the device is really a tty */
perror("open");
_exit(1);
} else {
"Cannot send to device %.*s %s\n",
"because it's not a tty");
closelog();
_exit(1);
}
}
#ifdef DEBUG
#else
#endif
if (f == NULL) {
perror("open");
_exit(1);
}
(void) fprintf(f,
"\07\07\07Broadcast Message from %s (%s) on %s %19.19s",
if (gflag)
(void) fprintf(f, "...\n");
#ifdef DEBUG
#endif
if (*bp == '\n')
(void) putc('\r', f);
} else {
(void) fputs("M-", f);
}
(void) putc('^', f);
}
else
}
if (*bp == '\n')
(void) fflush(f);
(void) printf("\n\007Write failed\n");
_exit(1);
}
}
(void) fclose(f);
_exit(0);
}
static int
{
int i;
return (1);
}
return (0);
}
static int
init_template(void) {
int fd = 0;
int err = 0;
if (fd == -1)
return (-1);
return (-1);
}
return (fd);
}