home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / info-service / gopher / Unix / xgopher.1.3 / sc_sound.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-05-25  |  5.3 KB  |  224 lines

  1. /* sc_sound.c
  2.    gopher item subclass procedures for sound */
  3.  
  4.      /*---------------------------------------------------------------*/
  5.      /* Xgopher        version 1.3     08 April 1993                  */
  6.      /*                version 1.2     20 November 1992               */
  7.      /*                version 1.1     20 April 1992                  */
  8.      /*                version 1.0     04 March 1992                  */
  9.      /* X window system client for the University of Minnesota        */
  10.      /*                                Internet Gopher System.        */
  11.      /* Allan Tuchman, University of Illinois at Urbana-Champaign     */
  12.      /*                Computing and Communications Services Office   */
  13.      /* Copyright 1992, 1993 by                                       */
  14.      /*           the Board of Trustees of the University of Illinois */
  15.      /* Permission is granted to freely copy and redistribute this    */
  16.      /* software with the copyright notice intact.                    */
  17.      /*---------------------------------------------------------------*/
  18.  
  19. #include "conf.h"
  20. #include "globals.h"
  21. #include "gopher.h"
  22. #include "appres.h"
  23. #include "util.h"
  24. #include "status.h"
  25. #include "jobs.h"
  26. #include "misc.h"
  27. #include "subst.h"
  28. #include "sc_sound.h"
  29. #include "sc_soundP.h"
  30.  
  31. #include "osdep.h"
  32.  
  33. extern     errno;
  34.  
  35.  
  36.  
  37. /* getSound
  38.    get a sound file and play it.  Since sound will not conflict with
  39.    visuals, this can be done asynchronously as a new process.
  40.  
  41.    X is run in a distributed environment.  As such, we take some pains
  42.    to ensure that the requestor of the sound is the one who will actually
  43.    hear the sound.  To wit, we strive to determine that the Xgopher
  44.    client host and X display host are one and the same.  
  45.  
  46.    Note that this does not eliminate mischief, as the sound command
  47.    specified in the resources can still be an "rsh" type of command. */
  48.  
  49. static BOOLEAN
  50. getSound(gi)
  51. gopherItemP    gi;
  52. {
  53.     static BOOLEAN    firstTime = TRUE;
  54.     static BOOLEAN    soundCommandOK = TRUE;
  55.     static char    *soundCmd;
  56.     char        message[MESSAGE_STRING_LEN];
  57.     FILE        *soundCmdFile;
  58.     PID_TYPE    soundPID = (PID_TYPE) 0;
  59.     int        s;
  60.  
  61.  
  62.     /* see if sound command is an executable file */
  63.  
  64.     if (firstTime) {
  65.         firstTime = FALSE;
  66.         soundCmd = editCommand(gi, cmdPath(appResources->soundCommand),
  67.                 (char *) NULL, (char *) NULL);
  68.         if (soundCmd == NULL) {
  69.             soundCommandOK = FALSE;
  70.         }
  71.  
  72.         /* check here for X display (later) */
  73.     }
  74.  
  75.     if (! soundCommandOK) {
  76.         sprintf (message,
  77.             "Unable to execute the sound play command: \'%s\'\n",
  78.             soundCmd);
  79.         showError(message);
  80.         return FALSE;
  81.                 
  82.     }
  83.  
  84.     if (findJobType(gi->type) != NO_JOB) {
  85.         /* sound may still be active */
  86.         PID_TYPE    pid;
  87.  
  88.         waitOnChildren();
  89.         pid = findJobType(gi->type);
  90.         if (pid != NO_JOB) {
  91.             showError(
  92.             "Another sound file is still executing.  Try again later."
  93.                 );
  94.             return FALSE;
  95.         } 
  96.     }
  97.  
  98.  
  99.     if ((soundPID = fork()) < 0) {
  100.         soundCommandOK = FALSE;
  101.         sprintf(message,
  102.             "Unable to start playing the sound (error %d)\n",
  103.             errno);
  104.         showError(message);
  105.         return FALSE;
  106.  
  107.     } else if (soundPID == 0) {
  108.  
  109.         /* we should immediately do a 
  110.               close (ConnectionNumber(XtDisplay(widget)));
  111.            here.  */
  112.  
  113.         /* DO NOT use status panel or any X requests including error
  114.            popups in this block.  This is the CHILD process and has
  115.            no business using the parent's X connection. */
  116.  
  117.         s = connectToSocket(gi->host, gi->port);
  118.         if (s < 0) {
  119.             /* networkError(s, gi->host, gi->port); */
  120.             fprintf (stderr, "Cannot connect to %s at port %d\n",
  121.                     gi->host, gi->port);
  122.             return FALSE;
  123.         }
  124.  
  125.         writeString(s, vStringValue(&(gi->selector)));
  126.         writeString(s, EOL_STRING);
  127.  
  128.         soundCmdFile = popen(soundCmd, "w");
  129.  
  130.         if (soundCmdFile == NULL) {
  131.             close (s);
  132.             sprintf(message,
  133.                 "Unable to start the sound command (\'%s\')",
  134.                 soundCmd);
  135.             /* showError(message); */
  136.             fprintf(stderr, "%s\n", message);
  137.             exit(-1);
  138.         }
  139.  
  140.         GI_copyNetUntilEOF(s, soundCmdFile);
  141.  
  142.         close(s);
  143.         pclose(soundCmdFile);
  144.         exit(0);
  145.     }
  146.  
  147.     /* parent */
  148.  
  149.     showStatus("trying to start playing a sound file from",
  150.                     STAT_TEMP_MESSAGE,
  151.                     gi->host, gi->port);
  152.     addJob(gi->type, soundPID);
  153.     return TRUE;
  154. }
  155.  
  156.  
  157. /* GISound_restart
  158.    kill a sound command process if possible. */
  159.  
  160. void
  161. GISound_restart()
  162. {
  163.     killAllItemType(A_SOUND);
  164. }
  165.  
  166.  
  167. /* GISound_init
  168.    initialize sound class - host access list and prefix. */
  169.  
  170. void
  171. GISound_init()
  172. {
  173.     GU_makePrefix(prefixSound,  appResources->prefixSound);
  174.     soundHostList = GU_createAccessList(appResources->soundServers);
  175.     GU_registerNewType(A_SOUND, &soundSubclass);
  176.  
  177.     /* as a mater of security, in public mode, if there are no
  178.        restrictions, sounds should be banned.  It is easy to
  179.        overcome these restrictions by creating a list such as
  180.        ".edu .com .mil .gov .net" etc.  */
  181.  
  182.     if (appResources->publicMode  &&  soundHostList == NULL) {
  183.         appResources->hasSound    = False;
  184.     }
  185.  
  186.     return;
  187. }
  188.  
  189.  
  190. /* GISound_access
  191.    check the accessability of a sound file selection */
  192.  
  193. BOOLEAN
  194. GISound_access(gi)
  195. gopherItemP    gi;
  196. {
  197.     BOOLEAN    result;
  198.  
  199.     if (appResources->hasSound  &&
  200.         (soundHostList == NULL  ||
  201.                 GU_checkAccess(gi->host, soundHostList))) {
  202.         result = TRUE;
  203.     }else {
  204.         result = FALSE;
  205.     }
  206.  
  207.     return result;
  208. }
  209.  
  210.  
  211. /* GISound_process
  212.    process a sound file selection */
  213.  
  214. BOOLEAN
  215. GISound_process(gi)
  216. gopherItemP    gi;
  217. {
  218.     BOOLEAN    result;
  219.  
  220.     result = getSound(gi);
  221.  
  222.     return result;
  223. }
  224.