/* imiscd.c - miscellaneous network service -- responder */
static char *rcsid
= "$Header: /f/osi/imisc/RCS/imiscd.c,v 7.4 91/02/22 09:26:21 mrose Interim $";
* $Header: /f/osi/imisc/RCS/imiscd.c,v 7.4 91/02/22 09:26:21 mrose Interim $
* Revision 7.4 91/02/22 09:26:21 mrose
* Revision 7.3 90/11/21 11:37:04 mrose
* Revision 7.2 90/07/09 14:38:48 mrose
* Revision 7.1 90/07/01 21:04:05 mrose
* Revision 7.0 89/11/23 21:57:39 mrose
* Acquisition, use, and distribution of this module and related
* materials are subject to the restrictions of a license agreement.
* Consult the Preface in the User's Manual for the full terms of
#include "IMISC-types.h" /* IMISC type definitions */
#include "ryresponder.h" /* for generic idempotent responders */
#include "IMISC-ops.h" /* IMISC operation definitions */
static char *myservice
= "isode miscellany"; /* should be something else */
int op_utcTime (), op_genTime (), op_timeOfDay (), op_users (),
op_charGen (), op_pwdGen (), op_exec (), op_tellUser (), op_data ();
static struct dispatch dispatches
[] = {
"utcTime", operation_IMISC_utcTime
, op_utcTime
,
"genTime", operation_IMISC_genTime
, op_genTime
,
"timeOfDay", operation_IMISC_timeOfDay
, op_timeOfDay
,
"users", operation_IMISC_users
, op_users
,
"chargen", operation_IMISC_charGen
, op_charGen
,
"pwdGen", operation_IMISC_pwdGen
, op_pwdGen
,
"qotd", operation_IMISC_qotd
, op_exec
,
"finger", operation_IMISC_finger
, op_exec
,
"tellUser", operation_IMISC_tellUser
, op_tellUser
,
"ping", operation_IMISC_ping
, op_data
,
"sink", operation_IMISC_sink
, op_data
,
"echo", operation_IMISC_echo
, op_data
,
struct type_IMISC_IA5List
*str2ia5list ();
ryresponder (argc
, argv
, PLocalHostName (), myservice
, NULLCP
,
dispatches
, table_IMISC_Operations
, NULLIFP
, NULLIFP
);
exit (0); /* NOTREACHED */
static int op_utcTime (sd
, ryo
, rox
, in
, roi
)
struct RoSAPindication
*roi
;
register struct UTCtime
*ut
= &uts
;
register struct type_IMISC_UTCResult
*ur
;
if (rox
-> rox_nolinked
== 0) {
advise (LLOG_EXCEPTIONS
, NULLCP
,
"RO-INVOKE.INDICATION/%d: %s, unknown linkage %d",
sd
, ryo
-> ryo_name
, rox
-> rox_linkid
);
return ureject (sd
, ROS_IP_LINKED
, rox
, roi
);
advise (LLOG_NOTICE
, NULLCP
, "RO-INVOKE.INDICATION/%d: %s",
if (time (&clock
) == NOTOK
|| (tm
= gmtime (&clock
)) == NULL
)
return error (sd
, error_IMISC_unableToDetermineTime
, (caddr_t
) NULL
,
if ((cp
= utct2str (ut
)) == NULLCP
|| (ur
= str2qb (cp
, strlen (cp
), 1)) == NULL
)
return error (sd
, error_IMISC_congested
, (caddr_t
) NULL
, rox
, roi
);
if (RyDsResult (sd
, rox
-> rox_id
, (caddr_t
) ur
, ROS_NOPRIO
, roi
) == NOTOK
)
ros_adios (&roi
-> roi_preject
, "RESULT");
free_IMISC_UTCResult (ur
);
static int op_genTime (sd
, ryo
, rox
, in
, roi
)
struct RoSAPindication
*roi
;
#if defined(BSD42) || defined (HPUX)
register struct UTCtime
*ut
= &uts
;
register struct type_IMISC_GenResult
*gr
;
if (rox
-> rox_nolinked
== 0) {
advise (LLOG_EXCEPTIONS
, NULLCP
,
"RO-INVOKE.INDICATION/%d: %s, unknown linkage %d",
sd
, ryo
-> ryo_name
, rox
-> rox_linkid
);
return ureject (sd
, ROS_IP_LINKED
, rox
, roi
);
advise (LLOG_NOTICE
, NULLCP
, "RO-INVOKE.INDICATION/%d: %s",
#if defined(BSD42) || defined (HPUX)
if (gettimeofday (&tvs
, (struct timezone
*) 0) == NOTOK
)
return error (sd
, error_IMISC_unableToDetermineTime
, (caddr_t
) NULL
,
if (time (&clock
) == NOTOK
)
return error (sd
, error_IMISC_unableToDetermineTime
, (caddr_t
) NULL
,
if ((tm
= gmtime (&clock
)) == NULL
)
return error (sd
, error_IMISC_unableToDetermineTime
, (caddr_t
) NULL
,
ut
-> ut_flags
|= UT_USEC
;
ut
-> ut_usec
= tvs
.tv_usec
;
if ((cp
= gent2str (ut
)) == NULLCP
|| (gr
= str2qb (cp
, strlen (cp
), 1)) == NULL
)
return error (sd
, error_IMISC_congested
, (caddr_t
) NULL
, rox
, roi
);
if (RyDsResult (sd
, rox
-> rox_id
, (caddr_t
) gr
, ROS_NOPRIO
, roi
) == NOTOK
)
ros_adios (&roi
-> roi_preject
, "RESULT");
free_IMISC_GenResult (gr
);
/* Return the number of seconds since 00:00 (midnight) 1 January 1900 GMT */
static int op_timeOfDay (sd
, ryo
, rox
, in
, roi
)
struct RoSAPindication
*roi
;
struct type_IMISC_TimeResult trs
;
register struct type_IMISC_TimeResult
*tr
= &trs
;
if (rox
-> rox_nolinked
== 0) {
advise (LLOG_EXCEPTIONS
, NULLCP
,
"RO-INVOKE.INDICATION/%d: %s, unknown linkage %d",
sd
, ryo
-> ryo_name
, rox
-> rox_linkid
);
return ureject (sd
, ROS_IP_LINKED
, rox
, roi
);
advise (LLOG_NOTICE
, NULLCP
, "RO-INVOKE.INDICATION/%d: %s",
if (time (&clock
) == NOTOK
)
return error (sd
, error_IMISC_unableToDetermineTime
, (caddr_t
) NULL
,
tr
-> parm
= clock
+ 2208988800;
if (RyDsResult (sd
, rox
-> rox_id
, (caddr_t
) tr
, ROS_NOPRIO
, roi
) == NOTOK
)
ros_adios (&roi
-> roi_preject
, "RESULT");
#define HMAX (sizeof (ut -> ut_host))
#define LMAX (sizeof (ut -> ut_line))
#define NMAX (sizeof (ut -> ut_name))
struct utmp
*getutent ();
static int op_users (sd
, ryo
, rox
, in
, roi
)
struct RoSAPindication
*roi
;
register struct utmp
*ut
= &uts
;
struct type_IMISC_IA5List
*ia5
;
register struct type_IMISC_IA5List
**ia5p
;
if (rox
-> rox_nolinked
== 0) {
advise (LLOG_EXCEPTIONS
, NULLCP
,
"RO-INVOKE.INDICATION/%d: %s, unknown linkage %d",
sd
, ryo
-> ryo_name
, rox
-> rox_linkid
);
return ureject (sd
, ROS_IP_LINKED
, rox
, roi
);
advise (LLOG_NOTICE
, NULLCP
, "RO-INVOKE.INDICATION/%d: %s",
if ((ud
= open ("/etc/utmp", 0)) == NOTOK
) {
(void) sprintf (buffer
, "/etc/utmp: %s", sys_errname (errno
));
if ((*ia5p
= str2ia5list (buffer
)) == NULL
)
ia5p
= &((*ia5p
) -> next
);
result
= error (sd
, error_IMISC_unableToOpenFile
, (caddr_t
) ia5
, rox
,
free_IMISC_IA5List (ia5
);
while (read (ud
, (char *) ut
, sizeof *ut
) == sizeof *ut
) {
if (ut
-> ut_name
[0] == NULL
)
if ((dp
= ctime (&ut
-> ut_time
)) == NULL
)
(void) sprintf (buffer
, "%-*.*s %-*.*s %.12s",
NMAX
, NMAX
, ut
-> ut_name
, LMAX
, LMAX
, ut
-> ut_line
, dp
+ 4);
(void) sprintf (buffer
+ strlen (buffer
), "\t(%.*s)",
if ((*ia5p
= str2ia5list (buffer
)) == NULL
)
ia5p
= &((*ia5p
) -> next
);
while (ut
= getutent ()) {
if (ut
-> ut_type
!= USER_PROCESS
)
if ((dp
= ctime (&ut
-> ut_time
)) == NULL
)
(void) sprintf (buffer
, "%-*.*s %-*.*s %.12s",
NMAX
, NMAX
, ut
-> ut_name
, LMAX
, LMAX
, ut
-> ut_line
,
if ((*ia5p
= str2ia5list (buffer
)) == NULL
)
ia5p
= &((*ia5p
) -> next
);
if (RyDsResult (sd
, rox
-> rox_id
, (caddr_t
) ia5
, ROS_NOPRIO
, roi
)
ros_adios (&roi
-> roi_preject
, "RESULT");
free_IMISC_IA5List (ia5
);
free_IMISC_IA5List (ia5
);
return error (sd
, error_IMISC_congested
, (caddr_t
) NULL
, rox
, roi
);
static int op_charGen (sd
, ryo
, rox
, in
, roi
)
struct RoSAPindication
*roi
;
struct type_IMISC_IA5List
*ia5
;
register struct type_IMISC_IA5List
**ia5p
;
if (rox
-> rox_nolinked
== 0) {
advise (LLOG_EXCEPTIONS
, NULLCP
,
"RO-INVOKE.INDICATION/%d: %s, unknown linkage %d",
sd
, ryo
-> ryo_name
, rox
-> rox_linkid
);
return ureject (sd
, ROS_IP_LINKED
, rox
, roi
);
advise (LLOG_NOTICE
, NULLCP
, "RO-INVOKE.INDICATION/%d: %s",
for (i
= 0; i
< 0x80; i
++)
if (isprint ((u_char
) i
))
for (rs
= ring
, i
= NBYTES
; i
> 0; rs
++, i
-= j
) {
j
= i
> LINSIZ
? LINSIZ
: i
;
for (de
= (dp
= line
) + j
, rp
= rs
; dp
< de
; dp
++, rp
++) {
if ((*ia5p
= str2ia5list (line
)) == NULL
)
ia5p
= &((*ia5p
) -> next
);
if (RyDsResult (sd
, rox
-> rox_id
, (caddr_t
) ia5
, ROS_NOPRIO
, roi
)
ros_adios (&roi
-> roi_preject
, "RESULT");
free_IMISC_IA5List (ia5
);
free_IMISC_IA5List (ia5
);
return error (sd
, error_IMISC_congested
, (caddr_t
) NULL
, rox
, roi
);
static int op_pwdGen (sd
, ryo
, rox
, in
, roi
)
struct RoSAPindication
*roi
;
struct type_IMISC_IA5List
*ia5
;
register struct type_IMISC_IA5List
**ia5p
;
if (rox
-> rox_nolinked
== 0) {
advise (LLOG_EXCEPTIONS
, NULLCP
,
"RO-INVOKE.INDICATION/%d: %s, unknown linkage %d",
sd
, ryo
-> ryo_name
, rox
-> rox_linkid
);
return ureject (sd
, ROS_IP_LINKED
, rox
, roi
);
advise (LLOG_NOTICE
, NULLCP
, "RO-INVOKE.INDICATION/%d: %s",
for (i
= NPASS
; i
> 0; i
--) {
if (pwdgen (buffer
) == NOTOK
)
if ((*ia5p
= str2ia5list (buffer
)) == NULL
)
ia5p
= &((*ia5p
) -> next
);
if (RyDsResult (sd
, rox
-> rox_id
, (caddr_t
) ia5
, ROS_NOPRIO
, roi
)
ros_adios (&roi
-> roi_preject
, "RESULT");
free_IMISC_IA5List (ia5
);
free_IMISC_IA5List (ia5
);
return error (sd
, error_IMISC_congested
, (caddr_t
) NULL
, rox
, roi
);
/* Based on an f77 algorithm supplied by Frank Wancho <Wancho@SIMTEL20>,
which was based on a basic algorithm by Paul D. Merillat and Arthur A. Key.
Strings returned are built by alternating vowels and consonants.
However, there are "Digraphs", and these are presorted according to
END, MIDDLE, and START positions.
Not going into combinatorial analysis (with 7 characters the "possible"
combinations exceed 20 million).
static char *Nx
= /* XXX */
"BBBCBFBKBLBMBNBPBTBVCCCDCFCMCPDBDCDDDFDGDKDLDMDNDPDTDVDWDZFBFCFDFGFKFMFNF\
PFZGBGDGFGJGMGNGPGTGVKBKDKFKMKNKPKTKVKZLBLCLFLGLMLNLRLVLZMBMCMDMFMGMJMKMLMMMNM\
RMTMVMZNBNCNFNOSZTBTCTDTFTGTJTKTLTMTNTPTVVCVGVLVPNJNLNPNRPCPDPFPGPKPMPNPVPZRBR\
CRDRFRGRJRLSBSDSFSGSJSRSV";
static char *Cx
= /* consonants */
static char *Vx
= /* vowels */
static char *Dx
= /* consonant pairs */
"BRCHCLCRDRFLFRGLGRKLKRPHPLPRQUSCSHSKSLSMSNSPSTSWTHTRTW";
static char *Lx
= /* end-consonant pairs */
"BSCKCSCTDSFSFTGSHSKSLLLDLKLPLSLTMPMSNDNKNNNSNTPPPSPTRKRMRNRPRSSSTSVSWS";
static char *Px
= /* vowel pairs */
static char *Ex
= /* end-vowels */
static char *Zx
= /* end-vowel pairs */
#define ifix(f) ((int) ((float) (f) + 0.5))
#define nrand() (((float) (random ()) / (float) 2147483647))
#define nrand() (((float) (rand ()) / (float) 2147483647))
#define rng(a,b) if (((i = ifix (a * nrand ()) * b) ? i -= b : i) < 0 \
|| i >= a * b + (1 - b)) \
register struct pair
*pair
;
register struct web
*web
;
(((unsigned) (strlen (Dx
) + strlen (Lx
) + strlen (Nx
)))))
(void) strcpy (s
= Mx
, Dx
);
(void) srandom ((int) time ((long *) 0));
(void) srand ((unsigned int) time ((long *) 0));
for (pair
= pairs
; pair
-> p_form
; pair
++)
for (s
= pw
; c
= *f
++;) {
for (web
= webs
; web
-> w_key
!= c
; web
++)
rng (web
-> w_length
, web
-> w_factor
);
for (j
= web
-> w_factor
; j
> 0; j
--)
*s
++ = (*web
-> w_string
)[i
++];
if (web
-> w_special
&& *f
== NULL
) {
while (index (web
-> w_special
, *s
))
*s
= (*web
-> w_string
)[--i
];
for (f
= buffer
+ strlen (s
= pw
), *f
= NULL
; *s
; s
++)
for (o
= objects
; s
= o
-> o_string
; o
++)
for (n
= o
-> o_advance
; *s
; s
+= n
)
if (strncmp (f
, s
, n
) == 0)
#define FORTUNE "/usr/games/fortune"
#define RFINGER "/usr/ucb/finger"
#define RFINGER "/usr/bin/finger"
static int op_exec (sd
, ryo
, rox
, in
, roi
)
struct RoSAPindication
*roi
;
struct type_IMISC_IA5List
*ia5
;
register struct type_IMISC_IA5List
**ia5p
;
if (rox
-> rox_nolinked
== 0) {
advise (LLOG_EXCEPTIONS
, NULLCP
,
"RO-INVOKE.INDICATION/%d: %s, unknown linkage %d",
sd
, ryo
-> ryo_name
, rox
-> rox_linkid
);
result
= ureject (sd
, ROS_IP_LINKED
, rox
, roi
);
advise (LLOG_NOTICE
, NULLCP
, "RO-INVOKE.INDICATION/%d: %s",
if (ryo
-> ryo_op
== operation_IMISC_qotd
) {
vec
[vecp
++] = pgm
= FORTUNE
;
vec
[vecp
++] = pgm
= RFINGER
;
for (ia5
= (struct type_IMISC_IA5List
*) in
; ia5
; ia5
= ia5
-> next
)
|| (vec
[vecp
++] = qb2str (ia5
-> IA5String
)) == NULLCP
) {
result
= error (sd
, error_IMISC_congested
, (caddr_t
) NULL
, rox
,
if (access (pgm
, 1) == NOTOK
) {
result
= error_IMISC_unableToAccessFile
;
free_IMISC_IA5List (ia5
);
(void) sprintf (buffer
, "%s: %s", pgm
, sys_errname (errno
));
if ((*ia5p
= str2ia5list (buffer
)) == NULL
)
ia5p
= &((*ia5p
) -> next
);
result
= error (sd
, result
, (caddr_t
) ia5
, rox
, roi
);
free_IMISC_IA5List (ia5
);
if (pipe (pd
) == NOTOK
) {
result
= error_IMISC_unableToPipe
;
result
= error_IMISC_unableToFork
;
if ((fd
= open ("/dev/null", 2)) != NOTOK
) {
(void) dup2 (fd
, 0), (void) close (fd
);
for (vecp
= vecq
; bp
= vec
[vecp
]; vecp
++) {
for (; vecq
< vecp
; vecq
++)
switch (i
= read (pd
[0], buffer
, sizeof buffer
)) {
result
= error_IMISC_errorReading
;
if ((*ia5p
= str2ia5list (data
)) == NULL
)
ia5p
= &((*ia5p
) -> next
);
if (RyDsResult (sd
, rox
-> rox_id
, (caddr_t
) ia5
,
ROS_NOPRIO
, roi
) == NOTOK
)
ros_adios (&roi
-> roi_preject
, "RESULT");
free_IMISC_IA5List (ia5
);
for (bp
= buffer
; i
> 0; bp
++, i
--)
if ((*ia5p
= str2ia5list (data
)) == NULL
)
ia5p
= &((*ia5p
) -> next
);
free_IMISC_IA5List (ia5
);
result
= error (sd
, error_IMISC_congested
, (caddr_t
) NULL
, rox
, roi
);
for (vecp
= vecq
; bp
= vec
[vecp
]; vecp
++)
static int op_tellUser (sd
, ryo
, rox
, in
, roi
)
struct RoSAPindication
*roi
;
register struct utmp
*ut
= &uts
;
struct type_IMISC_IA5List
*ia5
;
if (rox
-> rox_nolinked
== 0) {
advise (LLOG_EXCEPTIONS
, NULLCP
,
"RO-INVOKE.INDICATION/%d: %s, unknown linkage %d",
sd
, ryo
-> ryo_name
, rox
-> rox_linkid
);
result
= ureject (sd
, ROS_IP_LINKED
, rox
, roi
);
advise (LLOG_NOTICE
, NULLCP
, "RO-INVOKE.INDICATION/%d: %s",
for (ia5
= (struct type_IMISC_IA5List
*) in
; ia5
; ia5
= ia5
-> next
)
|| (vecl
[vecp
++] = qb2str (ia5
-> IA5String
)) == NULLCP
)
advise (LLOG_EXCEPTIONS
, NULLCP
,
"too few arguments (got %d, wanted at least 3)", vecp
);
result
= ureject (sd
, ROS_IP_MISTYPED
, rox
, roi
);
vec
= &vecl
[2], vecp
-= 2;
result
= error_IMISC_userNotLoggedIn
;
if ((ud
= open ("/etc/utmp", 0)) == NOTOK
) {
(void) sprintf (buffer
, "/etc/utmp: %s", sys_errname (errno
));
if ((ia5
= str2ia5list (buffer
)) == NULL
)
result
= error (sd
, error_IMISC_unableToOpenFile
, (caddr_t
) ia5
, rox
,
free_IMISC_IA5List (ia5
);
while (read (ud
, (char *) ut
, sizeof *ut
) == sizeof *ut
) {
if (ut
-> ut_name
[0] == NULL
)
if (strncmp (ut
-> ut_name
, touser
, sizeof ut
-> ut_name
) == 0)
if (do_the_tell (ut
, fromuser
, vec
, vecp
) != NOTOK
)
result
= error_IMISC_unableToOpenFile
;
while (ut
= getutent ()) {
if (ut
-> ut_type
!= USER_PROCESS
)
if (strncmp (ut
-> ut_name
, touser
, sizeof ut
-> ut_name
) == 0)
if (do_the_tell (ut
, fromuser
, vec
, vecp
) != NOTOK
)
result
= error_IMISC_unableToOpenFile
;
result
= error (sd
, result
, (caddr_t
) NULL
, rox
, roi
);
if (RyDsResult (sd
, rox
-> rox_id
, (caddr_t
) NULL
, ROS_NOPRIO
, roi
)
ros_adios (&roi
-> roi_preject
, "RESULT");
result
= error (sd
, error_IMISC_congested
, (caddr_t
) NULL
, rox
, roi
);
for (vecp
= 0; bp
= vecl
[vecp
]; vecp
++)
static int do_the_tell (ut
, from
, vec
, vecp
)
(void) strcpy (bp
= tty
, "/dev/");
(void) strncpy (bp
, ut
-> ut_line
, LMAX
);
if (stat (tty
, &st
) == NOTOK
|| (st
.st_mode
& (S_IWRITE
>> 3)) != (S_IWRITE
>> 3))
for (i
= 0; i
< 5; i
++) {
if ((fp
= fopen (tty
, "w")) == NULL
)
fprintf (fp
, "\r\nmessage from %s:\r\n\007", from
);
for (i
= 0, bp
= NULL
; i
< vecp
; i
++, bp
= " ") {
_exit (0); /* NOTREACHED */
static int op_data (sd
, ryo
, rox
, in
, roi
)
struct RoSAPindication
*roi
;
if (rox
-> rox_nolinked
== 0) {
advise (LLOG_EXCEPTIONS
, NULLCP
,
"RO-INVOKE.INDICATION/%d: %s, unknown linkage %d",
sd
, ryo
-> ryo_name
, rox
-> rox_linkid
);
return ureject (sd
, ROS_IP_LINKED
, rox
, roi
);
advise (LLOG_DEBUG
, NULLCP
, "RO-INVOKE.INDICATION/%d: %s",
if (RyDsResult (sd
, rox
-> rox_id
, ryo
-> ryo_op
== operation_IMISC_echo
? in
: (caddr_t
) NULL
, ROS_NOPRIO
, roi
) == NOTOK
)
ros_adios (&roi
-> roi_preject
, "RESULT");
static int error (sd
, err
, param
, rox
, roi
)
struct RoSAPindication
*roi
;
if (RyDsError (sd
, rox
-> rox_id
, err
, param
, ROS_NOPRIO
, roi
) == NOTOK
)
ros_adios (&roi
-> roi_preject
, "ERROR");
static int ureject (sd
, reason
, rox
, roi
)
struct RoSAPindication
*roi
;
if (RyDsUReject (sd
, rox
-> rox_id
, reason
, ROS_NOPRIO
, roi
) == NOTOK
)
ros_adios (&roi
-> roi_preject
, "U-REJECT");
struct type_IMISC_IA5List
*str2ia5list (s
)
register struct type_IMISC_IA5List
*ia5
;
if ((ia5
= (struct type_IMISC_IA5List
*) calloc (1, sizeof *ia5
)) == NULL
)
if ((ia5
-> IA5String
= str2qb (s
, strlen (s
), 1)) == NULL
) {