home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume27 / screen-3.5.1 / part04 / socket.c < prev    next >
C/C++ Source or Header  |  1993-08-08  |  30KB  |  1,203 lines

  1. /* Copyright (c) 1993
  2.  *      Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de)
  3.  *      Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de)
  4.  * Copyright (c) 1987 Oliver Laumann
  5.  *
  6.  * This program is free software; you can redistribute it and/or modify
  7.  * it under the terms of the GNU General Public License as published by
  8.  * the Free Software Foundation; either version 2, or (at your option)
  9.  * any later version.
  10.  *
  11.  * This program is distributed in the hope that it will be useful,
  12.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  * GNU General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU General Public License
  17.  * along with this program (see the file COPYING); if not, write to the
  18.  * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  *
  20.  ****************************************************************
  21.  */
  22.  
  23. #include "rcs.h"
  24. RCS_ID("$Id: socket.c,v 1.11 1993/08/04 00:43:00 mlschroe Exp $ FAU")
  25.  
  26. #include "config.h"
  27. #include <sys/types.h>
  28. #include <sys/stat.h>
  29. #ifndef sgi
  30. # include <sys/file.h>
  31. #endif
  32. #ifndef NAMEDPIPE
  33. #include <sys/socket.h>
  34. #endif
  35. #include <fcntl.h>
  36. #ifndef NAMEDPIPE
  37. #include <sys/un.h>
  38. #endif
  39. #include <signal.h>
  40. #ifndef M_XENIX
  41. #include <sys/time.h>
  42. #endif /* M_XENIX */
  43. #ifdef DIRENT
  44. # include <dirent.h>
  45. #else
  46. # include <sys/dir.h>
  47. # define dirent direct
  48. #endif
  49.  
  50. #include "screen.h"
  51.  
  52. #ifdef USEVARARGS
  53. # if defined(__STDC__)
  54. #  include <stdarg.h>
  55. # else
  56. #  include <varargs.h>
  57. # endif
  58. #endif
  59.  
  60. #include "extern.h"
  61.  
  62. #if defined(_SEQUENT_) && !defined(NAMEDPIPE)
  63. # define connect sconnect    /* _SEQUENT_ has braindamaged connect */
  64. static int sconnect __P((int, struct sockaddr *, int));
  65. #endif
  66.  
  67. extern char *RcFileName, *extra_incap, *extra_outcap;
  68. extern int ServerSocket, real_uid, real_gid, eff_uid, eff_gid;
  69. extern int dflag, iflag, rflag, lsflag, quietflag, wipeflag, xflag;
  70. extern char *attach_tty, *LoginName, HostName[];
  71. extern struct display *display, *displays;
  72. extern struct win *fore, *wtab[], *console_window, *windows;
  73. extern struct NewWindow nwin_undef;
  74. #ifdef NETHACK
  75. extern nethackflag;
  76. #endif
  77. #ifdef MULTIUSER
  78. extern char *multi;
  79. #endif
  80.  
  81. #ifdef PASSWORD
  82. extern int CheckPassword;
  83. extern char Password[];
  84. #endif
  85. extern char *getenv();
  86.  
  87. char SockPath[MAXPATHLEN];
  88. char *SockNamePtr, *SockName;
  89.  
  90. #ifdef MULTIUSER
  91. # define SOCKMODE (S_IWRITE | S_IREAD | (displays ? S_IEXEC : 0) | (multi ? 1 : 0))
  92. #else
  93. # define SOCKMODE (S_IWRITE | S_IREAD | (displays ? S_IEXEC : 0))
  94. #endif
  95.  
  96. int
  97. RecoverSocket()
  98. {
  99. #ifndef NOREUID
  100.   setreuid(eff_uid, real_uid);
  101.   setregid(eff_gid, real_gid);
  102. #endif
  103.   (void) unlink(SockPath);
  104. #ifndef NOREUID
  105.   setreuid(real_uid, eff_uid);
  106.   setregid(real_gid, eff_gid);
  107. #endif
  108.   close(ServerSocket);
  109.   if ((ServerSocket = MakeServerSocket()) < 0)
  110.     return 0;
  111.   return 1;
  112. }
  113.  
  114. /*
  115.  * Socket mode 700 means we are Attached. 600 is detached.
  116.  * We return how many sockets we found. If it was exactly one, we come
  117.  * back with a SockPath set to it and open it in a fd pointed to by fdp.
  118.  * If fdp == 0 we simply produce a list if all sockets.
  119.  */
  120. /* ARGSUSED */
  121. int
  122. FindSocket(how, fdp)
  123. int how;
  124. int *fdp;
  125. {
  126.   register int s, lasts = 0, found = 0, deadcount = 0, wipecount = 0;
  127.   register int l = 0;
  128.   register DIR *dirp;
  129.   register struct dirent *dp;
  130.   register char *Name;
  131.   struct stat st;
  132.   struct foundsock
  133.     {
  134.       char *name;
  135.       int mode;
  136.     } foundsock[100];    /* 100 is hopefully enough. */
  137.   int foundsockcount = 0;
  138.  
  139.   /* User may or may not give us a (prefix) SockName. We want to search. */
  140.   debug("FindSocket:\n");
  141.   if (SockName)
  142.     {
  143.       debug1("We want to match '%s'\n", SockName);
  144.       l = strlen(SockName);
  145. #ifdef NAME_MAX
  146.       if (l > NAME_MAX)
  147.     l = NAME_MAX;
  148. #endif
  149.     }
  150.  
  151. #ifndef NOREUID
  152.   setreuid(eff_uid, real_uid);
  153.   setregid(eff_gid, real_gid);
  154. #endif
  155.   debug1("FindSock searching... '%s'\n", SockPath);
  156.   /*
  157.    * this is a hack: SockName may point to Filename(Sockpath)...
  158.    */
  159.   found = *SockNamePtr;
  160.   *SockNamePtr = '\0';
  161.   if ((dirp = opendir(SockPath)) == NULL)
  162.     {
  163.       Panic(0, "Cannot opendir %s", SockPath);
  164.       /* NOTREACHED */
  165.     }
  166.   *SockNamePtr = found;
  167.   found = 0;
  168.   while ((dp = readdir(dirp)) != NULL)
  169.     {
  170.       Name = dp->d_name;
  171.       /* 
  172.        * there may be a file ".termcap" here. 
  173.        * Ignore it just like "." and "..". 
  174.        */
  175.       debug1("- %s\n", Name);
  176.       if (Name[0] == '.')
  177.     continue;
  178.       if (SockName && l)
  179.     {
  180.       register char *n = Name;
  181.  
  182.       debug2("Attach found: '%s', needed '%s'\n", Name, SockName);
  183.       /*
  184.        * The SockNames "hf", "ttyhf", "1", "12345.tty", "12345.ttyhf.medusa"
  185.        * all match the Name "12345.ttyhf.medusa".
  186.        */
  187.  
  188.       if ((*SockName <= '0' || *SockName > '9') && (*n > '0' && *n <= '9'))
  189.         {
  190.           while (*++n)
  191.         if (*n == '.')
  192.           {
  193.             n++;
  194.             break;
  195.           }
  196.           if (strncmp("tty", SockName, 3) && !strncmp("tty", n, 3))
  197.         n += 3;
  198.         }
  199.       if (strncmp(n, SockName, l))
  200.         {
  201.           debug3("strncmp('%s', '%s', %d)\n", n, SockName, l);
  202.           continue;
  203.         }
  204.     }
  205.       /*
  206.        * ATTENTION! MakeClientSocket adds SockName to SockPath! 
  207.        * Anyway, we need it earlier.
  208.        */
  209.       strcpy(SockNamePtr, Name);
  210.       if (stat(SockPath, &st))
  211.         {
  212.           debug1("could not stat! (%d)\n", errno);
  213.       continue;
  214.         }
  215. #ifndef SOCK_NOT_IN_FS
  216. # ifdef NAMEDPIPE
  217.       if (!S_ISFIFO(st.st_mode))
  218.     {
  219.       debug1("'%s' is not a pipe, ignored\n", SockPath);
  220.       continue;
  221.     }
  222. # else /* NAMEDPIPE */
  223. #  ifdef S_ISSOCK
  224.       if (!S_ISSOCK(st.st_mode))
  225.     {
  226.       debug1("'%s' is not a socket, ignored\n", SockPath);
  227.       continue;
  228.     }
  229. #  endif
  230. # endif /* NAMEDPIPE */
  231. #endif
  232.       if (st.st_uid != real_uid)
  233.         {
  234.           debug2("uid mismatch (%d - %d) - ignored\n", st.st_uid, real_uid);
  235.       continue;
  236.         }
  237.       s = st.st_mode & 0777;
  238.       debug2("FindSocket: %s has mode %04o...\n", Name, s);
  239. #ifdef MULTIUSER
  240.       if (multi && ((s & 0677) == 0600))
  241.     continue;
  242. #endif
  243.       foundsock[foundsockcount].name = SaveStr(Name);
  244. #ifdef MULTIUSER
  245.       foundsock[foundsockcount].mode = s ^ (multi ? 1 : 0);
  246. #else
  247.       foundsock[foundsockcount].mode = s;
  248. #endif
  249.       {
  250.     /* 
  251.      * marc parses the socketname again
  252.      */
  253.     int sockmpid = 0;
  254.     char *nam = Name;
  255.  
  256.     while (*nam)
  257.       {
  258.         if (*nam > '9' || *nam < '0')
  259.           break;
  260.         sockmpid = 10 * sockmpid + *nam - '0';
  261.         nam++;
  262.       }
  263.     /*
  264.      * A socket is counted as dead, when there is no
  265.      * process belongin to it. If there is one, and the
  266.      * socket mode indicates "single user detached", then
  267.      * we should be able to connect.
  268.      * If successfull, thats o.k. Otherwise we record that mode as -1.
  269.      * MakeClientSocket() must be careful not to block forever.
  270.      */
  271.     if (((sockmpid > 2) && kill(sockmpid, 0) == -1 && errno == ESRCH) ||
  272.         (((s & 0677) == 0600) && (s = MakeClientSocket(0, Name)) == -1))
  273.       {
  274.         foundsock[foundsockcount].mode = -1;
  275.         deadcount++;
  276.       }
  277.     else
  278.       close(s);
  279.       }
  280.       if (++foundsockcount >= 100)
  281.     break;
  282.     }
  283.   closedir(dirp);
  284.  
  285.   if (wipeflag)
  286.     {
  287.       for (s = 0; s < foundsockcount; s++)
  288.     {
  289.       if (foundsock[s].mode == -1)
  290.         {
  291.               strcpy(SockNamePtr, foundsock[s].name);
  292.           debug1("wiping '%s'\n", SockPath);
  293.           if (unlink(SockPath) == 0)
  294.             {
  295.           foundsock[s].mode = -2;
  296.               wipecount++;
  297.         }
  298.         }
  299.     }
  300.     }
  301. debug3("found=%d, dflag = %d, xflag = %d\n", found, dflag, xflag);
  302.   for (s = 0; s < foundsockcount; s++)
  303.     if ((foundsock[s].mode) == (dflag ? 0700 : 0600)
  304.         || (xflag && foundsock[s].mode == 0700)) 
  305.       {
  306.     found++;
  307. debug2("mode = %d --> found = %d\n", foundsock[s].mode, found);
  308.     lasts = s;
  309.       }
  310.   if (quietflag && (lsflag || (found != 1 && rflag != 2)))
  311.     eexit(10 + found);
  312.   debug2("attach: found=%d, foundsockcount=%d\n", found, foundsockcount);
  313.   if (found == 1 && lsflag == 0)
  314.     {
  315.       if ((lasts = MakeClientSocket(0, SockName = foundsock[lasts].name)) == -1)
  316.         found = 0;
  317.     }
  318.   else if (!quietflag && foundsockcount > 0)
  319.     {
  320.       switch (found)
  321.         {
  322.         case 0:
  323.           if (lsflag)
  324.         {
  325. #ifdef NETHACK
  326.               if (nethackflag)
  327.             printf("Your inventory:\n");
  328.           else
  329. #endif
  330.           printf((foundsockcount > 1) ?
  331.                  "There are screens on:\n" : "There is a screen on:\n");
  332.         }
  333.           else
  334.         {
  335. #ifdef NETHACK
  336.               if (nethackflag)
  337.             printf("Nothing fitting exists in the game:\n");
  338.           else
  339. #endif
  340.           printf((foundsockcount > 1) ?
  341.                  "There are screens on:\n" : "There is a screen on:\n");
  342.         }
  343.           break;
  344.         case 1:
  345. #ifdef NETHACK
  346.           if (nethackflag)
  347.             printf((foundsockcount > 1) ?
  348.                    "Prove thyself worthy or perish:\n" : 
  349.                    "You see here a good looking screen:\n");
  350.           else
  351. #endif
  352.           printf((foundsockcount > 1) ? 
  353.                  "There are several screens on:\n" :
  354.                  "There is a possible screen on:\n");
  355.           break;
  356.         default:
  357. #ifdef NETHACK
  358.           if (nethackflag)
  359.             printf((foundsockcount > 1) ? 
  360.                    "You may whish for a screen, what do you want?\n" : 
  361.                    "You see here a screen:\n");
  362.           else
  363. #endif
  364.           printf((foundsockcount > 1) ?
  365.                  "There are several screens on:\n" : "There is a screen on:\n");
  366.           break;
  367.         }
  368.       for (s = 0; s < foundsockcount; s++)
  369.     {
  370.       switch (foundsock[s].mode)
  371.         {
  372.         case 0700:
  373.           printf("\t%s\t(Attached)\n", foundsock[s].name);
  374.           break;
  375.         case 0600:
  376.           printf("\t%s\t(Detached)\n", foundsock[s].name);
  377.           break;
  378. #ifdef MULTIUSER
  379.         case 0701:
  380.           printf("\t%s\t(Multi, attached)\n", foundsock[s].name);
  381.           break;
  382.         case 0601:
  383.           printf("\t%s\t(Multi, detached)\n", foundsock[s].name);
  384.           break;
  385. #endif
  386.         case -1:
  387. #if defined(__STDC__) || defined(_AIX) || defined(SVR4)
  388.           printf("\t%s\t(Dead ??\?)\n", foundsock[s].name);
  389. #else
  390.           printf("\t%s\t(Dead ???)\n", foundsock[s].name);
  391. #endif
  392.           break;
  393.         case -2:
  394.           printf("\t%s\t(Removed)\n", foundsock[s].name);
  395.           break;
  396.         default:
  397.           printf("\t%s\t(Wrong mode)\n", foundsock[s].name);
  398.           break;
  399.         }
  400.     }
  401.     }
  402.   if (deadcount && !quietflag)
  403.     {
  404.       if (wipeflag)
  405.         {
  406. #ifdef NETHACK
  407.           if (nethackflag)
  408.             printf("You hear%s distant explosion%s.\n",
  409.            (deadcount > 1) ? "" : " a", (deadcount > 1) ? "s" : "");
  410.           else
  411. #endif
  412.           printf("%d Socket%s wiped out.\n", deadcount, (deadcount > 1)?"s":"");
  413.     }
  414.       else
  415.     {
  416. #ifdef NETHACK
  417.           if (nethackflag)
  418.             printf("The dead screen%s touch%s you. Try 'screen -wipe'.\n",
  419.            (deadcount > 1) ? "s" : "", (deadcount > 1) ? "" : "es");
  420.           else
  421. #endif
  422.           printf("Remove dead Sockets with 'screen -wipe'.\n");
  423.     }
  424.     }
  425.  
  426.   for (s = 0; s < foundsockcount; s++)
  427.     Free(foundsock[s].name);
  428.   if (found == 1 && fdp)
  429.     *fdp = lasts;
  430. #ifndef NOREUID
  431.   setreuid(real_uid, eff_uid);
  432.   setregid(real_gid, eff_gid);
  433. #endif
  434.   if (fdp)
  435.     return found;
  436.   return foundsockcount - wipecount;
  437. }
  438.  
  439. #ifdef NAMEDPIPE
  440.  
  441. int
  442. MakeServerSocket()
  443. {
  444.   register int s;
  445.   struct stat st;
  446.  
  447.   strcpy(SockNamePtr, SockName);
  448. # ifdef NAME_MAX
  449.   if (strlen(SockNamePtr) > NAME_MAX)
  450.     {
  451.       debug2("MakeClientSocket: '%s' truncated to %d chars\n",
  452.          SockNamePtr, NAME_MAX);
  453.       SockNamePtr[NAME_MAX] = '\0';
  454.     }
  455. # endif /* NAME_MAX */
  456.  
  457. # ifndef NOREUID
  458.   setreuid(eff_uid, real_uid);
  459.   setregid(eff_gid, real_gid);
  460. # endif /* NOREUID */
  461.   if ((s = open(SockPath, O_WRONLY | O_NDELAY)) >= 0)
  462.     {
  463.       debug("huii, my fifo already exists??\n");
  464.       if (quietflag)
  465.     {
  466.       Kill(d_userpid, SIG_BYE);
  467.       eexit(11);
  468.     }
  469.       printf("There is already a screen running on %s.\n",
  470.          Filename(SockPath));
  471.       if (stat(SockPath, &st) == -1)
  472.     Panic(errno, "stat");
  473.       if (st.st_uid != real_uid)
  474.     Panic(0, "Unfortunatelly you are not its owner.");
  475.       if ((st.st_mode & 0700) == 0600)
  476.     Panic(0, "To resume it, use \"screen -r\"");
  477.       else
  478.     Panic(0, "It is not detached.");
  479.       /* NOTREACHED */
  480.     }
  481. # ifndef NOREUID
  482.   (void) unlink(SockPath);
  483.   if (mknod(SockPath, S_IFIFO | SOCKMODE, 0))
  484.     Panic(0, "mknod fifo %s failed", SockPath);
  485. #  ifdef BROKEN_PIPE
  486.   if ((s = open(SockPath, O_RDWR | O_NDELAY, 0)) < 0)
  487. #  else
  488.   if ((s = open(SockPath, O_RDONLY | O_NDELAY, 0)) < 0)
  489. #  endif
  490.     Panic(errno, "open fifo %s", SockPath);
  491.   setreuid(real_uid, eff_uid);
  492.   setregid(real_gid, eff_gid);
  493.   return s;
  494. # else /* NOREUID */
  495.   if (UserContext() > 0)
  496.     {
  497.       (void) unlink(SockPath);
  498.       if (mknod(SockPath, S_IFIFO | SOCKMODE, 0))
  499.     UserReturn(0);
  500.       UserReturn(1);
  501.     }
  502.   if (UserStatus() <= 0)
  503.     Panic(0, "mknod fifo %s failed", SockPath);
  504. #  ifdef BROKEN_PIPE
  505.   if ((s = secopen(SockPath, O_RDWR | O_NDELAY, 0)) < 0)
  506. #  else
  507.   if ((s = secopen(SockPath, O_RDONLY | O_NDELAY, 0)) < 0)
  508. #  endif
  509.     Panic(errno, "open fifo %s", SockPath);
  510.   return s;
  511. # endif /* NOREUID */
  512. }
  513.  
  514.  
  515. int
  516. MakeClientSocket(err, name)
  517. int err;
  518. char *name;
  519. {
  520.   register int s = 0;
  521.  
  522.   strcpy(SockNamePtr, name);
  523. # ifdef NAME_MAX
  524.   if (strlen(SockNamePtr) > NAME_MAX)
  525.     {
  526.       debug2("MakeClientSocket: '%s' truncated to %d chars\n",
  527.          SockNamePtr, NAME_MAX);
  528.       SockNamePtr[NAME_MAX] = '\0';
  529.     }
  530. # endif /* NAME_MAX */
  531.   
  532.   if ((s = secopen(SockPath, O_WRONLY | O_NDELAY, 0)) >= 0)
  533.     {
  534.       (void) fcntl(s, F_SETFL, 0);
  535.       return s;
  536.     }
  537.   if (err)
  538.     Msg(errno, "open: %s (but continuing...)", SockPath);
  539.   debug1("MakeClientSocket() open %s failed\n", SockPath);
  540.   return -1;
  541. }
  542.  
  543. #else    /* NAMEDPIPE */
  544.  
  545. int
  546. MakeServerSocket()
  547. {
  548.   register int s;
  549.   struct sockaddr_un a;
  550.   struct stat st;
  551.  
  552.   if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
  553.     Panic(errno, "socket");
  554.   a.sun_family = AF_UNIX;
  555.   strcpy(SockNamePtr, SockName);
  556. # ifdef NAME_MAX
  557.   if (strlen(SockNamePtr) > NAME_MAX)
  558.     {
  559.       debug2("MakeServerSocket: '%s' truncated to %d chars\n",
  560.          SockNamePtr, NAME_MAX);
  561.       SockNamePtr[NAME_MAX] = '\0';
  562.     }
  563. # endif /* NAME_MAX */
  564.  
  565.   strcpy(a.sun_path, SockPath);
  566. # ifndef NOREUID
  567.   setreuid(eff_uid, real_uid);
  568.   setregid(eff_gid, real_gid);
  569. # endif /* NOREUID */
  570.   if (connect(s, (struct sockaddr *) &a, strlen(SockPath) + 2) != -1)
  571.     {
  572.       debug("oooooh! socket already is alive!\n");
  573.       if (quietflag)
  574.     { 
  575.       Kill(d_userpid, SIG_BYE);
  576.       /* 
  577.        * oh, well. nobody receives that return code. papa 
  578.        * dies by signal.
  579.        */
  580.       eexit(11);
  581.     }
  582.       printf("There is already a screen running on %s.\n",
  583.          Filename(SockPath));
  584.       if (stat(SockPath, &st) == -1)
  585.     Panic(errno, "stat");
  586.       if (st.st_uid != real_uid)
  587.     Panic(0, "Unfortunatelly you are not its owner.");
  588.       if ((st.st_mode & 0700) == 0600)
  589.     Panic(0, "To resume it, use \"screen -r\"");
  590.       else
  591.     Panic(0, "It is not detached.");
  592.       /* NOTREACHED */
  593.     }
  594. #if defined(m88k) || defined(sysV68)
  595.   close(s);    /* we get bind: Invalid argument if this is not done */
  596.   if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
  597.     Panic(errno, "reopen socket");
  598. #endif
  599.   (void) unlink(SockPath);
  600.   if (bind(s, (struct sockaddr *) & a, strlen(SockPath) + 2) == -1)
  601.     Panic(errno, "bind (%s)", SockPath);
  602. #ifdef SOCK_NOT_IN_FS
  603.     {
  604.       int f;
  605.       if ((f = secopen(SockPath, O_RDWR | O_CREAT, SOCKMODE)) < 0)
  606.         Panic(errno, "shadow socket open");
  607.       close(f);
  608.     }
  609. #else
  610.   chmod(SockPath, SOCKMODE);
  611. # ifdef NOREUID
  612.   chown(SockPath, real_uid, real_gid);
  613. # endif /* NOREUID */
  614. #endif /* SOCK_NOT_IN_FS */
  615.   if (listen(s, 5) == -1)
  616.     Panic(errno, "listen");
  617. # ifdef F_SETOWN
  618.   fcntl(s, F_SETOWN, getpid());
  619.   debug1("Serversocket owned by %d\n", fcntl(s, F_GETOWN, 0));
  620. # endif /* F_SETOWN */
  621. # ifndef NOREUID
  622.   setreuid(real_uid, eff_uid);
  623.   setregid(real_gid, eff_gid);
  624. # endif /* NOREUID */
  625.   return s;
  626. }
  627.  
  628. int
  629. MakeClientSocket(err, name)
  630. int err;
  631. char *name;
  632. {
  633.   register int s;
  634.   struct sockaddr_un a;
  635.  
  636.   if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
  637.     Panic(errno, "socket");
  638.   a.sun_family = AF_UNIX;
  639.   strcpy(SockNamePtr, name);
  640. # ifdef NAME_MAX
  641.   if (strlen(SockNamePtr) > NAME_MAX)
  642.     {
  643.       debug2("MakeClientSocket: '%s' truncated to %d chars\n",
  644.          SockNamePtr, NAME_MAX);
  645.       SockNamePtr[NAME_MAX] = '\0';
  646.     }
  647. # endif /* NAME_MAX */
  648.  
  649.   strcpy(a.sun_path, SockPath);
  650. # ifndef NOREUID
  651.   setreuid(eff_uid, real_uid);
  652.   setregid(eff_gid, real_gid);
  653. # else /* NOREUID */
  654.   if (access(SockPath, W_OK))
  655.     {
  656.       if (err)
  657.     Msg(errno, "%s", SockPath);
  658.       debug2("MakeClientSocket: access(%s): %d.\n", SockPath, errno);
  659.       close(s);
  660.       return -1;
  661.     }
  662. # endif /* NOREUID */
  663.   if (connect(s, (struct sockaddr *) &a, strlen(SockPath) + 2) == -1)
  664.     {
  665.       if (err)
  666.     Msg(errno, "%s: connect", SockPath);
  667.       debug("MakeClientSocket: connect failed.\n");
  668.       close(s);
  669.       s = -1;
  670.     }
  671. # ifndef NOREUID
  672.   setreuid(real_uid, eff_uid);
  673.   setregid(real_gid, eff_gid);
  674. # endif /* NOREUID */
  675.   return s;
  676. }
  677. #endif /* NAMEDPIPE */
  678.  
  679.  
  680. void
  681. SendCreateMsg(s, nwin)
  682. int s;
  683. struct NewWindow *nwin;
  684. {
  685.   struct msg m;
  686.   register char *p;
  687.   register int len, n;
  688.   char **av = nwin->args;
  689.  
  690.   debug1("SendCreateMsg() to '%s'\n", SockPath);
  691.   bzero((char *)&m, sizeof(m));
  692.   m.type = MSG_CREATE;
  693.   strcpy(m.m_tty, attach_tty);
  694.   p = m.m.create.line;
  695.   n = 0;
  696.   if (nwin->args != nwin_undef.args)
  697.     for (av = nwin->args; *av && n < MAXARGS - 1; ++av, ++n)
  698.       {
  699.         len = strlen(*av) + 1;
  700.         if (p + len >= m.m.create.line + MAXPATHLEN - 1)
  701.       break;
  702.         strcpy(p, *av);
  703.         p += len;
  704.       }
  705.   if (nwin->aka != nwin_undef.aka && p + strlen(nwin->aka) + 1 < m.m.create.line + MAXPATHLEN)
  706.     strcpy(p, nwin->aka);
  707.   else
  708.     *p = '\0';
  709.   m.m.create.nargs = n;
  710.   m.m.create.aflag = nwin->aflag;
  711.   m.m.create.flowflag = nwin->flowflag;
  712.   m.m.create.lflag = nwin->lflag;
  713.   m.m.create.hheight = nwin->histheight;
  714. #ifdef SYSV
  715.   if (getcwd(m.m.create.dir, sizeof(m.m.create.dir)) == 0)
  716. #else
  717.   if (getwd(m.m.create.dir) == 0)
  718. #endif
  719.     {
  720.       Msg(errno, "%s", m.m.create.dir);
  721.       return;
  722.     }
  723.   if (nwin->term != nwin_undef.term)
  724.     strncpy(m.m.create.screenterm, nwin->term, 19);
  725.   m.m.create.screenterm[19] = '\0';
  726.   debug1("SendCreateMsg writing '%s'\n", m.m.create.line);
  727.   if (write(s, (char *) &m, sizeof m) != sizeof m)
  728.     Msg(errno, "write");
  729. }
  730.  
  731. void
  732. #ifdef USEVARARGS
  733. /*VARARGS1*/
  734. # if defined(__STDC__)
  735. SendErrorMsg(char *fmt, ...)
  736. # else /* __STDC__ */
  737. SendErrorMsg(fmt, va_alist)
  738. char *fmt;
  739. va_dcl
  740. # endif /* __STDC__ */
  741. { /* } */
  742.   static va_list ap;
  743. #else /* USEVARARGS */
  744. /*VARARGS1*/
  745. SendErrorMsg(fmt, p1, p2, p3, p4, p5, p6)
  746. char *fmt;
  747. unsigned long p1, p2, p3, p4, p5, p6;
  748. {
  749. #endif /* USEVARARGS */
  750.   register int s;
  751.   struct msg m;
  752.  
  753. #ifdef USEVARARGS
  754. # if defined(__STDC__)
  755.   va_start(ap, fmt);
  756. # else /* __STDC__ */
  757.   va_start(ap);
  758. # endif /* __STDC__ */
  759.   (void) vsprintf(m.m.message, fmt, ap);
  760.   va_end(ap);
  761. #else /* USEVARARGS */
  762.   sprintf(m.m.message, fmt, p1, p2, p3, p4, p5, p6);
  763. #endif /* USEVARARGS */
  764.   debug1("SendErrorMsg: '%s'\n", m.m.message);
  765.   if (display == 0)
  766.     return;
  767.   s = MakeClientSocket(1, SockName);
  768.   m.type = MSG_ERROR;
  769.   strcpy(m.m_tty, d_usertty);
  770.   debug1("SendErrorMsg(): writing to '%s'\n", SockPath);
  771.   (void) write(s, (char *) &m, sizeof m);
  772.   close(s);
  773.   sleep(2);
  774. }
  775.  
  776. #ifdef PASSWORD
  777. static int
  778. CheckPasswd(pwd, pid, utty)
  779. int pid;
  780. char *pwd, *utty;
  781. {
  782.   if (CheckPassword && 
  783.       strcmp(crypt(pwd, (strlen(Password) > 1) ? Password : "JW"),
  784.          Password))
  785.     {
  786.       if (*pwd)
  787.     {
  788. # ifdef NETHACK
  789.           if (nethackflag)
  790.         Msg(0, "'%s' tries to explode in the sky, but fails. (%s)", utty, pwd);
  791.           else
  792. # endif /* NETHACK */
  793.       Msg(0, "Illegal reattach attempt from terminal %s, \"%s\"", utty, pwd);
  794.     }
  795.       debug1("CheckPass() wrong password kill(%d, SIG_PW_FAIL)\n", pid);
  796.       Kill(pid, SIG_PW_FAIL);
  797.       return 0;
  798.     }
  799.   debug1("CheckPass() from %d happy\n", pid);
  800.   Kill(pid, SIG_PW_OK);
  801.   return 1;
  802. }
  803. #endif    /* PASSWORD */
  804.  
  805. static void
  806. ExecCreate(mp)
  807. struct msg *mp;
  808. {
  809.   struct NewWindow nwin;
  810.   char *args[MAXARGS];
  811.   register int n;
  812.   register char **pp = args, *p = mp->m.create.line;
  813.  
  814.   nwin = nwin_undef;
  815.   for (n = mp->m.create.nargs; n > 0; --n)
  816.     {
  817.       *pp++ = p;
  818.       p += strlen(p) + 1;
  819.     }
  820.   *pp = 0;
  821.   if (*p)
  822.     nwin.aka = p;
  823.   if (*args)
  824.     nwin.args = args;
  825.   nwin.aflag = mp->m.create.aflag;
  826.   nwin.flowflag = mp->m.create.flowflag;
  827.   if (*mp->m.create.dir)
  828.     nwin.dir = mp->m.create.dir;
  829.   nwin.lflag = mp->m.create.lflag;
  830.   nwin.histheight = mp->m.create.hheight;
  831.   if (*mp->m.create.screenterm)
  832.     nwin.term =  mp->m.create.screenterm;
  833.   MakeWindow(&nwin);
  834. }
  835.  
  836. static int
  837. CheckPid(pid)
  838. int pid;
  839. {
  840.   debug1("Checking pid %d\n", pid);
  841.   if (pid < 2)
  842.     return(-1);
  843.   if (eff_uid == real_uid)
  844.     return kill(pid, 0);
  845.   if (UserContext() == 1)
  846.     {
  847.       UserReturn(kill(pid, 0));
  848.     }
  849.   return UserStatus();
  850. }
  851.  
  852. void
  853. ReceiveMsg()
  854. {
  855.   int left, len, i;
  856.   static struct msg m;
  857.   char *p;
  858.   int ns = ServerSocket;
  859.   struct mode Mode;
  860. #ifdef UTMPOK
  861.   struct win *wi;
  862. #endif
  863. #ifdef REMOTE_DETACH
  864.   struct display *next;
  865. #endif
  866.  
  867. #ifdef NAMEDPIPE
  868.   debug("Ha, there was someone knocking on my fifo??\n");
  869.   if (fcntl(ServerSocket, F_SETFL, 0) == -1)
  870.     Panic(errno, "DELAY fcntl");
  871. #else
  872.   struct sockaddr_un a;
  873.  
  874.   len = sizeof(a);
  875.   debug("Ha, there was someone knocking on my socket??\n");
  876.   if ((ns = accept(ns, (struct sockaddr *) &a, &len)) < 0)
  877.     {
  878.       Msg(errno, "accept");
  879.       return;
  880.     }
  881. #endif                /* NAMEDPIPE */
  882.  
  883.   p = (char *) &m;
  884.   left = sizeof(m);
  885.   while (left > 0)
  886.     {
  887.       len = read(ns, p, left);
  888.       if (len < 0 && errno == EINTR)
  889.     continue;
  890.       if (len <= 0)
  891.     break;
  892.       p += len;
  893.       left -= len;
  894.     }
  895.  
  896. #ifdef NAMEDPIPE
  897. # ifndef BROKEN_PIPE
  898.   /* Reopen pipe to prevent EOFs at the select() call */
  899.   close(ServerSocket);
  900.   if ((ServerSocket = secopen(SockPath, O_RDONLY | O_NDELAY, 0)) < 0)
  901.     Panic(errno, "reopen fifo %s", SockPath);
  902. # endif
  903. #else
  904.   close(ns);
  905. #endif
  906.  
  907.   if (len < 0)
  908.     {
  909.       Msg(errno, "read");
  910.       return;
  911.     }
  912.   if (left > 0)
  913.     {
  914.       if (left != sizeof(m))
  915.         Msg(0, "Message %d of %d bytes too small", left, sizeof(m));
  916.       else
  917.     debug("No data on socket.\n");
  918.       return;
  919.     }
  920.   debug2("*** RecMsg: type %d tty %s\n", m.type, m.m_tty);
  921.   for (display = displays; display; display = display->_d_next)
  922.     if (strcmp(d_usertty, m.m_tty) == 0)
  923.       break;
  924.   debug2("display: %s display %sfound\n", m.m_tty, display ? "" : "not ");
  925.   if (!display)
  926.     {
  927.       struct win *w;
  928.  
  929.       for (w = windows; w; w = w->w_next)
  930.         if (!strcmp(m.m_tty, w->w_tty))
  931.       {
  932.             display = w->w_display;
  933.         debug2("but window %s %sfound.\n", m.m_tty, display ? "" : "deatached (ignoring) ");
  934.         break;
  935.           }
  936.     }
  937.  
  938.   /* Remove the status to prevent garbage on the screen */
  939.   if (display && d_status)
  940.     RemoveStatus();
  941.  
  942.   switch (m.type)
  943.     {
  944.     case MSG_WINCH:
  945.       if (display)
  946.         CheckScreenSize(1); /* Change fore */
  947.       break;
  948.     case MSG_CREATE:
  949.       if (display)
  950.     ExecCreate(&m);
  951.       break;
  952.     case MSG_CONT:
  953.     if (display && d_userpid != 0 && kill(d_userpid, 0) == 0)
  954.       break;        /* Intruder Alert */
  955.       debug2("RecMsg: apid=%d,was %d\n", m.m.attach.apid, display ? d_userpid : 0);
  956.       /* FALLTHROUGH */
  957.     case MSG_ATTACH:
  958.       if (CheckPid(m.m.attach.apid))
  959.     {
  960.       debug1("Attach attempt with bad pid(%d)\n", m.m.attach.apid);
  961.       Msg(0, "Attach attempt with bad pid(%d) !", m.m.attach.apid);
  962.           break;
  963.     }
  964.       if ((i = secopen(m.m_tty, O_RDWR | O_NDELAY, 0)) < 0)
  965.     {
  966.       debug1("ALERT: Cannot open %s!\n", m.m_tty);
  967. #ifdef NETHACK
  968.           if (nethackflag)
  969.         Msg(errno, 
  970.             "You can't open (%s). Perhaps there's a Monster behind it",
  971.             m.m_tty);
  972.           else
  973. #endif
  974.       Msg(errno, "Attach: Could not open %s", m.m_tty);
  975.       Kill(m.m.attach.apid, SIG_BYE);
  976.       break;
  977.     }
  978. #ifdef PASSWORD
  979.       if (!CheckPasswd(m.m.attach.password, m.m.attach.apid, m.m_tty))
  980.     {
  981.       debug3("RcvMsg:Checkpass(%s,%d,%s) failed\n",
  982.          m.m.attach.password, m.m.attach.apid, m.m_tty);
  983.       close(i);
  984.       break;
  985.     }
  986. #else
  987. # ifdef MULTIUSER
  988.       Kill(m.m.attach.apid, SIGCONT);
  989. # endif
  990. #endif                /* PASSWORD */
  991.       if (display)
  992.     {
  993.       debug("RecMsg: hey, why you disturb, we are not detached. hangup!\n");
  994.       close(i);
  995.       Kill(m.m.attach.apid, SIG_BYE);
  996.       Msg(0, "Attach msg ignored: We are not detached.");
  997.       break;
  998.     }
  999.  
  1000. #ifdef MULTIUSER
  1001.       if (strcmp(m.m.attach.auser, LoginName))
  1002.         if (*FindUserPtr(m.m.attach.auser) == 0)
  1003.       {
  1004.               write(i, "Access to session denied.\n", 26);
  1005.           close(i);
  1006.           Kill(m.m.attach.apid, SIG_BYE);
  1007.           Msg(0, "Attach: access denied for user %s", m.m.attach.auser);
  1008.           break;
  1009.       }
  1010. #endif
  1011.  
  1012.       errno = 0;
  1013.       debug2("RecMsg: apid %d is o.k. and we just opened '%s'\n", m.m.attach.apid, m.m_tty);
  1014.       /* turn off iflag on a multi-attach... */
  1015.       if (iflag && displays)
  1016.     {
  1017.       iflag = 0;
  1018.       display = displays;
  1019. #if defined(TERMIO) || defined(POSIX)
  1020.       d_NewMode.tio.c_cc[VINTR] = VDISABLE;
  1021.       d_NewMode.tio.c_lflag &= ~ISIG;
  1022. #else /* TERMIO || POSIX */
  1023.       d_NewMode.m_tchars.t_intrc = -1;
  1024. #endif /* TERMIO || POSIX */
  1025.       SetTTY(d_userfd, &d_NewMode);
  1026.     }
  1027.  
  1028.       /* create new display */
  1029.       GetTTY(i, &Mode);
  1030.       if (MakeDisplay(m.m.attach.auser, m.m_tty, m.m.attach.envterm, i, m.m.attach.apid, &Mode) == 0)
  1031.         {
  1032.       write(i, "Could not make display.\n", 24);
  1033.       close(i);
  1034.       Msg(errno, "Attach: could not make display for user %s", m.m.attach.auser);
  1035.       Kill(m.m.attach.apid, SIG_BYE);
  1036.       break;
  1037.         }
  1038. #ifdef ultrix
  1039.       brktty(d_userfd);    /* for some strange reason this must be done */
  1040. #endif
  1041. #if defined(pyr) || defined(xelos) || defined(sequent)
  1042.       /*
  1043.        * Kludge for systems with braindamaged termcap routines,
  1044.        * which evaluate $TERMCAP, regardless weather it describes
  1045.        * the correct terminal type or not.
  1046.        */
  1047.       debug("unsetenv(TERMCAP) in case of a different terminal");
  1048.       unsetenv("TERMCAP");
  1049. #endif
  1050.     
  1051.       /*
  1052.        * We reboot our Terminal Emulator. Forget all we knew about
  1053.        * the old terminal, reread the termcap entries in .screenrc
  1054.        * (and nothing more from .screenrc is read. Mainly because
  1055.        * I did not check, weather a full reinit is save. jw) 
  1056.        * and /etc/screenrc, and initialise anew.
  1057.        */
  1058.       if (extra_outcap)
  1059.     free(extra_outcap);
  1060.       if (extra_incap)
  1061.     free(extra_incap);
  1062.       extra_incap = extra_outcap = 0;
  1063.       debug2("Message says size (%dx%d)\n", m.m.attach.columns, m.m.attach.lines);
  1064. #ifdef ETCSCREENRC
  1065. # ifdef ALLOW_SYSSCREENRC
  1066.       if ((p = getenv("SYSSCREENRC")))
  1067.     StartRc(p);
  1068.       else
  1069. # endif
  1070.     StartRc(ETCSCREENRC);
  1071. #endif
  1072.       StartRc(RcFileName);
  1073.       if (InitTermcap(m.m.attach.columns, m.m.attach.lines))
  1074.     {
  1075.       FreeDisplay();
  1076.       Kill(m.m.attach.apid, SIG_BYE);
  1077.       break;
  1078.     }
  1079.       InitTerm(m.m.attach.adaptflag);
  1080.       if (displays->_d_next == 0)
  1081.         (void) chsock();
  1082.       signal(SIGHUP, SigHup);
  1083. #ifdef UTMPOK
  1084.       /*
  1085.        * we set the Utmp slots again, if we were detached normally
  1086.        * and if we were detached by ^Z.
  1087.        */
  1088.       RemoveLoginSlot();
  1089.       if (displays->_d_next == 0)
  1090.         for (wi = windows; wi; wi = wi->w_next)
  1091.       if (wi->w_slot != (slot_t) -1)
  1092.         SetUtmp(wi);
  1093. #endif
  1094.       SetMode(&d_OldMode, &d_NewMode);
  1095.       SetTTY(d_userfd, &d_NewMode);
  1096.  
  1097.       d_fore = NULL;
  1098.       if (d_user->u_detachwin >= 0) 
  1099.         fore = wtab[d_user->u_detachwin];
  1100.       if (!fore || fore->w_display
  1101. #ifdef MULTIUSER
  1102.                    || AclCheckPermWin(d_user, ACL_WRITE, fore)
  1103. #endif
  1104.                                              )
  1105.         {
  1106.       /* try to get another window */
  1107. #ifdef MULTIUSER
  1108.       for (wi = windows; wi; wi = wi->w_next)
  1109.         if (!wi->w_display && !AclCheckPermWin(d_user, ACL_WRITE, fore))
  1110.           break;
  1111.       if (!wi)
  1112.         for (wi = windows; wi; wi = wi->w_next)
  1113.           if (!wi->w_display && !AclCheckPermWin(d_user, ACL_READ, fore))
  1114.             break;
  1115.       if (!wi)
  1116. #endif
  1117.         for (wi = windows; wi; wi = wi->w_next)
  1118.           if (!wi->w_display)
  1119.             break;
  1120.       fore = wi;
  1121.     }
  1122.       if (fore)
  1123.         SetForeWindow(fore);
  1124.       Activate(0);
  1125.       if (!d_fore)
  1126.     ShowWindows();
  1127.       if (displays->_d_next == 0 && console_window)
  1128.     {
  1129.       if (TtyGrabConsole(console_window->w_ptyfd, 1, "reattach") == 0)
  1130.         Msg(0, "console %s is on window %d", HostName, console_window->w_number);
  1131.     }
  1132.       debug("activated...\n");
  1133.       break;
  1134.     case MSG_ERROR:
  1135.       Msg(0, "%s", m.m.message);
  1136.       break;
  1137.     case MSG_HANGUP:
  1138.       SigHup(SIGARG);
  1139.       break;
  1140. #ifdef REMOTE_DETACH
  1141.     case MSG_DETACH:
  1142. # ifdef POW_DETACH
  1143.     case MSG_POW_DETACH:
  1144. # endif                /* POW_DETACH */
  1145.       for (display = displays; display; display = next)
  1146.     {
  1147.       next = display->_d_next;
  1148. # ifdef POW_DETACH
  1149.       if (m.type == MSG_POW_DETACH)
  1150.         Detach(D_REMOTE_POWER);
  1151.       else
  1152. # endif                /* POW_DETACH */
  1153.       if (m.type == MSG_DETACH)
  1154.         Detach(D_REMOTE);
  1155.     }
  1156.       break;
  1157. #endif
  1158.     default:
  1159.       Msg(0, "Invalid message (type %d).", m.type);
  1160.     }
  1161. }
  1162.  
  1163. #if defined(_SEQUENT_) && !defined(NAMEDPIPE)
  1164. #undef connect
  1165.  
  1166. /*
  1167.  *  sequent_ptx socket emulation must have mode 000 on the socket!
  1168.  */
  1169. static int
  1170. sconnect(s, sapp, len)
  1171. int s, len;
  1172. struct sockaddr *sapp;
  1173. {
  1174.   register struct sockaddr_un *sap;
  1175.   struct stat st;
  1176.   int x;
  1177.  
  1178.   sap = (struct sockaddr_un *)sapp;
  1179.   if (stat(sap->sun_path, &st))
  1180.     return -1;
  1181.   chmod(sap->sun_path, 0);
  1182.   x = connect(s, (struct sockaddr *) sap, len);
  1183.   chmod(sap->sun_path, st.st_mode);
  1184.   return x;
  1185. }
  1186. #endif
  1187.  
  1188. int
  1189. chsock()
  1190. {
  1191.   int r, euid = geteuid();
  1192.   if (euid != real_uid)
  1193.     {
  1194.       if (UserContext() <= 0)
  1195.         return UserStatus();
  1196.     }
  1197.   r = chmod(SockPath, SOCKMODE);
  1198.   if (euid != real_uid)
  1199.     UserReturn(r);
  1200.   return r;
  1201. }
  1202.  
  1203.