home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume28 / advise / part01 < prev    next >
Encoding:
Text File  |  1992-02-22  |  52.9 KB  |  2,301 lines

  1. Newsgroups: comp.sources.misc
  2. From: ag@monique.bubble.org (Keith Gabryelski)
  3. Subject:  v28i070:  advise - Attach to another user, v2.0, Part01/02
  4. Message-ID: <csm-v28i070=advise.221330@sparky.IMD.Sterling.COM>
  5. X-Md4-Signature: e0f7d8b39d119422b99037865b9bd813
  6. Date: Mon, 24 Feb 1992 04:14:17 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: ag@monique.bubble.org (Keith Gabryelski)
  10. Posting-number: Volume 28, Issue 70
  11. Archive-name: advise/part01
  12. Environment: SunOS, SYSVR4i386
  13.  
  14. Advise attaches a user (the advisor) to another user's (the advisee)
  15. terminal in such a way the the advisor can type for the advisee and 
  16. view what the advisee's terminal is displaying.
  17.  
  18. The advisee would typically type ``advise  -a'' to allow advise attaches; 
  19. the advisor would then type ``advise user name'' which would connect the  
  20. advisors terminal the the advisee's.
  21.  
  22. All characters the advisor types are sent to the advisee's terminal
  23. as if the advisee typed them save the meta character.
  24.  
  25. Keith Gabryelski 
  26. ------------------
  27. #! /bin/sh
  28. # This is a shell archive.  Remove anything before this line, then feed it
  29. # into a shell via "sh file" or similar.  To overwrite existing files,
  30. # type "sh file -c".
  31. # The tool that generated this appeared in the comp.sources.unix newsgroup;
  32. # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
  33. # Contents:  COPYING Makefile.SUNOS Makefile.SVR4i386 advise.c advise.h
  34. #   advise.id advise.man advisedev.c advisemod.c advmod.id
  35. # Wrapped by kent@sparky on Sun Feb 23 21:54:18 1992
  36. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  37. echo If this archive is complete, you will see the following message:
  38. echo '          "shar: End of archive 1 (of 2)."'
  39. if test -f 'COPYING' -a "${1}" != "-c" ; then 
  40.   echo shar: Will not clobber existing file \"'COPYING'\"
  41. else
  42.   echo shar: Extracting \"'COPYING'\" \(7166 characters\)
  43.   sed "s/^X//" >'COPYING' <<'END_OF_FILE'
  44. X
  45. X            Advise GENERAL PUBLIC LICENSE
  46. X            (Clarified 11 Feb 1988)
  47. X
  48. X Copyright (C) 1988 Free Software Foundation, Inc.
  49. X Everyone is permitted to copy and distribute verbatim copies
  50. X of this license, but changing it is not allowed.  You can also
  51. X use this wording to make the terms for other programs.
  52. X
  53. X  The license agreements of most software companies keep you at the
  54. Xmercy of those companies.  By contrast, our general public license is
  55. Xintended to give everyone the right to share Advise.  To make sure that
  56. Xyou get the rights we want you to have, we need to make restrictions
  57. Xthat forbid anyone to deny you these rights or to ask you to surrender
  58. Xthe rights.  Hence this license agreement.
  59. X
  60. X  Specifically, we want to make sure that you have the right to give
  61. Xaway copies of Advise, that you receive source code or else can get it
  62. Xif you want it, that you can change Advise or use pieces of it in new
  63. Xfree programs, and that you know you can do these things.
  64. X
  65. X  To make sure that everyone has such rights, we have to forbid you to
  66. Xdeprive anyone else of these rights.  For example, if you distribute
  67. Xcopies of Advise, you must give the recipients all the rights that you
  68. Xhave.  You must make sure that they, too, receive or can get the
  69. Xsource code.  And you must tell them their rights.
  70. X
  71. X  Also, for our own protection, we must make certain that everyone
  72. Xfinds out that there is no warranty for Advise.  If Advise is modified by
  73. Xsomeone else and passed on, we want its recipients to know that what
  74. Xthey have is not what we distributed, so that any problems introduced
  75. Xby others will not reflect on our reputation.
  76. X
  77. X  Therefore we (Richard Stallman and the Free Software Foundation,
  78. XInc.) make the following terms which say what you must do to be
  79. Xallowed to distribute or change Advise.
  80. X
  81. X
  82. X            COPYING POLICIES
  83. X
  84. X  1. You may copy and distribute verbatim copies of Advise source code
  85. Xas you receive it, in any medium, provided that you conspicuously and
  86. Xappropriately publish on each copy a valid copyright notice "Copyright
  87. X(C) 1988 Free Software Foundation, Inc." (or with whatever year is
  88. Xappropriate); keep intact the notices on all files that refer to this
  89. XLicense Agreement and to the absence of any warranty; and give any
  90. Xother recipients of the Advise program a copy of this License
  91. XAgreement along with the program.  You may charge a distribution fee
  92. Xfor the physical act of transferring a copy.
  93. X
  94. X  2. You may modify your copy or copies of Advise or any portion of it,
  95. Xand copy and distribute such modifications under the terms of
  96. XParagraph 1 above, provided that you also do the following:
  97. X
  98. X    a) cause the modified files to carry prominent notices stating
  99. X    that you changed the files and the date of any change; and
  100. X
  101. X    b) cause the whole of any work that you distribute or publish,
  102. X    that in whole or in part contains or is a derivative of Advise or
  103. X    any part thereof, to be licensed at no charge to all third
  104. X    parties on terms identical to those contained in this License
  105. X    Agreement (except that you may choose to grant more extensive
  106. X    warranty protection to some or all third parties, at your option).
  107. X
  108. X    c) You may charge a distribution fee for the physical act of
  109. X    transferring a copy, and you may at your option offer warranty
  110. X    protection in exchange for a fee.
  111. X
  112. XMere aggregation of another unrelated program with this program (or its
  113. Xderivative) on a volume of a storage or distribution medium does not bring
  114. Xthe other program under the scope of these terms.
  115. X
  116. X  3. You may copy and distribute Advise (or a portion or derivative of it,
  117. Xunder Paragraph 2) in object code or executable form under the terms of
  118. XParagraphs 1 and 2 above provided that you also do one of the following:
  119. X
  120. X    a) accompany it with the complete corresponding machine-readable
  121. X    source code, which must be distributed under the terms of
  122. X    Paragraphs 1 and 2 above; or,
  123. X
  124. X    b) accompany it with a written offer, valid for at least three
  125. X    years, to give any third party free (except for a nominal
  126. X    shipping charge) a complete machine-readable copy of the
  127. X    corresponding source code, to be distributed under the terms of
  128. X    Paragraphs 1 and 2 above; or,
  129. X
  130. X    c) accompany it with the information you received as to where the
  131. X    corresponding source code may be obtained.  (This alternative is
  132. X    allowed only for noncommercial distribution and only if you
  133. X    received the program in object code or executable form alone.)
  134. X
  135. XFor an executable file, complete source code means all the source code for
  136. Xall modules it contains; but, as a special exception, it need not include
  137. Xsource code for modules which are standard libraries that accompany the
  138. Xoperating system on which the executable file runs.
  139. X
  140. X  4. You may not copy, sublicense, distribute or transfer Advise
  141. Xexcept as expressly provided under this License Agreement.  Any attempt
  142. Xotherwise to copy, sublicense, distribute or transfer Advise is void and
  143. Xyour rights to use the program under this License agreement shall be
  144. Xautomatically terminated.  However, parties who have received computer
  145. Xsoftware programs from you with this License Agreement will not have
  146. Xtheir licenses terminated so long as such parties remain in full compliance.
  147. X
  148. X  5. If you wish to incorporate parts of Advise into other free programs
  149. Xwhose distribution conditions are different, write to the Free Software
  150. XFoundation at 675 Mass Ave, Cambridge, MA 02139.  We have not yet worked
  151. Xout a simple rule that can be stated here, but we will often permit this.
  152. XWe will be guided by the two goals of preserving the free status of all
  153. Xderivatives of our free software and of promoting the sharing and reuse of
  154. Xsoftware.
  155. X
  156. XYour comments and suggestions about our licensing policies and our
  157. Xsoftware are welcome!  Please contact the Free Software Foundation, Inc.,
  158. X675 Mass Ave, Cambridge, MA 02139, or call (617) 876-3296.
  159. X
  160. X               NO WARRANTY
  161. X
  162. X  BECAUSE ADVISE IS LICENSED FREE OF CHARGE, WE PROVIDE ABSOLUTELY NO
  163. XWARRANTY, TO THE EXTENT PERMITTED BY APPLICABLE STATE LAW.  EXCEPT
  164. XWHEN OTHERWISE STATED IN WRITING, FREE SOFTWARE FOUNDATION, INC,
  165. XRICHARD M. STALLMAN AND/OR OTHER PARTIES PROVIDE ADVISE "AS IS" WITHOUT
  166. XWARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT
  167. XLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  168. XA PARTICULAR PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND
  169. XPERFORMANCE OF ADVISE IS WITH YOU.  SHOULD ADVISE PROVE DEFECTIVE, YOU
  170. XASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
  171. X
  172. X IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL RICHARD M.
  173. XSTALLMAN, THE FREE SOFTWARE FOUNDATION, INC., AND/OR ANY OTHER PARTY
  174. XWHO MAY MODIFY AND REDISTRIBUTE GNU SEND AS PERMITTED ABOVE, BE LIABLE TO
  175. XYOU FOR DAMAGES, INCLUDING ANY LOST PROFITS, LOST MONIES, OR OTHER
  176. XSPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR
  177. XINABILITY TO USE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA
  178. XBEING RENDERED INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR A
  179. XFAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS) GNU SEND, EVEN
  180. XIF YOU HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES, OR FOR
  181. XANY CLAIM BY ANY OTHER PARTY.
  182. END_OF_FILE
  183.   if test 7166 -ne `wc -c <'COPYING'`; then
  184.     echo shar: \"'COPYING'\" unpacked with wrong size!
  185.   fi
  186.   # end of 'COPYING'
  187. fi
  188. if test -f 'Makefile.SUNOS' -a "${1}" != "-c" ; then 
  189.   echo shar: Will not clobber existing file \"'Makefile.SUNOS'\"
  190. else
  191.   echo shar: Extracting \"'Makefile.SUNOS'\" \(787 characters\)
  192.   sed "s/^X//" >'Makefile.SUNOS' <<'END_OF_FILE'
  193. X
  194. XMODDIR=/etc/modules
  195. XBINDIR=/local/bin
  196. XMANDIR=/local/man/man1
  197. XMANEXT=.1
  198. X
  199. XINSTALL=install
  200. XINSTBIN=$(INSTALL) -o root -m 4111
  201. XINSTMAN=$(INSTALL) -m 444
  202. X
  203. XALL= advise advisedev.o
  204. X
  205. Xall: $(ALL)
  206. X
  207. Xadvise: advise.h advise.c
  208. X    cc -O -s -o advise advise.c
  209. X
  210. XCFLAGS= -O -DKERNEL -D`arch -k`
  211. X
  212. Xadvisedev.o: advisemod.c advisedev.c advise.h
  213. X
  214. Xclean:
  215. X    rm -f $(ALL)
  216. X
  217. Xinstall: $(ALL)
  218. X    $(INSTBIN) advise $(BINDIR)/advise
  219. X    $(INSTMAN) advise.man $(MANDIR)/advise$(MANEXT)
  220. X    if [ ! -d $(MODDIR) ]; then ( mkdir $(MODDIR) ); fi
  221. X    install -m 444 advisedev.o $(MODDIR)/advise.o
  222. X    install -m 555 advise.exec $(MODDIR)/advise.exec
  223. X    @echo ""
  224. X    @echo "The following line should be placed somewhere near the end in /etc/rc.local:"
  225. X    @echo ""
  226. X    @echo "/usr/etc/modload $(MODDIR)/advise.o -exec $(MODDIR)/advise.exec"
  227. X    @echo ""
  228. END_OF_FILE
  229.   if test 787 -ne `wc -c <'Makefile.SUNOS'`; then
  230.     echo shar: \"'Makefile.SUNOS'\" unpacked with wrong size!
  231.   fi
  232.   # end of 'Makefile.SUNOS'
  233. fi
  234. if test -f 'Makefile.SVR4i386' -a "${1}" != "-c" ; then 
  235.   echo shar: Will not clobber existing file \"'Makefile.SVR4i386'\"
  236. else
  237.   echo shar: Extracting \"'Makefile.SVR4i386'\" \(710 characters\)
  238.   sed "s/^X//" >'Makefile.SVR4i386' <<'END_OF_FILE'
  239. X
  240. XBINDIR=/local/bin
  241. XMANDIR=/local/man/man1
  242. XMANEXT=.1
  243. X
  244. XINSTALL=/usr/ucb/install
  245. XINSTBIN=$(INSTALL) -o root -m 4111
  246. XINSTMAN=$(INSTALL) -m 444
  247. X
  248. XIDINSTALL=/etc/conf/bin/idinstall
  249. X
  250. XKOBJS=advisedev.o advisemod.o
  251. XCFLAGS= -O -D_KERNEL -DINKERNEL
  252. X
  253. XALL=$(KOBJS) advise
  254. X
  255. Xall: $(ALL)
  256. X
  257. Xadvisedev.o: advise.h
  258. X
  259. Xadvisemod.o: advise.h
  260. X
  261. Xadvise: advise.h advise.c
  262. X    cc -O -s -o advise advise.c
  263. X    -mcs -d advise
  264. X
  265. Xclean:
  266. X    rm -f $(ALL)
  267. X
  268. Xinstall: install.kernel install.user
  269. X
  270. Xinstall.kernel: $(KOBJS)
  271. X    -$(IDINSTALL) -d advise
  272. X    cd advise.id; $(IDINSTALL) -ka advise
  273. X    -$(IDINSTALL) -d advmod
  274. X    cd advmod.id; $(IDINSTALL) -ka advmod
  275. X
  276. Xinstall.user: advise
  277. X    $(INSTBIN) advise $(BINDIR)/advise
  278. X    $(INSTMAN) advise.man $(MANDIR)/advise$(MANEXT)
  279. END_OF_FILE
  280.   if test 710 -ne `wc -c <'Makefile.SVR4i386'`; then
  281.     echo shar: \"'Makefile.SVR4i386'\" unpacked with wrong size!
  282.   fi
  283.   # end of 'Makefile.SVR4i386'
  284. fi
  285. if test -f 'advise.c' -a "${1}" != "-c" ; then 
  286.   echo shar: Will not clobber existing file \"'advise.c'\"
  287. else
  288.   echo shar: Extracting \"'advise.c'\" \(15710 characters\)
  289.   sed "s/^X//" >'advise.c' <<'END_OF_FILE'
  290. X/* Copyright (C) 1990 Keith Gabryelski (ag@amix.commodore.com)
  291. X
  292. XThis file is part of advise.
  293. X
  294. Xadvise is distributed in the hope that it will be useful,
  295. Xbut WITHOUT ANY WARRANTY.  No author or distributor
  296. Xaccepts responsibility to anyone for the consequences of using it
  297. Xor for whether it serves any particular purpose or works at all,
  298. Xunless he says so in writing.  Refer to the advise General Public
  299. XLicense for full details.
  300. X
  301. XEveryone is granted permission to copy, modify and redistribute
  302. Xadvise, but only under the conditions described in the
  303. Xadvise General Public License.   A copy of this license is
  304. Xsupposed to have been given to you along with advise so you
  305. Xcan know your rights and responsibilities.  It should be in a
  306. Xfile named COPYING.  Among other things, the copyright notice
  307. Xand this notice must be preserved on all copies.  */
  308. X
  309. X/*
  310. X** Author:    Keith Gabryelski    (ag@amix.commodore.com)
  311. X*/
  312. X
  313. X#include <sys/types.h>
  314. X#include <sys/stat.h>
  315. X#include <signal.h>
  316. X#include <stdio.h>
  317. X#include <stdlib.h>
  318. X#include <unistd.h>
  319. X#include <fcntl.h>
  320. X#include <stropts.h>
  321. X#include <poll.h>
  322. X#include <sys/stream.h>
  323. X#include <errno.h>
  324. X#include <utmp.h>
  325. X#include <pwd.h>
  326. X#include <termios.h>
  327. X#include <string.h>
  328. X#include <ctype.h>
  329. X#include "advise.h"
  330. X
  331. X#ifdef sun
  332. Xextern int optind;
  333. X
  334. X#ifndef CTRL
  335. X#define    CTRL(c)    ((c)&037)
  336. X#endif /* !CTRL */
  337. X
  338. X#ifndef EUNATCH
  339. X#define EUNATCH ENOPROTOOPT
  340. X#endif /* ! EUNATCH */
  341. X
  342. X#endif /* sun */
  343. X
  344. Xextern char *optarg;
  345. X
  346. X#define max(a,b) ((a)>(b)?(a):(b))
  347. X
  348. Xstatic struct module_list
  349. X{
  350. X    char *name;            /* name of module */
  351. X    struct module_list *next;    /* next module to be pushed */
  352. X} advise_module_list =
  353. X{
  354. X    ADVMODNAME, NULL,
  355. X};
  356. X
  357. X#ifdef __STDC__
  358. X#define PR_(x)    x
  359. X#else
  360. X#define PR_(x)    ()
  361. X#endif /* __STDC__ */
  362. X
  363. Xstatic void usage PR_( (void) ), advise PR_( (char *) );
  364. Xstatic char *strchar PR_( (char) );
  365. Xstatic struct module_list *list_modules PR_( (int, char *));
  366. X
  367. Xstatic int allow_deny_p, allow_deny;
  368. Xstatic int allow_advise_p, allow_advise;
  369. Xstatic int error_flag;
  370. Xstatic int secret, spy, reverse;
  371. Xstatic int meta_character = '~';
  372. Xstatic char *progname;
  373. Xstatic char *module = "ldterm";
  374. X
  375. X#ifdef sun
  376. X
  377. X#ifndef __STDC__
  378. X/*
  379. X * strerror - map error number to descriptive string
  380. X * (stolen from cnews/libfake/strerror.c)
  381. X *
  382. X */
  383. Xstatic char *
  384. Xstrerror(errnum)
  385. Xint errnum;
  386. X{
  387. X    extern int sys_nerr;
  388. X    extern char *sys_errlist[];
  389. X
  390. X    if (errnum > 0 && errnum < sys_nerr)
  391. X        return(sys_errlist[errnum]);
  392. X    else if (errnum != 0)
  393. X        return("unknown error");
  394. X    else
  395. X        return("no details given");
  396. X}
  397. X#endif /* ! __STDC__ */
  398. X
  399. Xstatic int utmpfd=-1;
  400. X
  401. Xvoid
  402. Xendutent(
  403. X#ifdef __STDC__
  404. X    void
  405. X#endif /* __STDC__ */
  406. X    )
  407. X{
  408. X    if(utmpfd!=-1) close(utmpfd);
  409. X    utmpfd=-1;
  410. X}
  411. X
  412. Xvoid
  413. Xsetutent(
  414. X#ifdef __STDC__
  415. X    void
  416. X#endif /* __STDC__ */
  417. X    )
  418. X{
  419. X    endutent();
  420. X    utmpfd=open("/etc/utmp", O_RDONLY);
  421. X}
  422. X
  423. Xstruct utmp *
  424. Xgetutent(
  425. X#ifdef __STDC__
  426. X    void
  427. X#endif /* __STDC__ */
  428. X    )
  429. X{
  430. X    static struct utmp ut;
  431. X    int ret;
  432. X
  433. X    if(utmpfd==-1) return(NULL);
  434. X    do {
  435. X        if(read(utmpfd, &ut, sizeof(ut)) != sizeof(ut)) return(NULL);
  436. X    } while(nonuser(ut));
  437. X
  438. X    return(&ut);
  439. X}
  440. X
  441. Xstruct utmp *
  442. X#ifdef __STDC__
  443. Xgetutline(struct utmp *ut)
  444. X#else
  445. Xgetutline(ut)
  446. Xstruct utmp *ut;
  447. X#endif /* __STDC__ */
  448. X{
  449. X    struct utmp *utm;
  450. X
  451. X    while(utm=getutent())
  452. X        if(!strncmp(utm->ut_line, ut->ut_line)) return(utm);
  453. X
  454. X    return(NULL);
  455. X}
  456. X#endif /* sun */
  457. X
  458. Xint
  459. X#ifdef __STDC__
  460. Xmain(int argc, char **argv)
  461. X#else
  462. Xmain(argc, argv)
  463. Xchar **argv;
  464. X#endif /* __STDC__ */
  465. X{
  466. X    int c, error=0;
  467. X    struct termios termios;
  468. X    struct module_list *modules;
  469. X
  470. X    progname = *argv;
  471. X
  472. X    while((c = getopt(argc, argv, "ADM:Sardm:s?")) != EOF)
  473. X    {
  474. X    switch(c)
  475. X    {
  476. X    case 's':
  477. X        spy++;
  478. X        break;
  479. X
  480. X    case 'r':
  481. X        if (!getuid())
  482. X        reverse++;
  483. X        else
  484. X        {
  485. X        (void) fprintf(stderr, "%s: -r option only available to the super user\n", progname);
  486. X        error_flag++;
  487. X        }
  488. X        break;
  489. X
  490. X    case 'S':
  491. X        if (!getuid())
  492. X        secret++;
  493. X        else
  494. X        {
  495. X        (void) fprintf(stderr, "%s: -S option only available to the super user\n", progname);
  496. X        error_flag++;
  497. X        }
  498. X        break;
  499. X
  500. X    case 'a':
  501. X        allow_deny_p++;
  502. X        allow_deny=ADVISE_ALLOW;
  503. X        allow_advise_p++;
  504. X        allow_advise++;
  505. X        break;
  506. X
  507. X    case 'd':
  508. X        allow_advise_p++;
  509. X        allow_advise=0;
  510. X        break;
  511. X
  512. X    case 'A':
  513. X        allow_deny_p++;
  514. X        allow_deny=ADVISE_ALLOW;
  515. X        break;
  516. X
  517. X    case 'D':
  518. X        allow_deny_p++;
  519. X        allow_deny=ADVISE_DENY;
  520. X        break;
  521. X
  522. X    case 'm':
  523. X        meta_character = optarg[0];
  524. X        break;
  525. X
  526. X    case 'M':
  527. X        module = optarg;
  528. X        break;
  529. X
  530. X    case '?':
  531. X        error_flag++;
  532. X        break;
  533. X    }
  534. X
  535. X    if (error_flag)
  536. X    {
  537. X        usage();
  538. X    }
  539. X    }
  540. X
  541. X    if (allow_advise_p)
  542. X    {
  543. X    int status = ioctl(0, ADVISE_STATUS, &status);
  544. X
  545. X    if (allow_advise && status)
  546. X    {
  547. X        int advise_module_pushed = 0;
  548. X
  549. X        /* Push advise module on stream */
  550. X        (void) ioctl(0, TCGETS, &termios);
  551. X
  552. X        modules = list_modules(0, module);
  553. X
  554. X        advise_module_list.next = modules;
  555. X
  556. X        for (modules = &advise_module_list;
  557. X         modules != NULL;
  558. X         modules = modules->next)
  559. X        {
  560. X
  561. X        if (!strcmp(modules->name, ADVMODNAME))
  562. X        {
  563. X            if (advise_module_pushed)
  564. X            continue;
  565. X
  566. X            advise_module_pushed = 1;
  567. X        }
  568. X
  569. X        if (ioctl(0, I_PUSH, modules->name))
  570. X        {
  571. X            (void) fprintf(stderr, "%s: Couldn't I_PUSH: %s (%s).\n",
  572. X                   progname, modules->name, strerror(errno));
  573. X            error++;
  574. X        }
  575. X        }
  576. X
  577. X        (void) ioctl(0, TCSETS, &termios);
  578. X    }
  579. X
  580. X    if (!allow_advise && !status)
  581. X    {
  582. X        (void) ioctl(0, TCGETS, &termios);
  583. X
  584. X        modules = list_modules(0, ADVMODNAME);
  585. X
  586. X        while (modules != NULL)
  587. X        {
  588. X        if (strcmp(modules->name, ADVMODNAME))
  589. X        {
  590. X            if (ioctl(0, I_PUSH, modules->name))
  591. X            {
  592. X            (void) fprintf(stderr,
  593. X                       "%s: Couldn't I_PUSH: %s (%s).\n",
  594. X                       progname, modules->name,
  595. X                       strerror(errno));
  596. X            error++;
  597. X            }
  598. X        }
  599. X
  600. X        modules = modules->next;
  601. X        }
  602. X
  603. X        (void) ioctl(0, TCSETS, &termios);
  604. X    }
  605. X
  606. X    if (!allow_deny_p)
  607. X        return error ? 1 : 0;
  608. X    }
  609. X
  610. X    if (allow_deny_p)
  611. X    {
  612. X    if (ioctl(0, allow_deny, 0))
  613. X    {
  614. X        if (errno == EINVAL)
  615. X        {
  616. X        (void) fprintf(stderr, "%s: module \"%s\" not in stream.\n",
  617. X                   progname, ADVMODNAME);
  618. X        }
  619. X        else
  620. X        {
  621. X        (void) fprintf(stderr, "%s: Couldn't set advisory mode (%s).\n",
  622. X                   progname, strerror(errno));
  623. X        }
  624. X
  625. X        return 1;
  626. X    }
  627. X
  628. X    goto advstat;
  629. X    }
  630. X
  631. X    /* All switches have been handled */
  632. X
  633. X    argc -= optind;
  634. X    argv += optind;
  635. X
  636. X    if (argc > 1)
  637. X    {
  638. X    usage();
  639. X    }
  640. X
  641. X    if (argc == 0)
  642. X    {
  643. X    int retval, status;
  644. X
  645. Xadvstat:
  646. X    /*
  647. X    ** Status of advise.
  648. X    */
  649. X
  650. X    retval = ioctl(0, ADVISE_STATUS, &status);
  651. X#if !defined(M_COPYOUT) && !defined(sun)
  652. X    status = !retval;
  653. X#endif /* n M_COPYOUT */
  654. X
  655. X    if (retval)
  656. X    {
  657. X        printf("Module \"%s\" not pushed on stream.\n", ADVMODNAME);
  658. X    }
  659. X    else
  660. X    {
  661. X        printf("Advise access %s\n", status ? "allowed" : "denied");
  662. X    }
  663. X
  664. X    return 0;
  665. X    }
  666. X
  667. X    advise(*argv);
  668. X
  669. X    return 0;
  670. X}
  671. X
  672. Xstatic void
  673. Xusage(
  674. X#ifdef __STDC__
  675. X    void
  676. X#endif /* __STDC__ */
  677. X    )
  678. X{
  679. X    (void) fprintf(stderr, "usage: %s [-ADad?] [-M module] | [-Ssr] [-m char] [ device | username ]\n",
  680. X           progname);
  681. X    exit(1);
  682. X}
  683. X
  684. Xstruct termios termios, oldtermios;
  685. X
  686. Xvoid restoretermios(sig)
  687. X{
  688. X    (void) ioctl(0, TCSETS, &oldtermios);
  689. X    exit(0);
  690. X}
  691. X
  692. Xstatic void
  693. X#ifdef __STDC__
  694. Xadvise(char *who)
  695. X#else
  696. Xadvise(who)
  697. Xchar *who;
  698. X#endif /* __STDC__ */
  699. X{
  700. X    int ret, fd, metad=0;
  701. X    char buf[1024], *device=NULL, *devname, *login_name, *tty_name;
  702. X    struct pollfd pfds[2];
  703. X    struct stat stbuf;
  704. X    struct utmp *ut, uts;
  705. X    char username[sizeof(ut->ut_name) + 1];
  706. X
  707. X    username[0] = '\0';
  708. X
  709. X    if (*who == '/') /* full path name */
  710. X    device = who;
  711. X    else
  712. X    {
  713. X    /* Either this is /dev/ + who OR a username */
  714. X
  715. X    setutent();
  716. X
  717. X    while ((ut = getutent()) != NULL)
  718. X    {
  719. X        if (
  720. X#ifdef USER_PROCESS
  721. X        (ut->ut_type==USER_PROCESS) &&
  722. X#endif /* USER_PROCESS */
  723. X        (!strncmp(who, ut->ut_name, sizeof(ut->ut_name))))
  724. X        {
  725. X        if(device) free(device);
  726. X        device = (char *)malloc(sizeof("/dev/") +
  727. X                    sizeof(ut->ut_line));
  728. X
  729. X        if (device == NULL)
  730. X        {
  731. X            (void) fprintf(stderr,
  732. X                "%s: malloc failed (Out of Memory)\n",
  733. X                progname);
  734. X
  735. X            exit(1);
  736. X        }
  737. X
  738. X        strcpy(device, "/dev/");
  739. X        strncat(device, ut->ut_line, sizeof(ut->ut_line));
  740. X        device[sizeof("/dev/")+sizeof(ut->ut_line)] = '\0';
  741. X
  742. X        strncpy(username, ut->ut_name, sizeof(ut->ut_name));
  743. X        username[sizeof(ut->ut_name)] = '\0';
  744. X        if(!strcmp(device, ttyname(0))) continue;
  745. X        break;
  746. X        }
  747. X    }
  748. X
  749. X    if (device == NULL) /* Is /dev/ + who */
  750. X    {
  751. X        device = (char *)malloc(sizeof("/dev/") + strlen(who));
  752. X
  753. X        if (device == NULL)
  754. X        {
  755. X        (void) fprintf(stderr, "%s: malloc failed (Out of Memory)\n",
  756. X                progname);
  757. X
  758. X        exit(1);
  759. X        }
  760. X
  761. X        strcpy(device, "/dev/");
  762. X        strcat(device, who);
  763. X    }
  764. X
  765. X    endutent();
  766. X    }
  767. X
  768. X    devname = device + sizeof("/dev/") - 1;
  769. X
  770. X    if (username[0] == '\0')
  771. X    {
  772. X    setutent();
  773. X
  774. X    strncpy(uts.ut_line, devname, sizeof(uts.ut_line));
  775. X
  776. X    if ((ut = getutline(&uts)) != NULL)
  777. X    {
  778. X        strncpy(username, ut->ut_name, sizeof(ut->ut_name));
  779. X        username[sizeof(ut->ut_name)] = '\0';
  780. X    }
  781. X    else
  782. X    {
  783. X        strcpy(username, "unknown");
  784. X    }
  785. X
  786. X    endutent();
  787. X    }
  788. X
  789. X    if(!strcmp(device, ttyname(0)))
  790. X    {
  791. X    (void) fprintf(stderr, "%s: Can't advise yourself!\n", progname);
  792. X    exit(1);
  793. X    }
  794. X
  795. X    if (stat(device, &stbuf) < 0)
  796. X    {
  797. X    if (errno == ENOENT)
  798. X    {
  799. X        if(*who=='/') (void) fprintf(stderr, "%s: no advisee device \"%s\"\n", progname, device);
  800. X        else (void) fprintf(stderr, "%s: unknown user \"%s\" or no advisee device \"%s\"\n", progname, who, device);
  801. X    }
  802. X    else
  803. X    {
  804. X        (void) fprintf(stderr,
  805. X               "%s: Couldn't stat() advisee device: %s (%s)\n",
  806. X               progname, device, strerror(errno));
  807. X    }
  808. X    exit(1);
  809. X    }
  810. X
  811. X    if ((fd = open("/dev/advise", O_RDWR|O_NONBLOCK)) < 0)
  812. X    {
  813. X    (void) fprintf(stderr,
  814. X           "%s: Couldn't open advisory device: /dev/advise (%s)\n",
  815. X           progname, strerror(errno));
  816. X    exit(1);
  817. X    }
  818. X    setuid(getuid());
  819. X
  820. X    if (ioctl(fd, reverse?ADVISE_SETADVISEERD:ADVISE_SETADVISEEWR, 
  821. X#ifdef sun
  822. X    &
  823. X#endif /* sun */
  824. X    stbuf.st_rdev))
  825. X    {
  826. X    if (errno == EUNATCH)
  827. X    {
  828. X        (void) fprintf(stderr,
  829. X               "%s: module \"%s\" not in place for %s\n",
  830. X               progname, ADVMODNAME, device);
  831. X    } else if (errno == EACCES)
  832. X    {
  833. X        (void) fprintf(stderr, "%s: Permission denied\n", progname);
  834. X    } else
  835. X    {
  836. X        (void) fprintf(stderr,
  837. X               "%s: Couldn't set advisee: %s (%lu, %lu) (%s)\n",
  838. X            progname, device,
  839. X#ifdef sun
  840. X            major(stbuf.st_rdev), minor(stbuf.st_rdev),
  841. X#else
  842. X            ((stbuf.st_rdev >> 16) &0xFFFF), (stbuf.st_rdev&0xFFFF),
  843. X#endif /* sun */
  844. X            strerror(errno));
  845. X    }
  846. X    exit(1);
  847. X    }
  848. X
  849. X    if (!secret)
  850. X    {
  851. X    char *str;
  852. X    struct passwd *pt;
  853. X
  854. X    if ((login_name = getlogin()) == NULL)
  855. X    {
  856. X        pt = getpwuid(getuid());
  857. X
  858. X        if (pt == NULL || pt->pw_name == NULL)
  859. X        {
  860. X        login_name = "somebody";
  861. X        }
  862. X        else
  863. X        {
  864. X        login_name = pt->pw_name;
  865. X        }
  866. X    }
  867. X
  868. X    if ((tty_name = ttyname(2)) != NULL)
  869. X    {
  870. X        if (!strncmp(tty_name, "/dev/", sizeof("/dev/")-1))
  871. X        tty_name += sizeof("/dev/")-1;
  872. X    }
  873. X    else
  874. X        tty_name = "somewhere";
  875. X
  876. X    str = malloc(strlen(login_name) + strlen(tty_name) +
  877. X             sizeof("[: advising :]\n\r") + strlen(username) +
  878. X             strlen(devname));
  879. X
  880. X    if (str)
  881. X    {
  882. X        struct advise_message m;
  883. X        struct strbuf ctl, data;
  884. X
  885. X        m.type = ADVISE_READDATA;
  886. X
  887. X        ctl.len = sizeof(m);
  888. X        ctl.buf = (void *)&m;
  889. X
  890. X        sprintf(str, "[%s:%s %s %s:%s]\n\r", login_name,
  891. X            tty_name, spy ? "spying" : "advising", username, devname);
  892. X
  893. X        data.len = strlen(str);
  894. X        data.buf = str;
  895. X
  896. X        (void) putmsg(fd, &ctl, &data, 0);
  897. X
  898. X        free(str);
  899. X    }
  900. X    }
  901. X
  902. X
  903. X    (void) ioctl(0, TCGETS, &termios);
  904. X
  905. X    oldtermios = termios;
  906. X    signal(SIGTERM, restoretermios);
  907. X    termios.c_oflag &= ~OPOST;
  908. X
  909. X    if (!spy)
  910. X    {
  911. X    termios.c_cc[VMIN] = 1;
  912. X    termios.c_cc[VTIME] = 0;
  913. X    termios.c_lflag &= ~(ISIG|ICANON|ECHO);
  914. X    } else signal(SIGINT, restoretermios);
  915. X    (void) ioctl(0, TCSETS, &termios);
  916. X
  917. X    pfds[0].fd = fd;
  918. X    pfds[0].events = POLLIN;
  919. X
  920. X    pfds[1].fd = 0;
  921. X    pfds[1].events = POLLIN;
  922. X
  923. X    for (;;)
  924. X    {
  925. X    if (poll(pfds, spy?1:2, INFTIM) < 0)
  926. X        continue;
  927. X
  928. X    if ((pfds[0].revents&POLLHUP) != 0) /* module removed */
  929. X    {
  930. X        (void) ioctl(0, TCSETS, &oldtermios);
  931. X        exit(0);
  932. X    }
  933. X    if ((pfds[0].revents&POLLIN) != 0) /* data from advisee ready */
  934. X    {
  935. X        if ((ret = read(fd, buf, sizeof(buf))) > 0)
  936. X        write(1, buf, ret);
  937. X    }
  938. X
  939. X    if (!spy && ((pfds[1].revents&POLLIN) != 0)) /* data from advisor ready */
  940. X    {
  941. X        if ((ret = read(0, buf, sizeof(buf))) > 0)
  942. X        {
  943. X            register int i;
  944. X            register char *p = buf, *pp=buf;
  945. X
  946. X            for (i=0; i < ret; ++i, p++)
  947. X            {
  948. X            if (metad)
  949. X            {
  950. X                if (metad == 2)
  951. X                {
  952. X                meta_character = *p;
  953. X                printf("The meta character is now: %s\n",
  954. X                       strchar(meta_character));
  955. X                pp++;
  956. X                metad = 0;
  957. X                continue;
  958. X                }
  959. X
  960. X                switch (*p)
  961. X                {
  962. X                case '=':
  963. X                metad=2;
  964. X                pp++;
  965. X                break;
  966. X
  967. X                case '?':
  968. X                {
  969. X                char *escstr = strchar(meta_character);
  970. X
  971. X                printf("Help for meta character <%s>:\n",
  972. X                       escstr);
  973. X                printf("%s?\t-- This help message.\n", escstr);
  974. X                printf("%s~\t-- Send a single meta character.\n",
  975. X                       escstr);
  976. X                printf("%s.\t-- Disconnect advise session.\n",
  977. X                       escstr);
  978. X                printf("%s=C\t-- Change meta character to C.\n",
  979. X                       escstr);
  980. X                printf("%s^Z\t-- Suspend advise session.\n",
  981. X                       escstr);
  982. X                pp++;
  983. X                metad=0;
  984. X                break;
  985. X                }
  986. X
  987. X                case '.':
  988. X                {
  989. X                if (!secret)
  990. X                {
  991. X                    char *str;
  992. X
  993. X                    str = malloc(strlen(login_name) +
  994. X                      strlen(tty_name) +
  995. X                      sizeof("[: disconnecting from :]\n") +
  996. X                           strlen(username) + strlen(devname));
  997. X
  998. X                    if (str)
  999. X                    {
  1000. X                    struct advise_message m;
  1001. X                    struct strbuf ctl, data;
  1002. X
  1003. X                    m.type = ADVISE_READDATA;
  1004. X
  1005. X                    ctl.len = sizeof(m);
  1006. X                    ctl.buf = (void *)&m;
  1007. X
  1008. X                    sprintf(str, "[%s:%s disconnecting from %s:%s]\n\r",
  1009. X                        login_name, tty_name, username,
  1010. X                        devname);
  1011. X
  1012. X                    data.len = strlen(str);
  1013. X                    data.buf = str;
  1014. X
  1015. X                    (void) putmsg(fd, &ctl, &data, 0);
  1016. X
  1017. X                    free(str);
  1018. X                    }
  1019. X                }
  1020. X
  1021. X                close(fd);
  1022. X
  1023. X                (void) ioctl(0, TCSETS, &oldtermios);
  1024. X
  1025. X                exit(0);
  1026. X                }
  1027. X
  1028. X                case CTRL('Z'):
  1029. X                {
  1030. X                (void) ioctl(0, TCSETS, &oldtermios);
  1031. X                (void) signal(SIGTSTP, SIG_DFL);
  1032. X                (void) kill(0, SIGTSTP);
  1033. X                (void) ioctl(0, TCSETS, &termios);
  1034. X                pp++;
  1035. X                metad=0;
  1036. X                break;
  1037. X                }
  1038. X
  1039. X                default:
  1040. X                metad=0;
  1041. X                break;
  1042. X                }
  1043. X            }
  1044. X            else
  1045. X            {
  1046. X                if (*p == meta_character)
  1047. X                {
  1048. X                int d = p - pp;
  1049. X
  1050. X                metad=1;
  1051. X
  1052. X                if (d) write(fd, pp, d);
  1053. X
  1054. X                pp += d + 1;
  1055. X                i += d;
  1056. X                }
  1057. X            }
  1058. X            }
  1059. X
  1060. X            if (p - pp) write(fd, pp, p-pp);
  1061. X        }
  1062. X    }
  1063. X    }
  1064. X}
  1065. X
  1066. Xstatic struct module_list *
  1067. X#ifdef __STDC__
  1068. Xlist_modules(int fd, char *push_below)
  1069. X#else
  1070. Xlist_modules(fd, push_below)
  1071. Xchar *push_below;
  1072. X#endif /* __STDC__ */
  1073. X{
  1074. X    char lookbuf[max(FMNAMESZ+1,256)];
  1075. X    struct module_list *mp, *mpp;
  1076. X
  1077. X    mp = NULL;
  1078. X
  1079. X    while (ioctl(fd, I_LOOK, lookbuf) == 0)
  1080. X    {
  1081. X    if (ioctl(fd, I_POP, 0))
  1082. X    {
  1083. X        (void) fprintf(stderr, "%s: Couldn't I_POP: %s (%s).\n", progname,
  1084. X               lookbuf, strerror(errno));
  1085. X        return mp;
  1086. X    }
  1087. X
  1088. X    if ((mpp = (struct module_list *)malloc(sizeof(struct module_list)))
  1089. X        == NULL || (mpp->name = malloc(strlen(lookbuf) + 1)) == NULL)
  1090. X    {
  1091. X        (void) fprintf(stderr, "%s: Couldn't malloc (out of memory).\n",
  1092. X               progname);
  1093. X        return mp;
  1094. X    }
  1095. X
  1096. X    mpp->next = mp;
  1097. X    mp = mpp;
  1098. X
  1099. X    strcpy(mp->name, lookbuf);
  1100. X
  1101. X    if (!strcmp(push_below, lookbuf))
  1102. X        break;
  1103. X    }
  1104. X
  1105. X    return mp;
  1106. X}
  1107. X
  1108. Xstatic char *
  1109. X#ifdef __STDC__
  1110. Xstrchar(char character)
  1111. X#else
  1112. Xstrchar(character)
  1113. Xchar character;
  1114. X#endif /* __STDC__ */
  1115. X{
  1116. X    static char retbuf[4];
  1117. X    char *p = retbuf;
  1118. X    int capit = 0;
  1119. X
  1120. X    if (!isascii(character))
  1121. X    {
  1122. X    *p++ = '~';
  1123. X    capit = 1;
  1124. X    character = toascii(character);
  1125. X    }
  1126. X
  1127. X    if (iscntrl(character))
  1128. X    {
  1129. X    *p++ = '^';
  1130. X    capit = 1;
  1131. X    character += '@';
  1132. X    }
  1133. X
  1134. X    if (capit)
  1135. X    *p++ = toupper(character);
  1136. X    else
  1137. X    *p++ = character;
  1138. X
  1139. X    *p = '\0';
  1140. X
  1141. X    return retbuf;
  1142. X}
  1143. END_OF_FILE
  1144.   if test 15710 -ne `wc -c <'advise.c'`; then
  1145.     echo shar: \"'advise.c'\" unpacked with wrong size!
  1146.   fi
  1147.   # end of 'advise.c'
  1148. fi
  1149. if test -f 'advise.h' -a "${1}" != "-c" ; then 
  1150.   echo shar: Will not clobber existing file \"'advise.h'\"
  1151. else
  1152.   echo shar: Extracting \"'advise.h'\" \(2277 characters\)
  1153.   sed "s/^X//" >'advise.h' <<'END_OF_FILE'
  1154. X/* Copyright (C) 1990 Keith Gabryelski (ag@amix.commodore.com)
  1155. X
  1156. XThis file is part of advise.
  1157. X
  1158. Xadvise is distributed in the hope that it will be useful,
  1159. Xbut WITHOUT ANY WARRANTY.  No author or distributor
  1160. Xaccepts responsibility to anyone for the consequences of using it
  1161. Xor for whether it serves any particular purpose or works at all,
  1162. Xunless he says so in writing.  Refer to the advise General Public
  1163. XLicense for full details.
  1164. X
  1165. XEveryone is granted permission to copy, modify and redistribute
  1166. Xadvise, but only under the conditions described in the
  1167. Xadvise General Public License.   A copy of this license is
  1168. Xsupposed to have been given to you along with advise so you
  1169. Xcan know your rights and responsibilities.  It should be in a
  1170. Xfile named COPYING.  Among other things, the copyright notice
  1171. Xand this notice must be preserved on all copies.  */
  1172. X
  1173. X/*
  1174. X** Author:    Keith Gabryelski    (ag@amix.commodore.com)
  1175. X*/
  1176. X
  1177. Xstruct advise_queue_list
  1178. X{
  1179. X    mblk_t            *savbp;    /* ptr to this mblk for freeb()ing */
  1180. X    queue_t            *q;    /* advisor's queue */
  1181. X    int                minord; /* minor device for this advisor */
  1182. X    int                wdir;    /* direction of writes */
  1183. X    struct advise_state        *state; /* ptr back to advise_state struct */
  1184. X    struct advise_queue_list    *next;  /* ptr to next advisor */
  1185. X};
  1186. X
  1187. Xstruct advise_state
  1188. X{
  1189. X    mblk_t            *savbp;    /* ptr to this mblk for freeb()ing */
  1190. X    int                status;    /* current status */
  1191. X    dev_t            dev;    /* our device */
  1192. X    queue_t            *q;    /* queue for advisor writing */
  1193. X    struct advise_queue_list    *q_wlist, *q_rlist; /* lists of spies */
  1194. X    struct advise_state        *next;  /* next in advise_table */
  1195. X};
  1196. X
  1197. X#define ALLOW_ADVICE        (0x01)
  1198. X
  1199. Xstruct advise_message
  1200. X{
  1201. X    int                type;   /* What type of data is this? */
  1202. X};
  1203. X
  1204. X#define ADVISE_DATA        (0x00)
  1205. X#define ADVISE_READDATA        (0x01)
  1206. X
  1207. X#ifdef sun
  1208. X#define ADVISE_SETADVISEEWR    _IOW(z, 1, dev_t)
  1209. X#define ADVISE_SETADVISEERD    _IOW(z, 2, dev_t)
  1210. X#define    ADVISE_ALLOW        _IO(z, 3)
  1211. X#define    ADVISE_DENY        _IO(z, 4)
  1212. X#define    ADVISE_STATUS        _IOR(z, 5, int)
  1213. X#else
  1214. X#define ADVISE            ('z'<<16)
  1215. X#define ADVISE_SETADVISEEWR    (ADVISE|0x01)
  1216. X#define ADVISE_SETADVISEERD    (ADVISE|0x02)
  1217. X#define    ADVISE_ALLOW        (ADVISE|0x03)
  1218. X#define    ADVISE_DENY        (ADVISE|0x04)
  1219. X#define ADVISE_STATUS        (ADVISE|0x05)
  1220. X#endif /* sun */
  1221. X
  1222. X#define spladvise    spltty
  1223. X
  1224. X#define ADVMODNAME    "advmod"
  1225. END_OF_FILE
  1226.   if test 2277 -ne `wc -c <'advise.h'`; then
  1227.     echo shar: \"'advise.h'\" unpacked with wrong size!
  1228.   fi
  1229.   # end of 'advise.h'
  1230. fi
  1231. if test ! -d 'advise.id' ; then
  1232.     echo shar: Creating directory \"'advise.id'\"
  1233.     mkdir 'advise.id'
  1234. fi
  1235. if test -f 'advise.man' -a "${1}" != "-c" ; then 
  1236.   echo shar: Will not clobber existing file \"'advise.man'\"
  1237. else
  1238.   echo shar: Extracting \"'advise.man'\" \(2161 characters\)
  1239.   sed "s/^X//" >'advise.man' <<'END_OF_FILE'
  1240. X.TH advise 1
  1241. X.SH NAME
  1242. Xadvise \- Attach to another user.
  1243. X.SH SYNOPSIS
  1244. X.B advise
  1245. X[-ADad?] [-M module] | [-Ss] [-m char] [ device | username ]
  1246. X.SH DESCRIPTION
  1247. X.B Advise
  1248. Xattaches a user (the advisor) to another user's (the advisee) terminal in
  1249. Xsuch a way the the advisor can type for the advisee and view what
  1250. Xthe advisee's terminal is displaying.
  1251. X.PP
  1252. XThe advisee would typically type ``advise -a'' to allow advise attaches;
  1253. Xthe advisor would then type ``advise username'' which would connect the
  1254. Xadvisors terminal the the advisee's.
  1255. X.PP
  1256. XAll characters the advisor types are sent to the advisee's terminal
  1257. Xas if the advisee typed them save the meta character.
  1258. X.PP
  1259. XThe default meta character is tilde (~).  The advisor uses the meta
  1260. Xcharacter to disconnect or suspend the advise session.  The meta
  1261. Xcommands that are available to the advisor are:
  1262. X.PP
  1263. X.RS
  1264. X.TP
  1265. X~?
  1266. XMeta character help message.
  1267. X.TP
  1268. X~~
  1269. XSend the meta character to the advisee's terminal.
  1270. X.TP
  1271. X~.
  1272. XDisconnect advise session.
  1273. X.TP
  1274. X~=C
  1275. XChange the meta character to C.
  1276. X.TP
  1277. X~^Z
  1278. XSuspend this advise session.
  1279. X.RE
  1280. X.PP
  1281. XIn Advise mode the advisor uses ``~.'' to disconnect the advise session
  1282. X(Note: the advisor should use ``~~'' to send one tilde to the advisee's
  1283. Xterminal).
  1284. X.PP
  1285. XIn ``spy mode'' the advisor should use an interrupt is use to disconnect
  1286. Xthe advise session.
  1287. X.PP
  1288. X``advise -d'' can be used by the advisee to disconnect the advise
  1289. Xsession.
  1290. X.SH OPTIONS
  1291. X.TP
  1292. X-A
  1293. XAllow advise attaches to this terminal.
  1294. X.TP
  1295. X-D
  1296. XDisallow advise attaches to this terminal.
  1297. X.TP
  1298. X-M module
  1299. XName of module to place advise module under.
  1300. X.TP
  1301. X-S
  1302. XWhen attaching to another user, don't send the attach message.
  1303. X(available to the super user, only).
  1304. X.TP
  1305. X-a
  1306. XPush advise module on standard input stream and allow advise
  1307. Xattaches.
  1308. X.TP
  1309. X-d
  1310. XPush advise module on standard input stream and disallow advise
  1311. Xattaches.
  1312. X.TP
  1313. X-m char
  1314. XChange the meta character to ``char''.  The default meta character
  1315. Xis tilde (~).
  1316. X.TP
  1317. X-s
  1318. XSpy mode only (ie, input from the advisor is not passed to the
  1319. Xadvisee).
  1320. X.TP
  1321. Xdevice
  1322. XThe name of the tty device to advise.
  1323. X.TP
  1324. Xusername
  1325. XThe name of the user to advise.
  1326. X.SH AUTHOR
  1327. X.RS
  1328. X.PP
  1329. XKeith M. Gabryelski (ag@amix.commodore.com)
  1330. X.RE
  1331. END_OF_FILE
  1332.   if test 2161 -ne `wc -c <'advise.man'`; then
  1333.     echo shar: \"'advise.man'\" unpacked with wrong size!
  1334.   fi
  1335.   # end of 'advise.man'
  1336. fi
  1337. if test -f 'advisedev.c' -a "${1}" != "-c" ; then 
  1338.   echo shar: Will not clobber existing file \"'advisedev.c'\"
  1339. else
  1340.   echo shar: Extracting \"'advisedev.c'\" \(10422 characters\)
  1341.   sed "s/^X//" >'advisedev.c' <<'END_OF_FILE'
  1342. X/* Copyright (C) 1990 Keith Gabryelski (ag@amix.commodore.com)
  1343. X
  1344. XThis file is part of advise.
  1345. X
  1346. Xadvise is distributed in the hope that it will be useful,
  1347. Xbut WITHOUT ANY WARRANTY.  No author or distributor
  1348. Xaccepts responsibility to anyone for the consequences of using it
  1349. Xor for whether it serves any particular purpose or works at all,
  1350. Xunless he says so in writing.  Refer to the advise General Public
  1351. XLicense for full details.
  1352. X
  1353. XEveryone is granted permission to copy, modify and redistribute
  1354. Xadvise, but only under the conditions described in the
  1355. Xadvise General Public License.   A copy of this license is
  1356. Xsupposed to have been given to you along with advise so you
  1357. Xcan know your rights and responsibilities.  It should be in a
  1358. Xfile named COPYING.  Among other things, the copyright notice
  1359. Xand this notice must be preserved on all copies.  */
  1360. X
  1361. X/*
  1362. X** Author:    Keith Gabryelski    (ag@amix.commodore.com)
  1363. X*/
  1364. X
  1365. X#include <sys/types.h>
  1366. X#include <sys/param.h>
  1367. X#include <sys/sysmacros.h>
  1368. X#include <sys/signal.h>
  1369. X#include <sys/file.h>
  1370. X#if !defined(sun) && !defined(i386) /* AmigaUnix ? */
  1371. X#include <sys/user.h>
  1372. X#endif /* !sun && !i386 */
  1373. X#include <sys/proc.h>
  1374. X#include <sys/termios.h>
  1375. X#include <sys/ttold.h>
  1376. X#ifndef sun
  1377. X#include <sys/cmn_err.h>
  1378. X#endif /* !sun */
  1379. X#include <sys/stream.h>
  1380. X#include <sys/stropts.h>
  1381. X#include <sys/errno.h>
  1382. X#include <sys/debug.h>
  1383. X#include "advise.h"
  1384. X#ifndef sun
  1385. X#include <sys/inline.h>
  1386. X#else
  1387. X#include "advisemod.c"
  1388. X
  1389. X#ifndef L_MAXMIN
  1390. X#define L_MAXMIN 0377
  1391. X#endif /* ! L_MAXMIN */
  1392. X
  1393. X#ifndef EUNATCH
  1394. X#define EUNATCH ENOPROTOOPT
  1395. X#endif /* ! EUNATCH */
  1396. X
  1397. X#endif /* ! sun */
  1398. X
  1399. X#ifdef i386
  1400. X#include <sys/ddi.h>
  1401. X
  1402. Xint advisedevflag = 0;    /* Used by the Kernel */
  1403. X#endif /* i386 */
  1404. X
  1405. Xint adviseopen(), adviseclose(), adviserput(), advisewput();
  1406. Xvoid advisesrvioc();
  1407. X
  1408. Xstatic struct module_info adviseiinfo =
  1409. X{
  1410. X    0, "advise", 0, INFPSZ, 2048, 128,
  1411. X};
  1412. X
  1413. Xstatic struct qinit adviserinit =
  1414. X{
  1415. X    adviserput, NULL, adviseopen, adviseclose, NULL, &adviseiinfo, NULL
  1416. X};
  1417. X
  1418. Xstatic struct module_info adviseoinfo =
  1419. X{
  1420. X    42, "advise", 0, INFPSZ, 300, 200,
  1421. X};
  1422. X
  1423. Xstatic struct qinit advisewinit =
  1424. X{
  1425. X    advisewput, NULL, NULL, NULL, NULL, &adviseoinfo, NULL
  1426. X};
  1427. X
  1428. X#ifndef sun
  1429. Xextern struct advise_state advise_table;
  1430. X#else
  1431. Xstatic
  1432. X#endif /* sun */
  1433. Xstruct streamtab adviseinfo =
  1434. X{
  1435. X    &adviserinit, &advisewinit, NULL, NULL,
  1436. X};
  1437. X
  1438. Xstatic char minoralloc[((L_MAXMIN+1+7)&~7)/8];
  1439. X
  1440. X/*ARGSUSED*/
  1441. Xstatic int
  1442. Xadviseopen(q, dev, flag, sflag
  1443. X#ifndef sun
  1444. X    , credp
  1445. X#endif /* !sun */
  1446. X)
  1447. Xregister queue_t *q;
  1448. X#ifdef sun
  1449. X#define openerr(x) return OPENFAIL
  1450. X#else
  1451. X#define openerr(x) return x
  1452. Xdev_t *dev;
  1453. Xcred_t *credp;
  1454. X#endif /* sun */
  1455. X{
  1456. X    register mblk_t *bp;
  1457. X    struct advise_queue_list *ql;
  1458. X    struct advise_state  *sp;
  1459. X    int i;
  1460. X    int s;
  1461. X
  1462. X    if (sflag != CLONEOPEN)
  1463. X    openerr(EINVAL);
  1464. X
  1465. X    s=spladvise();
  1466. X    for (i=0; i < L_MAXMIN && minoralloc[i/8]&(1<<(i%8)); ++i);
  1467. X
  1468. X    if(i==L_MAXMIN) {
  1469. X    splx(s);
  1470. X    openerr(ENOMEM); /* no more resources */
  1471. X    }
  1472. X
  1473. X    minoralloc[i/8] |= 1<<(i%8);
  1474. X    i++;
  1475. X    splx(s);
  1476. X
  1477. X#ifndef sun
  1478. X    *dev = makedevice(getmajor(*dev), i);
  1479. X#endif /* sun */
  1480. X
  1481. X    if ((bp = allocb((int)sizeof(struct advise_queue_list), BPRI_MED)) == NULL)
  1482. X    {
  1483. X    openerr(ENOMEM);
  1484. X    }
  1485. X
  1486. X    bp->b_wptr += sizeof(struct advise_queue_list);
  1487. X    ql = (struct advise_queue_list *)bp->b_rptr;
  1488. X    ql->savbp = bp;
  1489. X    ql->next = NULL;
  1490. X    ql->q = q;
  1491. X    ql->minord = i;
  1492. X    ql->wdir = 0;
  1493. X    ql->state = NULL;
  1494. X
  1495. X    q->q_ptr = (caddr_t)ql;
  1496. X    WR(q)->q_ptr = (caddr_t)ql;
  1497. X
  1498. X#ifdef sun
  1499. X    return minor(i);
  1500. X#else
  1501. X    return 0;
  1502. X#endif /* sun */
  1503. X}
  1504. X
  1505. Xstatic struct advise_state *
  1506. Xvalidstate(sp)
  1507. Xstruct advise_state *sp;
  1508. X{
  1509. X    struct advise_state *llist = &advise_table;
  1510. X
  1511. X    if(sp != NULL) if (sp->q != NULL) {
  1512. X    while (llist != NULL && llist->next != sp)
  1513. X        llist = llist->next;
  1514. X
  1515. X    return(llist);
  1516. X    }
  1517. X    return(NULL);
  1518. X}
  1519. X
  1520. Xstatic
  1521. Xadviseclose(q)
  1522. Xregister queue_t *q;
  1523. X{
  1524. X    struct advise_state *llist = &advise_table;
  1525. X    struct advise_queue_list *qp = (struct advise_queue_list *)q->q_ptr;
  1526. X    struct advise_queue_list *ql, *qlp;
  1527. X    int s;
  1528. X
  1529. X    s=spladvise();
  1530. X
  1531. X    /* Remove us from the advisor's list */
  1532. X    if (llist = validstate(qp->state))
  1533. X    {
  1534. X    if(ql = llist->next->q_wlist) {
  1535. X
  1536. X    if (ql->q == q)
  1537. X      llist->next->q_wlist = ql->next;
  1538. X    else
  1539. X    {
  1540. X        while (ql->next != NULL && ql->next->q != q)
  1541. X        ql = ql->next;
  1542. X
  1543. X        if (ql->next != NULL)
  1544. X        ql->next = ql->next->next;
  1545. X    }
  1546. X    }
  1547. X
  1548. X    if(ql = llist->next->q_rlist) {
  1549. X
  1550. X    if (ql->q == q)
  1551. X        llist->next->q_rlist = ql->next;
  1552. X    else
  1553. X    {
  1554. X        while (ql->next != NULL && ql->next->q != q)
  1555. X        ql = ql->next;
  1556. X
  1557. X        if (ql->next != NULL)
  1558. X        ql->next = ql->next->next;
  1559. X    }
  1560. X    }
  1561. X    }
  1562. X
  1563. X    /* mark minor device number as free in our allocation bitmap */
  1564. X    minoralloc[(qp->minord-1)/8] &= ~(1<<((qp->minord-1)%8));
  1565. X
  1566. X    splx(s);
  1567. X
  1568. X    qp->state = NULL;
  1569. X    freeb(qp->savbp);
  1570. X
  1571. X    q->q_ptr = NULL;
  1572. X    WR(q)->q_ptr = NULL;
  1573. X}
  1574. X
  1575. Xstatic int
  1576. Xadviserput(q, bp)
  1577. Xstruct queue *q;
  1578. Xmblk_t *bp;
  1579. X{
  1580. X    putnext(q, bp);
  1581. X}
  1582. X
  1583. Xstatic int
  1584. Xadvisewput(q, mp)
  1585. Xstruct queue *q;
  1586. Xmblk_t *mp;
  1587. X{
  1588. X    struct advise_queue_list *qp = (struct advise_queue_list *)q->q_ptr;
  1589. X    struct advise_state *sp = qp->state;
  1590. X    int s;
  1591. X
  1592. X    switch (mp->b_datap->db_type)
  1593. X    {
  1594. X    case M_PROTO:
  1595. X    {
  1596. X    struct advise_message *ms = (struct advise_message *)mp->b_rptr;
  1597. X    mblk_t *mp2 = unlinkb(mp);
  1598. X
  1599. X    if (mp2)
  1600. X    {
  1601. X        s=spladvise();
  1602. X        if (validstate(sp))
  1603. X        {
  1604. X        if (ms->type == ADVISE_READDATA)
  1605. X        {
  1606. X            putnext(WR(sp->q), mp2);
  1607. X        }
  1608. X        else
  1609. X        {
  1610. X            putnext(sp->q, mp2);
  1611. X        }
  1612. X        }
  1613. X        else
  1614. X        freemsg(mp2);
  1615. X        splx(s);
  1616. X    }
  1617. X
  1618. X    freemsg(mp);
  1619. X    break;
  1620. X    }
  1621. X
  1622. X    case M_DATA:
  1623. X    /*
  1624. X    ** Write data to advisee.
  1625. X    */
  1626. X        s=spladvise();
  1627. X    if (validstate(sp))
  1628. X        putnext(qp->wdir?WR(sp->q):sp->q, mp);
  1629. X    else
  1630. X        freemsg(mp);
  1631. X    splx(s);
  1632. X    break;
  1633. X
  1634. X#ifdef M_COPYOUT
  1635. X    case M_IOCDATA:
  1636. X#endif /* M_COPYOUT */
  1637. X    case M_IOCTL:
  1638. X    advisesrvioc(q, mp);
  1639. X    break;
  1640. X
  1641. X    default:
  1642. X    freemsg(mp);
  1643. X    break;
  1644. X    }
  1645. X}
  1646. X
  1647. X
  1648. Xstatic void
  1649. Xadvisesrvioc(q, mp)
  1650. Xqueue_t *q;
  1651. Xmblk_t *mp;
  1652. X{
  1653. X    mblk_t *mp1;
  1654. X    struct iocblk *iocbp = (struct iocblk *)mp->b_rptr;
  1655. X    struct advise_queue_list *qp=(struct advise_queue_list *)q->q_ptr; 
  1656. X    int s;
  1657. X
  1658. X#ifdef M_COPYOUT
  1659. X    if (mp->b_datap->db_type == M_IOCDATA)
  1660. X    {
  1661. X    /* For copyin/copyout failures, just free message. */
  1662. X    if (((struct copyresp *)mp->b_rptr)->cp_rval)
  1663. X    {
  1664. X        freemsg(mp);
  1665. X        return;
  1666. X    }
  1667. X
  1668. X    if (!((struct copyresp *)mp->b_rptr)->cp_private)
  1669. X    {
  1670. X        mp->b_datap->db_type = M_IOCACK;
  1671. X        freemsg(unlinkb(mp));
  1672. X        iocbp->ioc_count = 0;
  1673. X        iocbp->ioc_rval = 0;
  1674. X        iocbp->ioc_error = 0;
  1675. X        putnext(RD(q), mp);
  1676. X        return;
  1677. X    }
  1678. X    }
  1679. X#endif /* M_COPYOUT */
  1680. X
  1681. X    switch (iocbp->ioc_cmd)
  1682. X    {
  1683. X    case ADVISE_SETADVISEEWR:
  1684. X    case ADVISE_SETADVISEERD:
  1685. X    {
  1686. X        register dev_t p;
  1687. X        struct advise_queue_list *qlp, **qlist;
  1688. X        struct advise_state *llist;
  1689. X
  1690. X        if (qp->state != NULL) /* already advising someone */
  1691. X        {
  1692. X        iocbp->ioc_error = EBUSY;
  1693. X        mp->b_datap->db_type = M_IOCNAK;
  1694. X        iocbp->ioc_count = 0;
  1695. X        putnext(RD(q), mp);
  1696. X        break;
  1697. X        }
  1698. X
  1699. X        if (!mp->b_cont)
  1700. X        {
  1701. X        iocbp->ioc_error = EINVAL;
  1702. X        mp->b_datap->db_type = M_IOCNAK;
  1703. X        iocbp->ioc_count = 0;
  1704. X        putnext(RD(q), mp);
  1705. X        break;
  1706. X        }
  1707. X
  1708. X        p = *(dev_t *)mp->b_cont->b_rptr;
  1709. X
  1710. X        s = spladvise();
  1711. X
  1712. X#ifdef sun
  1713. Xconsoletryagain:    /* ugly hack to allow advising of /dev/console */
  1714. X#endif /* sun */
  1715. X        llist = advise_table.next;
  1716. X
  1717. X        while (llist != NULL && llist->dev != p)
  1718. X        {
  1719. X        llist = llist->next;
  1720. X        }
  1721. X
  1722. X        if (llist == NULL)
  1723. X        {
  1724. X#ifdef sun
  1725. X        if(major(p)==0) {
  1726. X            p=makedev(1, minor(p));
  1727. X            goto consoletryagain;
  1728. X        }
  1729. X#endif /* sun */
  1730. X        splx(s);
  1731. X        iocbp->ioc_error = EUNATCH;
  1732. X        mp->b_datap->db_type = M_IOCNAK;
  1733. X        iocbp->ioc_count = 0;
  1734. X        putnext(RD(q), mp);
  1735. X        break;
  1736. X        }
  1737. X
  1738. X        if ((llist->status & ALLOW_ADVICE) == 0 && (
  1739. X#ifdef sun
  1740. X        iocbp->ioc_uid
  1741. X#else
  1742. X#ifdef i386
  1743. X        drv_priv(iocbp->ioc_cr)
  1744. X#else
  1745. X        !suser(u.u_cred)
  1746. X#endif /* i386 */
  1747. X#endif /* sun */
  1748. X        ))
  1749. X        {
  1750. X        splx(s);
  1751. X        iocbp->ioc_error = EACCES;
  1752. X        mp->b_datap->db_type = M_IOCNAK;
  1753. X        iocbp->ioc_count = 0;
  1754. X        putnext(RD(q), mp);
  1755. X        break;
  1756. X        }
  1757. X
  1758. X        /*
  1759. X        ** Add ourself to the list of advisors for this advisee.
  1760. X        */
  1761. X
  1762. X        if(iocbp->ioc_cmd==ADVISE_SETADVISEERD) qlist=&llist->q_rlist;
  1763. X        else qlist=&llist->q_wlist;
  1764. X
  1765. X        if (*qlist == NULL)
  1766. X        {
  1767. X        qlp = *qlist = qp;
  1768. X        }
  1769. X        else
  1770. X        {
  1771. X        qlp = *qlist;
  1772. X
  1773. X        while (qlp->next != NULL)
  1774. X            qlp = qlp->next;
  1775. X
  1776. X        qlp->next = qp;
  1777. X        qlp = qp;
  1778. X        }
  1779. X
  1780. X        qlp->state = llist;
  1781. X
  1782. X        if(iocbp->ioc_cmd==ADVISE_SETADVISEERD) qlp->wdir=1;
  1783. X        else qlp->wdir=0;
  1784. X
  1785. X        splx(s);
  1786. X
  1787. X        mp->b_datap->db_type = M_IOCACK;
  1788. X        mp1 = unlinkb(mp);
  1789. X        if (mp1)
  1790. X        freeb(mp1);
  1791. X        iocbp->ioc_count = 0;
  1792. X        putnext(RD(q), mp);
  1793. X        break;
  1794. X    }
  1795. X
  1796. X    default:
  1797. X    /* Unrecognized ioctl command */
  1798. X    if (canput(RD(q)->q_next))
  1799. X    {
  1800. X        mp->b_datap->db_type = M_IOCNAK;
  1801. X        putnext(RD(q), mp);
  1802. X    }
  1803. X    else
  1804. X        putbq(q, mp);
  1805. X    break;
  1806. X    }
  1807. X}
  1808. X
  1809. X#ifdef sun
  1810. X
  1811. X/* autoload support for SunOS 4.1. 
  1812. X   Derived from example in section 5.7 of Sun manual "Writing Device Drivers",
  1813. X   and code of similar purpose in a streams logging module written by
  1814. X   Matthias Urlichs <urlichs@smurf.sub.org>.
  1815. X*/
  1816. X#include <sys/conf.h>
  1817. X#include <sys/buf.h>
  1818. X#include <sundev/mbvar.h>
  1819. X#include <sun/autoconf.h>
  1820. X#include <sun/vddrv.h>
  1821. X
  1822. Xextern nodev();
  1823. X
  1824. Xstatic struct cdevsw advisecdev = {
  1825. X    nodev,          nodev,          nodev,          nodev,
  1826. X    nodev,          nodev,          nodev,          0,
  1827. X    &adviseinfo,    0
  1828. X};
  1829. X
  1830. Xstatic struct vdldrv vd = {
  1831. X    VDMAGIC_PSEUDO,
  1832. X    "advise",
  1833. X    NULL,
  1834. X#ifndef sun4c
  1835. X    NULL,NULL,0,1,
  1836. X#endif    /* sun4c */
  1837. X    NULL,&advisecdev,0,0
  1838. X};
  1839. X
  1840. Xstatic struct fmodsw *fmod_advmod=NULL;
  1841. X
  1842. Xxxxinit(fc,vdp,vdi,vds)
  1843. Xunsigned int fc;
  1844. Xstruct vddrv *vdp;
  1845. Xaddr_t vdi;
  1846. Xstruct vdstat *vds;
  1847. X{
  1848. X    switch(fc) {
  1849. X        case VDLOAD:
  1850. X            if(fmod_advmod) return(EBUSY);
  1851. X        {
  1852. X            int dev,i;
  1853. X
  1854. X            for(dev=0; dev < fmodcnt; dev++) {
  1855. X                if(fmodsw[dev].f_str == NULL)
  1856. X                    break;
  1857. X            }
  1858. X            if(dev == fmodcnt) return(ENODEV);
  1859. X
  1860. X            fmod_advmod = &fmodsw[dev];
  1861. X            for(i=0;i<=FMNAMESZ;i++)
  1862. X                fmod_advmod->f_name[i] = advmodinfo.st_rdinit->qi_minfo->mi_idname[i];
  1863. X        }
  1864. X            fmod_advmod->f_str = &advmodinfo;
  1865. X            vdp->vdd_vdtab = (struct vdlinkage *)&vd;
  1866. X            return 0;
  1867. X
  1868. X        case VDUNLOAD:
  1869. X            if(advise_table.next) return(EIO);
  1870. X            for(i=0; i<sizeof(minoralloc); i++)
  1871. X                if(minoralloc[i]) return(EIO);
  1872. X
  1873. X            if(fmod_advmod) {
  1874. X                fmod_advmod->f_name[0] = '\0';
  1875. X                fmod_advmod->f_str = NULL;
  1876. X                fmod_advmod=NULL;
  1877. X            } else return(ENODEV);
  1878. X            return 0;
  1879. X
  1880. X        case VDSTAT:
  1881. X            return 0;
  1882. X
  1883. X        default:
  1884. X            return EIO;
  1885. X    }
  1886. X}
  1887. X#endif /* sun */
  1888. END_OF_FILE
  1889.   if test 10422 -ne `wc -c <'advisedev.c'`; then
  1890.     echo shar: \"'advisedev.c'\" unpacked with wrong size!
  1891.   fi
  1892.   # end of 'advisedev.c'
  1893. fi
  1894. if test -f 'advisemod.c' -a "${1}" != "-c" ; then 
  1895.   echo shar: Will not clobber existing file \"'advisemod.c'\"
  1896. else
  1897.   echo shar: Extracting \"'advisemod.c'\" \(7510 characters\)
  1898.   sed "s/^X//" >'advisemod.c' <<'END_OF_FILE'
  1899. X/* Copyright (C) 1990 Keith Gabryelski (ag@amix.commodore.com)
  1900. X
  1901. XThis file is part of advise.
  1902. X
  1903. Xadvise is distributed in the hope that it will be useful,
  1904. Xbut WITHOUT ANY WARRANTY.  No author or distributor
  1905. Xaccepts responsibility to anyone for the consequences of using it
  1906. Xor for whether it serves any particular purpose or works at all,
  1907. Xunless he says so in writing.  Refer to the advise General Public
  1908. XLicense for full details.
  1909. X
  1910. XEveryone is granted permission to copy, modify and redistribute
  1911. Xadvise, but only under the conditions described in the
  1912. Xadvise General Public License.   A copy of this license is
  1913. Xsupposed to have been given to you along with advise so you
  1914. Xcan know your rights and responsibilities.  It should be in a
  1915. Xfile named COPYING.  Among other things, the copyright notice
  1916. Xand this notice must be preserved on all copies.  */
  1917. X
  1918. X/*
  1919. X** Author:    Keith Gabryelski    (ag@amix.commodore.com)
  1920. X*/
  1921. X
  1922. X#ifndef sun
  1923. X#include <sys/types.h>
  1924. X#include <sys/param.h>
  1925. X#include <sys/signal.h>
  1926. X#include <sys/file.h>
  1927. X#include <sys/user.h>
  1928. X#include <sys/proc.h>
  1929. X#include <sys/termios.h>
  1930. X#include <sys/ttold.h>
  1931. X#include <sys/cmn_err.h>
  1932. X#include <sys/stream.h>
  1933. X#include <sys/stropts.h>
  1934. X#include <sys/errno.h>
  1935. X#include <sys/debug.h>
  1936. X#include "advise.h"
  1937. X#include <sys/inline.h>
  1938. X#endif /* sun */
  1939. X
  1940. X#ifdef i386
  1941. X#include <sys/ddi.h>
  1942. X
  1943. Xint advmoddevflag = 0;    /* Used by the Kernel */
  1944. X#endif /* i386 */
  1945. X
  1946. Xint advisemopen(), advisemclose(), advisemput();
  1947. X
  1948. Xstatic struct module_info advisemiinfo =
  1949. X{
  1950. X    0, ADVMODNAME, 0, INFPSZ, 2048, 128,
  1951. X};
  1952. X
  1953. Xstatic struct qinit advisemrinit =
  1954. X{
  1955. X    advisemput, NULL, advisemopen, advisemclose, NULL, &advisemiinfo, NULL
  1956. X};
  1957. X
  1958. Xstatic struct module_info advisemoinfo =
  1959. X{
  1960. X    42, ADVMODNAME, 0, INFPSZ, 300, 200,
  1961. X};
  1962. X
  1963. Xstatic struct qinit advisemwinit =
  1964. X{
  1965. X    advisemput, NULL, NULL, NULL, NULL, &advisemoinfo, NULL
  1966. X};
  1967. X
  1968. X#ifdef sun
  1969. Xstatic
  1970. X#endif /* sun */
  1971. Xstruct streamtab advmodinfo =
  1972. X{
  1973. X    &advisemrinit, &advisemwinit, NULL, NULL,
  1974. X};
  1975. X
  1976. X#ifdef sun
  1977. Xstatic
  1978. X#endif /* sun */
  1979. Xstruct advise_state advise_table;
  1980. X
  1981. X
  1982. X/*ARGSUSED*/
  1983. Xstatic int
  1984. Xadvisemopen(q, dev, flag, sflag
  1985. X#ifndef sun
  1986. X    , credp
  1987. X#endif /* !sun */
  1988. X)
  1989. Xregister queue_t *q;
  1990. X#ifdef sun
  1991. X#define DEVP    dev
  1992. X#else
  1993. X#define DEVP    *dev
  1994. Xdev_t DEVP;
  1995. Xcred_t *credp;
  1996. X#endif /* !sun */
  1997. X{
  1998. X    register struct advise_state *sp;
  1999. X    register mblk_t *bp;
  2000. X    struct advise_state *llist = &advise_table;
  2001. X    int s;
  2002. X
  2003. X    if (sflag != MODOPEN)
  2004. X    return EINVAL;
  2005. X
  2006. X    if ((bp = allocb((int)sizeof(struct advise_state), BPRI_MED)) == NULL)
  2007. X    {
  2008. X    return ENOMEM;
  2009. X    }
  2010. X
  2011. X    bp->b_wptr += sizeof(struct advise_state);
  2012. X    sp = (struct advise_state *)bp->b_rptr;
  2013. X    sp->savbp = bp;
  2014. X
  2015. X    sp->dev = DEVP;
  2016. X    sp->status = 0;        /* Deny access by default */
  2017. X    sp->next = NULL;
  2018. X    sp->q_wlist = sp->q_rlist = NULL;
  2019. X    sp->q = q;
  2020. X
  2021. X    s=spladvise();
  2022. X    while (llist->next != NULL)
  2023. X    {
  2024. X    if (llist->next->dev == DEVP)
  2025. X    {
  2026. X        /*
  2027. X        ** We are already pushed on this stream.
  2028. X        */
  2029. X        freeb(bp);
  2030. X
  2031. X        sp = llist->next;
  2032. X
  2033. X        break;
  2034. X    }
  2035. X
  2036. X    llist = llist->next;
  2037. X    }
  2038. X
  2039. X    llist->next = sp;
  2040. X    splx(s);
  2041. X
  2042. X    q->q_ptr = (caddr_t)sp;
  2043. X    WR(q)->q_ptr = (caddr_t)sp;
  2044. X
  2045. X    return 0;
  2046. X}
  2047. X
  2048. Xstatic
  2049. Xadvisemclose(q)
  2050. Xregister queue_t *q;
  2051. X{
  2052. X    register struct advise_state *sp = (struct advise_state *)q->q_ptr;
  2053. X    struct advise_state *llist = &advise_table;
  2054. X    struct advise_queue_list *qp;
  2055. X    int s;
  2056. X
  2057. X    sp->status = 0;
  2058. X
  2059. X    s = spladvise();
  2060. X
  2061. X    /* unlink us from the state table */
  2062. X
  2063. X    while (llist->next != sp)
  2064. X    llist = llist->next;
  2065. X
  2066. X    llist->next = llist->next->next;
  2067. X
  2068. X    /* tell each advisor that we're shutting down */
  2069. X    for (qp = sp->q_rlist; qp != NULL; qp = qp->next)
  2070. X    {
  2071. X    flushq(qp->q, FLUSHDATA);
  2072. X    putctl(qp->q->q_next, M_HANGUP);
  2073. X    }
  2074. X    for (qp = sp->q_wlist; qp != NULL; qp = qp->next)
  2075. X    {
  2076. X    flushq(qp->q, FLUSHDATA);
  2077. X    putctl(qp->q->q_next, M_HANGUP);
  2078. X    }
  2079. X    splx(s);
  2080. X
  2081. X    freeb(sp->savbp);
  2082. X
  2083. X    q->q_ptr = NULL;
  2084. X    WR(q)->q_ptr = NULL;
  2085. X}
  2086. X
  2087. Xstatic int
  2088. Xadvisemput(q, mp)
  2089. Xregister queue_t *q;
  2090. Xregister mblk_t *mp;
  2091. X{
  2092. X    struct advise_state *sp = (struct advise_state *)q->q_ptr;
  2093. X    register struct advise_queue_list *qp;
  2094. X    int s;
  2095. X
  2096. X    if(q==sp->q) { /* called as read-side put proc */
  2097. X    if(mp->b_datap->db_type==M_DATA) {
  2098. X        /*
  2099. X        ** Write data to advisors.
  2100. X        */
  2101. X        s = spladvise();
  2102. X        for (qp = sp->q_rlist; qp != NULL; qp = qp->next) {
  2103. X        mblk_t *mp1 = copymsg(mp);
  2104. X
  2105. X        if (mp1 != NULL) putnext(qp->q, mp1);
  2106. X        }
  2107. X        splx(s);
  2108. X    }
  2109. X
  2110. X    }
  2111. X    else switch (mp->b_datap->db_type) /* called as write-side put proc */
  2112. X    {
  2113. X    case M_DATA:
  2114. X    /*
  2115. X    ** Write data to advisors.
  2116. X    */
  2117. X    s = spladvise();
  2118. X    for (qp = sp->q_wlist; qp != NULL; qp = qp->next)
  2119. X    {
  2120. X        mblk_t *mp1 = copymsg(mp);
  2121. X
  2122. X        if (mp1 != NULL)
  2123. X        putnext(qp->q, mp1);
  2124. X    }
  2125. X
  2126. X    splx(s);
  2127. X    break;
  2128. X
  2129. X#ifdef M_COPYOUT
  2130. X    case M_IOCDATA:
  2131. X#endif /* !M_COPYOUT */
  2132. X    case M_IOCTL:
  2133. X    if (advisemsrvioc(q, mp)) /* handled? */
  2134. X        return 0;
  2135. X    break;
  2136. X    }
  2137. X
  2138. X    putnext(q, mp);
  2139. X
  2140. X    return 0;
  2141. X}
  2142. X
  2143. Xstatic int
  2144. Xadvisemsrvioc(q, mp)
  2145. Xqueue_t *q;
  2146. Xmblk_t *mp;
  2147. X{
  2148. X    mblk_t *mp1;
  2149. X    struct iocblk *iocbp = (struct iocblk *)mp->b_rptr;
  2150. X    struct advise_state *sp = (struct advise_state *)q->q_ptr;
  2151. X
  2152. X#ifdef M_COPYOUT
  2153. X    if (mp->b_datap->db_type == M_IOCDATA)
  2154. X    {
  2155. X    struct copyresp *csp = (struct copyresp *)mp->b_rptr;
  2156. X
  2157. X    switch(csp->cp_cmd)
  2158. X    {
  2159. X    case ADVISE_STATUS:
  2160. X    case ADVISE_ALLOW:
  2161. X    case ADVISE_DENY:
  2162. X        /* For copyin/copyout failures, just free message. */
  2163. X
  2164. X        if (csp->cp_rval)
  2165. X        freemsg(mp);
  2166. X        else if (!csp->cp_private)
  2167. X        {
  2168. X        mp->b_datap->db_type = M_IOCACK;
  2169. X        freemsg(unlinkb(mp));
  2170. X        iocbp->ioc_count = 0;
  2171. X        iocbp->ioc_rval = 0;
  2172. X        iocbp->ioc_error = 0;
  2173. X        putnext(RD(q), mp);
  2174. X        }
  2175. X
  2176. X        return 1;
  2177. X        }
  2178. X    }
  2179. X#endif /* M_COPYOUT */
  2180. X
  2181. X    switch (iocbp->ioc_cmd)
  2182. X    {
  2183. X#if defined(M_COPYOUT) || defined(sun)
  2184. X    case ADVISE_STATUS:
  2185. X        {
  2186. X        int *status;
  2187. X#ifdef M_COPYOUT
  2188. X        caddr_t arg = *(caddr_t *)mp->b_cont->b_rptr;
  2189. X
  2190. X        freemsg(mp->b_cont);
  2191. X#endif /* M_COPYOUT */
  2192. X
  2193. X        mp->b_cont = allocb(sizeof(int), BPRI_MED);
  2194. X        if (!mp->b_cont)
  2195. X        {
  2196. X        mp->b_datap->db_type = M_IOCNAK;
  2197. X        freemsg(unlinkb(mp));
  2198. X        iocbp->ioc_count = 0;
  2199. X        iocbp->ioc_rval = 0;
  2200. X        iocbp->ioc_error = ENOMEM;
  2201. X        putnext(RD(q), mp);
  2202. X        return 1;
  2203. X        }
  2204. X
  2205. X        status = (int *)mp->b_cont->b_rptr;
  2206. X        mp->b_cont->b_wptr += sizeof(int);
  2207. X
  2208. X        *status = sp->status;
  2209. X
  2210. X#ifdef M_COPYOUT
  2211. X        if (mp->b_datap->db_type == M_IOCTL &&
  2212. X        iocbp->ioc_count == TRANSPARENT)
  2213. X        {
  2214. X        struct copyreq *creq = (struct copyreq *)mp->b_rptr;
  2215. X        mp->b_datap->db_type = M_COPYOUT;
  2216. X        creq->cq_addr = arg;
  2217. X        mp->b_wptr = mp->b_rptr + sizeof *creq;
  2218. X        mp->b_cont->b_wptr = mp->b_cont->b_rptr + sizeof(int);
  2219. X        creq->cq_size = sizeof(int);
  2220. X        creq->cq_flag = 0;
  2221. X        creq->cq_private = (mblk_t *)NULL;
  2222. X        putnext(RD(q), mp);
  2223. X        return 1;
  2224. X        }
  2225. X#else /* !M_COPYOUT */
  2226. X        mp->b_datap->db_type = M_IOCACK;
  2227. X        iocbp->ioc_count = sizeof(int);
  2228. X        putnext(RD(q), mp);
  2229. X#endif /* M_COPYOUT */
  2230. X    }
  2231. X
  2232. X    break;
  2233. X
  2234. X#else /* !M_COPYOUT && !sun */
  2235. X
  2236. X    case ADVISE_STATUS:
  2237. X    mp->b_datap->db_type = M_IOCACK;
  2238. X    mp1 = unlinkb(mp);
  2239. X    if (mp1)
  2240. X        freeb(mp1);
  2241. X    iocbp->ioc_count = 0;
  2242. X    putnext(RD(q), mp);
  2243. X    break;
  2244. X#endif /* M_COPYOUT || sun */
  2245. X
  2246. X    case ADVISE_ALLOW:
  2247. X    sp->status |= ALLOW_ADVICE;
  2248. X
  2249. X    mp->b_datap->db_type = M_IOCACK;
  2250. X    mp1 = unlinkb(mp);
  2251. X    if (mp1)
  2252. X        freeb(mp1);
  2253. X    iocbp->ioc_count = 0;
  2254. X    putnext(RD(q), mp);
  2255. X    break;
  2256. X
  2257. X    case ADVISE_DENY:
  2258. X    sp->status &= ~(ALLOW_ADVICE);
  2259. X
  2260. X    mp->b_datap->db_type = M_IOCACK;
  2261. X    mp1 = unlinkb(mp);
  2262. X    if (mp1)
  2263. X        freeb(mp1);
  2264. X    iocbp->ioc_count = 0;
  2265. X    putnext(RD(q), mp);
  2266. X    break;
  2267. X
  2268. X    default:
  2269. X    return 0;
  2270. X    }
  2271. X
  2272. X    return 1;
  2273. X}
  2274. END_OF_FILE
  2275.   if test 7510 -ne `wc -c <'advisemod.c'`; then
  2276.     echo shar: \"'advisemod.c'\" unpacked with wrong size!
  2277.   fi
  2278.   # end of 'advisemod.c'
  2279. fi
  2280. if test ! -d 'advmod.id' ; then
  2281.     echo shar: Creating directory \"'advmod.id'\"
  2282.     mkdir 'advmod.id'
  2283. fi
  2284. echo shar: End of archive 1 \(of 2\).
  2285. cp /dev/null ark1isdone
  2286. MISSING=""
  2287. for I in 1 2 ; do
  2288.     if test ! -f ark${I}isdone ; then
  2289.     MISSING="${MISSING} ${I}"
  2290.     fi
  2291. done
  2292. if test "${MISSING}" = "" ; then
  2293.     echo You have unpacked both archives.
  2294.     rm -f ark[1-9]isdone
  2295. else
  2296.     echo You still must unpack the following archives:
  2297.     echo "        " ${MISSING}
  2298. fi
  2299. exit 0
  2300. exit 0 # Just in case...
  2301.