Ejemplo n.º 1
0
/*-------------------------------------------------------------------*/
int http_command(int argc, char *argv[])
{
    int rc = 0;

    if ( !http_struct_init )
    {
        memset(&http_serv,0,sizeof(HTTP_SERV));
        initialize_condition( &http_serv.http_wait_shutdown );
        initialize_lock( &http_serv.http_lock_shutdown );
        initialize_lock( &http_lock_root );
        http_struct_init = TRUE;
    }

    http_serv.httpstmtold = FALSE;

    if ( argc == 2 && CMD(argv[0],rootx,4) &&
         ( ( strlen(argv[0]) == 5 && argv[2] != NULL && strcmp(argv[2],"httproot") == 0 ) ||
           ( strlen(argv[0]) == 4 ) ) )
    {
        if ( strlen(argv[0]) == 5 )
        {
            http_serv.httpstmtold = TRUE;
        }

        obtain_lock( &http_lock_root );
        if (http_serv.httproot)
        {
            free(http_serv.httproot);
            http_serv.httproot = NULL;
        }

        if ( strlen(argv[1]) > 0 )
        {
            char    pathname[MAX_PATH];

            hostpath(pathname, argv[1], sizeof(pathname));

            if ( pathname[strlen(pathname)-1] != PATHSEPC )
                strlcat( pathname, PATHSEPS, sizeof(pathname) );

            http_serv.httproot = strdup(pathname);
        }
        release_lock( &http_lock_root );

        http_root();

        if ( MLVL(VERBOSE) )
            WRMSG(HHC02204, "I", http_serv.httpstmtold ? "httproot": "root",
                        http_serv.httproot ? http_serv.httproot : "<not specified>");

        if ( http_serv.httpstmtold )
            http_startup(TRUE);

        rc = 0;
    }
    else if ( (argc == 2 || argc == 3 || argc == 5) && CMD(argv[0],portx,4) &&
              ( ( strlen(argv[0]) == 5 && argv[5] != NULL && strcmp(argv[5],"httpport") == 0 ) ||
                ( strlen(argv[0]) == 4 ) ) )
    {
        if ( strlen(argv[0]) == 5 )
        {
            http_serv.httpstmtold = TRUE;
        }

        if ( sysblk.httptid != 0 )
        {
            WRMSG( HHC01812, "E" );
            rc = -1;
        }
        else
        {
            char c;

            if (sscanf(argv[1], "%hu%c", &http_serv.httpport, &c) != 1
                    || http_serv.httpport == 0
                    || (http_serv.httpport < 1024 && http_serv.httpport != 80) )
            {
                rc = -1;
            }
            if ( rc >= 0 && argc == 3 && CMD(argv[2],noauth,6) )
            {
                http_serv.httpauth = 0;
            }
            else if ( rc >=0 && argc == 5 && CMD(argv[2],auth,4) )
            {
                if ( strlen( argv[3] ) < 1 || strlen( argv[4] ) < 1 )
                {
                    WRMSG( HHC01814, "E" );
                    rc = -1;
                }
                else
                {
                    if (http_serv.httpuser)
                        free(http_serv.httpuser);
                    http_serv.httpuser = strdup(argv[3]);

                    if (http_serv.httppass)
                        free(http_serv.httppass);
                    http_serv.httppass = strdup(argv[4]);

                    http_serv.httpauth = 1;
                }
            }
            else if ( argc != 2 || rc < 0 )
            {
                WRMSG( HHC02299, "E", "http" );
                rc = -1;
            }

            if ( rc >= 0 && MLVL(VERBOSE) )
            {
                char msgbuf[128];
                if ( http_serv.httpauth == 1 )
                {
                    MSGBUF( msgbuf, "port=%hu auth userid<%s> password<%s>",
                            http_serv.httpport,
                          ( http_serv.httpuser == NULL || strlen(http_serv.httpuser) == 0 ) ?
                                "" : http_serv.httpuser,
                          ( http_serv.httppass == NULL || strlen(http_serv.httppass) == 0 ) ?
                                "" : http_serv.httppass );
                }
                else
                    MSGBUF( msgbuf, "port=%hu noauth", http_serv.httpport );

                WRMSG( HHC02204, "I", http_serv.httpstmtold ? "httpport":"port", msgbuf );

                if ( http_serv.httpstmtold )
                    http_startup(TRUE);

            }   /* VERBOSE */
        }
    }
    else if ( argc == 1 && CMD(argv[0],start,3) )
    {
        if ( http_serv.httpport == 0 )
        {
            WRMSG( HHC01815, "E", "not valid");
            rc = -1;
        }
        else
            rc = http_startup(FALSE);
    }
    else if (argc == 1 && CMD(argv[0],stop,4))
    {
        if ( sysblk.httptid != 0 )
        {
            http_shutdown(NULL);
            WRMSG( HHC01805, "I" );
            rc = 1;
        }
        else
        {
            http_serv.httpshutdown = TRUE;
            WRMSG( HHC01806, "W", "already stopped" );
            rc = 1;
        }
    }
    else if ( argc == 0 )
    {
        if ( sysblk.httptid != 0 )
        {
            if ( http_serv.httpbinddone )
            {
                WRMSG( HHC01809, "I" );
                rc = 0;
            }
            else
            {
                WRMSG( HHC01813, "I" );
                rc = 1;
            }
        }
        else
        {
            WRMSG( HHC01810, "I" );
            rc = 1;
        }

        WRMSG(HHC01811, "I", http_get_root());

        WRMSG(HHC01808, "I", http_get_port(), http_get_portauth());
    }
    else
    {
        WRMSG( HHC02299, "E", "http" );
        rc = -1;
    }
    return rc;
}
Ejemplo n.º 2
0
// --------------------------------------------------------------------
// CTCI_EnqueueIPFrame
// --------------------------------------------------------------------
//
// Places the provided IP frame in the next available frame slot in
// the adapter buffer. For details regarding the actual buffer layout
// please refer to the comments preceding the CTCI_ReadThread function.
//
// Returns:
//
//  0 == Success
// -1 == Failure; errno = ENOBUFS:  No buffer space available
//                        EMSGSIZE: Message too long
//
static int  CTCI_EnqueueIPFrame( DEVBLK* pDEVBLK,
                                 BYTE*   pData, size_t iSize )
{
    PCTCIHDR pFrame;
    PCTCISEG pSegment;
    PCTCBLK  pCTCBLK = (PCTCBLK)pDEVBLK->dev_data;

    // Will frame NEVER fit into buffer??
    if( iSize > MAX_CTCI_FRAME_SIZE( pCTCBLK ) )
    {
        errno = EMSGSIZE;   // Message too long
        return -1;          // (-1==failure)
    }

    obtain_lock( &pCTCBLK->Lock );

    // Ensure we dont overflow the buffer
    if( ( pCTCBLK->iFrameOffset +         // Current buffer Offset
          sizeof( CTCIHDR ) +             // Size of Block Header
          sizeof( CTCISEG ) +             // Size of Segment Header
          iSize +                         // Size of Ethernet packet
          sizeof(pFrame->hwOffset) )      // Size of Block terminator
        > pCTCBLK->iMaxFrameBufferSize )  // Size of Frame buffer
    {
        release_lock( &pCTCBLK->Lock );
        errno = ENOBUFS;    // No buffer space available
        return -1;          // (-1==failure)
    }

    // Fix-up Frame pointer
    pFrame = (PCTCIHDR)pCTCBLK->bFrameBuffer;

    // Fix-up Segment pointer
    pSegment = (PCTCISEG)( pCTCBLK->bFrameBuffer +
                           sizeof( CTCIHDR ) +
                           pCTCBLK->iFrameOffset );

    // Initialize segment
    memset( pSegment, 0, iSize + sizeof( CTCISEG ) );

    // Increment offset
    pCTCBLK->iFrameOffset += sizeof( CTCISEG ) + iSize;

    // Update next frame offset
    STORE_HW( pFrame->hwOffset,
              pCTCBLK->iFrameOffset + sizeof( CTCIHDR ) );

    // Store segment length
    STORE_HW( pSegment->hwLength, sizeof( CTCISEG ) + iSize );

    // Store Frame type
    STORE_HW( pSegment->hwType, ETH_TYPE_IP );

    // Copy data
    memcpy( pSegment->bData, pData, iSize );

    // Mark data pending
    pCTCBLK->fDataPending = 1;

    release_lock( &pCTCBLK->Lock );

    obtain_lock( &pCTCBLK->EventLock );
    signal_condition( &pCTCBLK->Event );
    release_lock( &pCTCBLK->EventLock );

    return 0;       // (0==success)
}
Ejemplo n.º 3
0
void  CTCI_Read( DEVBLK* pDEVBLK,   U16   sCount,
                 BYTE*   pIOBuf,    BYTE* pUnitStat,
                 U16*    pResidual, BYTE* pMore )
{
    PCTCBLK     pCTCBLK  = (PCTCBLK)pDEVBLK->dev_data;
    PCTCIHDR    pFrame   = NULL;
    size_t      iLength  = 0;
    int         rc       = 0;

    for ( ; ; )
    {
        obtain_lock( &pCTCBLK->Lock );

        if( !pCTCBLK->fDataPending )
        {
            struct timespec waittime;
            struct timeval  now;

            release_lock( &pCTCBLK->Lock );

            gettimeofday( &now, NULL );

            waittime.tv_sec  = now.tv_sec  + CTC_READ_TIMEOUT_SECS;
            waittime.tv_nsec = now.tv_usec * 1000;

            obtain_lock( &pCTCBLK->EventLock );
            rc = timed_wait_condition( &pCTCBLK->Event,
                                       &pCTCBLK->EventLock,
                                       &waittime );
            release_lock( &pCTCBLK->EventLock );

            if( rc == ETIMEDOUT || rc == EINTR )
            {
                // check for halt condition
                if( pDEVBLK->scsw.flag2 & SCSW2_FC_HALT ||
                    pDEVBLK->scsw.flag2 & SCSW2_FC_CLEAR )
                {
                    if( pDEVBLK->ccwtrace || pDEVBLK->ccwstep )
                        logmsg( _("HHCCT040I %4.4X: Halt or Clear Recognized\n"),
                                pDEVBLK->devnum );

                    *pUnitStat = CSW_CE | CSW_DE;
                    *pResidual = sCount;
                    return;
                }

                continue;
            }

            obtain_lock( &pCTCBLK->Lock );
        }

        // Sanity check
        if( pCTCBLK->iFrameOffset == 0 )
        {
            release_lock( &pCTCBLK->Lock );
            continue;
        }

        // Fix-up frame pointer and terminate block
        pFrame = (PCTCIHDR)( pCTCBLK->bFrameBuffer +
                  sizeof( CTCIHDR ) +
                  pCTCBLK->iFrameOffset );

        STORE_HW( pFrame->hwOffset, 0x0000 );

        // (fix for day-1 bug offered by Vince Weaver [[email protected]])
//      iLength = pCTCBLK->iFrameOffset + sizeof( CTCIHDR ) + 2;
        iLength = pCTCBLK->iFrameOffset + sizeof( CTCIHDR );

        if( sCount < iLength )
        {
            *pMore     = 1;
            *pResidual = 0;

            iLength    = sCount;
        }
        else
        {
            *pMore      = 0;
            *pResidual -= iLength;
        }

        *pUnitStat = CSW_CE | CSW_DE;

        memcpy( pIOBuf, pCTCBLK->bFrameBuffer, iLength );

        if( pCTCBLK->fDebug )
        {
            logmsg( _("HHCCT041I %4.4X: CTC Received Frame (%d bytes):\n"),
                    pDEVBLK->devnum, iLength );
            packet_trace( pCTCBLK->bFrameBuffer, iLength );
        }

        // Reset frame buffer
        pCTCBLK->iFrameOffset  = 0;
        pCTCBLK->fDataPending  = 0;

        release_lock( &pCTCBLK->Lock );

        return;
    }
}
Ejemplo n.º 4
0
/*-------------------------------------------------------------------*/
int bind_device_ex (DEVBLK* dev, char* spec, ONCONNECT fn, void* arg )
{
    bind_struct* bs;
    int was_list_empty;
    int rc;

    if (!init_done) init_sockdev();

    if (sysblk.shutdown) return 0;

    logdebug("bind_device (%4.4X, %s)\n", dev->devnum, spec);

    /* Error if device already bound */
    if (dev->bs)
    {
        WRMSG (HHC01041, "E", SSID_TO_LCSS(dev->ssid), dev->devnum, dev->bs->spec);
        return 0;   /* (failure) */
    }

    /* Create a new bind_struct entry */
    bs = malloc(sizeof(bind_struct));

    if (!bs)
    {
        char buf[40];
        MSGBUF( buf, "malloc(%d)", (int)sizeof(bind_struct));
        WRMSG (HHC01000, "E", SSID_TO_LCSS(dev->ssid), dev->devnum, buf, strerror(errno));
        return 0;   /* (failure) */
    }

    memset(bs, 0, sizeof(bind_struct));

    bs->fn  = fn;
    bs->arg = arg;

    if (!(bs->spec = strdup(spec)))
    {
        WRMSG (HHC01000, "E", SSID_TO_LCSS(dev->ssid), dev->devnum, "strdup()", strerror(errno) );
        free (bs);
        return 0;   /* (failure) */
    }

    /* Create a listening socket */
    if (bs->spec[0] == '/') bs->sd = unix_socket (bs->spec);
    else                    bs->sd = inet_socket (bs->spec);
    if (bs->sd == -1)
    {
        /* (error message already issued) */
        free( bs->spec );
        free( bs );
        return 0; /* (failure) */
    }

    /* Chain device and bind_struct to each other */
    dev->bs = bs;
    bs->dev = dev;

    /* Add the new entry to our list of bound devices
       and create the socket thread that will listen
       for connections (if it doesn't already exist) */

    obtain_lock( &bind_lock );

    was_list_empty = IsListEmpty( &bind_head );

    InsertListTail( &bind_head, &bs->bind_link );

    if ( was_list_empty )
    {
        rc = create_thread( &sysblk.socktid, JOINABLE,
                            socket_thread, NULL, "socket_thread" );
        if (rc)
        {
            WRMSG(HHC00102, "E", strerror( rc ) );
            RemoveListEntry( &bs->bind_link );
            close_socket(bs->sd);
            free( bs->spec );
            free( bs );
            release_lock( &bind_lock );
            return 0; /* (failure) */
        }
    }

    SIGNAL_SOCKDEV_THREAD();

    release_lock( &bind_lock );

    WRMSG (HHC01042, "I", SSID_TO_LCSS(dev->ssid), dev->devnum, dev->bs->spec);

    return 1;   /* (success) */
}
Ejemplo n.º 5
0
/*-------------------------------------------------------------------*/
int unbind_device_ex (DEVBLK* dev, int forced)
{
    bind_struct* bs;

    logdebug("unbind_device(%4.4X)\n", dev->devnum);

    /* Error if device not bound */
    if (!(bs = dev->bs))
    {
        WRMSG (HHC01043, "E", SSID_TO_LCSS(dev->ssid), dev->devnum);
        return 0;   /* (failure) */
    }

    /* Is anyone still connected? */
    if (dev->fd != -1)
    {
        /* Yes. Should we forcibly disconnect them? */
        if (forced)
        {
            /* Yes. Then do so... */
            close_socket( dev->fd );
            dev->fd = -1;
            WRMSG (HHC01044, "I", SSID_TO_LCSS(dev->ssid), dev->devnum, dev->bs->clientip,
                   dev->bs->clientname, dev->bs->spec);
        }
        else
        {
            /* No. Then fail the request. */
            WRMSG (HHC01045, "E", SSID_TO_LCSS(dev->ssid), dev->devnum, dev->bs->clientip,
                   dev->bs->clientname, dev->bs->spec);
            return 0;   /* (failure) */
        }
    }

    /* Remove the entry from our list */

    obtain_lock( &bind_lock );
    RemoveListEntry( &bs->bind_link );
    SIGNAL_SOCKDEV_THREAD();
    release_lock( &bind_lock );

    WRMSG (HHC01046, "I",SSID_TO_LCSS(dev->ssid), dev->devnum, bs->spec);

    if (bs->sd != -1)
        close_socket (bs->sd);

    /* Unchain device and bind_struct from each another */

    dev->bs = NULL;
    bs->dev = NULL;

    /* Discard the entry */

    if ( bs->clientname ) free( bs->clientname );
    if ( bs->clientip   ) free( bs->clientip   );

    bs->clientname = NULL;
    bs->clientip   = NULL;

    free ( bs->spec );
    free ( bs );

    return 1;   /* (success) */
}
Ejemplo n.º 6
0
/*-------------------------------------------------------------------*/
void socket_device_connection_handler (bind_struct* bs)
{
    struct sockaddr_in  client;         /* Client address structure  */
    struct hostent*     pHE;            /* Addr of hostent structure */
    socklen_t           namelen;        /* Length of client structure*/
    char*               clientip;       /* Addr of client ip address */
    char*               clientname;     /* Addr of client hostname   */
    DEVBLK*             dev;            /* Device Block pointer      */
    int                 csock;          /* Client socket             */

    dev = bs->dev;

    logdebug("socket_device_connection_handler(dev=%4.4X)\n",
             dev->devnum);

    /* Accept the connection... */

    csock = accept(bs->sd, 0, 0);

    if (csock == -1)
    {
        WRMSG (HHC01000, "E", SSID_TO_LCSS(dev->ssid), dev->devnum, "accept()", strerror(HSO_errno));
        return;
    }

    /* Determine the connected client's IP address and hostname */

    namelen = sizeof(client);
    clientip = NULL;
    clientname = "<unknown>";

    if (1
            && getpeername(csock, (struct sockaddr*) &client, &namelen) == 0
            && (clientip = inet_ntoa(client.sin_addr)) != NULL
            && (pHE = gethostbyaddr((unsigned char*)(&client.sin_addr),
                                    sizeof(client.sin_addr), AF_INET)) != NULL
            && pHE->h_name && *pHE->h_name
       )
    {
        clientname = (char*) pHE->h_name;
    }

    if (!clientip) clientip = "<unknown>";

    /* Obtain the device lock */

    obtain_lock (&dev->lock);

    /* Reject if device is busy or interrupt pending */

    if (dev->busy || IOPENDING(dev)
            || (dev->scsw.flag3 & SCSW3_SC_PEND))
    {
        close_socket( csock );
        WRMSG (HHC01037, "E", SSID_TO_LCSS(dev->ssid), dev->devnum, clientname, clientip, bs->spec);
        release_lock (&dev->lock);
        return;
    }

    /* Reject new client if previous client still connected */

    if (dev->fd != -1)
    {
        close_socket( csock );
        WRMSG (HHC01038, "E", SSID_TO_LCSS(dev->ssid), dev->devnum, clientname, clientip, bs->spec,
               bs->clientname, bs->clientip);
        release_lock (&dev->lock);
        return;
    }

    /* Indicate that a client is now connected to this device */

    dev->fd = csock;

    if (bs->clientip)   free(bs->clientip);
    if (bs->clientname) free(bs->clientname);

    bs->clientip   = strdup(clientip);
    bs->clientname = strdup(clientname);

    /* Call the boolean onconnect callback */

    if (bs->fn && !bs->fn( bs->arg ))
    {
        /* Callback says it can't accept it */
        close_socket( dev->fd );
        dev->fd = -1;
        WRMSG (HHC01039, "E", SSID_TO_LCSS(dev->ssid), dev->devnum, clientname, clientip, bs->spec);
        release_lock (&dev->lock);
        return;
    }

    WRMSG (HHC01040, "I", SSID_TO_LCSS(dev->ssid), dev->devnum, clientname, clientip, bs->spec);

    release_lock (&dev->lock);
    device_attention (dev, CSW_DE);
}
Ejemplo n.º 7
0
/*---------------------------------------------------------------------------*/
static void hao_message(char *buf)
{
  char work[HAO_WKLEN];
  char cmd[HAO_WKLEN];
  regmatch_t rm[HAO_MAXCAPT+1];
  int i, j, k, numcapt;
  size_t n;
  char *p;

  /* copy and strip spaces */
  hao_cpstrp(work, buf);

  /* strip the herc prefix */
  while(!strncmp(work, "herc", 4))
    hao_cpstrp(work, &work[4]);

  /* Ignore the message if we should (e.g. if one of our own!) */
  if (hao_ignoremsg( work ))
      return;

  /* serialize */
  obtain_lock(&ao_lock);

  /* check all defined rules */
  for(i = 0; i < HAO_MAXRULE; i++)
  {
    if(ao_tgt[i] && ao_cmd[i])  /* complete rule defined in this slot? */
    {
      /* does this rule match our message? */
      if (regexec(&ao_preg[i], work, HAO_MAXCAPT+1, rm, 0) == 0)
      {
        /* count the capturing group matches */
        for (j = 0; j <= HAO_MAXCAPT && rm[j].rm_so >= 0; j++);
        numcapt = j - 1;

        /* copy the command and process replacement patterns */
        for (n=0, p=ao_cmd[i]; *p && n < sizeof(cmd)-1; ) {
          /* replace $$ by $ */
          if (*p == '$' && p[1] == '$') {
            cmd[n++] = '$';
            p += 2;
            continue;
          }
          /* replace $` by characters to the left of the match */
          if (*p == '$' && p[1] == '`') {
            n += hao_subst(work, 0, rm[0].rm_so, cmd, n, sizeof(cmd));
            p += 2;
            continue;
          }
          /* replace $' by characters to the right of the match */
          if (*p == '$' && p[1] == '\'') {
            n += hao_subst(work, rm[0].rm_eo, strlen(work), cmd, n, sizeof(cmd));
            p += 2;
            continue;
          }
          /* replace $1..$99 by the corresponding capturing group */
          if (*p == '$' && isdigit(p[1])) {
            if (isdigit(p[2])) {
              j = (p[1]-'0') * 10 + (p[2]-'0');
              k = 3;
            } else {
              j = p[1]-'0';
              k = 2;
            }
            if (j > 0 && j <= numcapt) {
              n += hao_subst(work, rm[j].rm_so, rm[j].rm_eo, cmd, n, sizeof(cmd));
              p += k;
              continue;
            }
          }
          /* otherwise copy one character */
          cmd[n++] = *p++;
        }
        cmd[n] = '\0';

        /* issue command for this rule */
        WRMSG(HHC00081, "I", i, cmd);
        panel_command(cmd);
      }
    }
  }
  release_lock(&ao_lock);
}
Ejemplo n.º 8
0
/*---------------------------------------------------------------------------*/
static void hao_cmd(char *arg)
{
  int i;
  int j;

  /* serialize */
  obtain_lock(&ao_lock);

  /* find the free slot */
  for(i = 0; ao_cmd[i] && i < HAO_MAXRULE; i++);

  /* check for table full -> so tgt cmd expected */
  if(i == HAO_MAXRULE)
  {
    release_lock(&ao_lock);
    WRMSG(HHC00071, "E", "command", HAO_MAXRULE);
    return;
  }

  /* check if target is given */
  if(!ao_tgt[i])
  {
    release_lock(&ao_lock);
    WRMSG(HHC00072, "E", "cmd", "tgt");
    return;
  }

  /* check for empty cmd string */
  if(!strlen(arg))
  {
    release_lock(&ao_lock);
    WRMSG(HHC00073, "E", "command");
    return;
  }

  /* check for hao command, prevent deadlock */
  for(j = 0; !strncasecmp(&arg[j], "herc ", 4); j += 5);
  if(!strcasecmp(&arg[j], "hao") || !strncasecmp(&arg[j], "hao ", 4))
  {
    release_lock(&ao_lock);
    WRMSG(HHC00078, "E");
    return;
  }

  /* check for possible loop */
  for(j = 0; j < HAO_MAXRULE; j++)
  {
    if(ao_tgt[j] && !regexec(&ao_preg[j], arg, 0, NULL, 0))
    {
      release_lock(&ao_lock);
      WRMSG(HHC00076, "E", "command", "target", j);
      return;
    }
  }

  /* duplicate the string */
  ao_cmd[i] = strdup(arg);

  /* check duplication */
  if(!ao_cmd[i])
  {
    release_lock(&ao_lock);
    WRMSG(HHC00075, "E", "strdup()", strerror(ENOMEM));
    return;
  }

  release_lock(&ao_lock);
  WRMSG(HHC00077, "I", "command", i);
}
Ejemplo n.º 9
0
/*---------------------------------------------------------------------------*/
static void hao_tgt(char *arg)
{
  int i;
  int j;
  int rc;
  char work[HAO_WKLEN];

  /* serialize */
  obtain_lock(&ao_lock);

  /* find a free slot */
  for(i = 0; ao_tgt[i] && i < HAO_MAXRULE; i++)

  /* check for table full */
  if(i == HAO_MAXRULE)
  {
    release_lock(&ao_lock);
    WRMSG(HHC00071, "E", "target", HAO_MAXRULE);
    return;
  }

  /* check if not command is expected */
  for(j = 0; j < HAO_MAXRULE; j++)
  {
    if(ao_tgt[j] && !ao_cmd[j])
    {
      release_lock(&ao_lock);
      WRMSG(HHC00072, "E", "tgt", "cmd");
      return;
    }
  }

  /* check for empty target */
  if(!strlen(arg))
  {
    release_lock(&ao_lock);
    WRMSG(HHC00073, "E", "target");
    return;
  }

  /* check for duplicate targets */
  for(j = 0; j < HAO_MAXRULE; j++)
  {
    if(ao_tgt[j] && !strcmp(arg, ao_tgt[j]))
    {
      release_lock(&ao_lock);
      WRMSG(HHC00074, "E", j);
      return;
    }
  }

  /* compile the target string */
  rc = regcomp(&ao_preg[i], arg, REG_EXTENDED);

  /* check for error */
  if(rc)
  {
    release_lock(&ao_lock);

    /* place error in work */
    regerror(rc, (const regex_t *) &ao_preg[i], work, HAO_WKLEN);
    WRMSG(HHC00075, "E", "regcomp()", work);
    return;
  }

  /* check for possible loop */
  for(j = 0; j < HAO_MAXRULE; j++)
  {
    if(ao_cmd[j] && !regexec(&ao_preg[i], ao_cmd[j], 0, NULL, 0))
    {
      release_lock(&ao_lock);
      regfree(&ao_preg[i]);
      WRMSG(HHC00076, "E", "target", "command", i);
      return;
    }
  }

  /* duplicate the target */
  ao_tgt[i] = strdup(arg);

  /* check duplication */
  if(!ao_tgt[i])
  {
    release_lock(&ao_lock);
    regfree(&ao_preg[i]);
    WRMSG(HHC00075, "E", "strdup()", strerror(ENOMEM));
    return;
  }

  release_lock(&ao_lock);
  WRMSG(HHC00077, "I", "target", i);
}
Ejemplo n.º 10
0
/*-------------------------------------------------------------------*/
int ARCH_DEP(load_ipl) (U16 lcss, U16 devnum, int cpu, int clear)
{
REGS   *regs;                           /* -> Regs                   */
DEVBLK *dev;                            /* -> Device control block   */
int     i;                              /* Array subscript           */
BYTE    unitstat;                       /* IPL device unit status    */
BYTE    chanstat;                       /* IPL device channel status */

    /* Get started */
    if (ARCH_DEP(common_load_begin) (cpu, clear) != 0)
        return -1;

    /* The actual IPL proper starts here... */

    regs = sysblk.regs[cpu];    /* Point to IPL CPU's registers */

    /* Point to the device block for the IPL device */
    dev = find_device_by_devnum (lcss,devnum);
    if (dev == NULL)
    {
        logmsg (_("HHCCP027E Device %4.4X not in configuration%s\n"),
                devnum,
                (sysblk.arch_mode == ARCH_370 ?
                  " or not connected to channelset" : ""));
        HDC1(debug_cpu_state, regs);
        return -1;
    }
#if defined(OPTION_IPLPARM)
    if(sysblk.haveiplparm)
    {
        for(i=0;i<16;i++)
        {
            regs->GR_L(i)=fetch_fw(&sysblk.iplparmstring[i*4]);
        }
        sysblk.haveiplparm=0;
    }
#endif

    /* Set Main Storage Reference and Update bits */
    STORAGE_KEY(regs->PX, regs) |= (STORKEY_REF | STORKEY_CHANGE);
    sysblk.main_clear = sysblk.xpnd_clear = 0;

    /* Build the IPL CCW at location 0 */
    regs->psa->iplpsw[0] = 0x02;              /* CCW command = Read */
    regs->psa->iplpsw[1] = 0;                 /* Data address = zero */
    regs->psa->iplpsw[2] = 0;
    regs->psa->iplpsw[3] = 0;
    regs->psa->iplpsw[4] = CCW_FLAGS_CC | CCW_FLAGS_SLI;
                                        /* CCW flags */
    regs->psa->iplpsw[5] = 0;                 /* Reserved byte */
    regs->psa->iplpsw[6] = 0;                 /* Byte count = 24 */
    regs->psa->iplpsw[7] = 24;

    /* Enable the subchannel for the IPL device */
    dev->pmcw.flag5 |= PMCW5_E;

    /* Build the operation request block */                    /*@IWZ*/
    memset (&dev->orb, 0, sizeof(ORB));                        /*@IWZ*/
    dev->busy = 1;

    RELEASE_INTLOCK(NULL);

    /* Execute the IPL channel program */
    ARCH_DEP(execute_ccw_chain) (dev);

    OBTAIN_INTLOCK(NULL);

    /* Clear the interrupt pending and device busy conditions */
    obtain_lock (&sysblk.iointqlk);
    DEQUEUE_IO_INTERRUPT_QLOCKED(&dev->ioint);
    DEQUEUE_IO_INTERRUPT_QLOCKED(&dev->pciioint);
    DEQUEUE_IO_INTERRUPT_QLOCKED(&dev->attnioint);
    release_lock(&sysblk.iointqlk);
    dev->busy = 0;
    dev->scsw.flag2 = 0;
    dev->scsw.flag3 = 0;

    /* Check that load completed normally */
#ifdef FEATURE_S370_CHANNEL
    unitstat = dev->csw[4];
    chanstat = dev->csw[5];
#endif /*FEATURE_S370_CHANNEL*/

#ifdef FEATURE_CHANNEL_SUBSYSTEM
    unitstat = dev->scsw.unitstat;
    chanstat = dev->scsw.chanstat;
#endif /*FEATURE_CHANNEL_SUBSYSTEM*/

    if (unitstat != (CSW_CE | CSW_DE) || chanstat != 0) {
        logmsg (_("HHCCP029E %s mode IPL failed: CSW status=%2.2X%2.2X\n"
                  "           Sense="),
                get_arch_mode_string(regs), unitstat, chanstat);
        for (i=0; i < (int)dev->numsense; i++)
        {
            logmsg ("%2.2X", dev->sense[i]);
            if ((i & 3) == 3) logmsg(" ");
        }
        logmsg ("\n");
        HDC1(debug_cpu_state, regs);
        return -1;
    }

#ifdef FEATURE_S370_CHANNEL
    /* Test the EC mode bit in the IPL PSW */
    if (regs->psa->iplpsw[1] & 0x08) {
        /* In EC mode, store device address at locations 184-187 */
        STORE_FW(regs->psa->ioid, dev->devnum);
    } else {
        /* In BC mode, store device address at locations 2-3 */
        STORE_HW(regs->psa->iplpsw + 2, dev->devnum);
    }
#endif /*FEATURE_S370_CHANNEL*/

#ifdef FEATURE_CHANNEL_SUBSYSTEM
    /* Set LPUM */
    dev->pmcw.lpum = 0x80;
    STORE_FW(regs->psa->ioid, (dev->ssid<<16)|dev->subchan);

    /* Store zeroes at locations 188-191 */
    memset (regs->psa->ioparm, 0, 4);
#endif /*FEATURE_CHANNEL_SUBSYSTEM*/

    /* Save IPL device number, cpu number and lcss */
    sysblk.ipldev = devnum;
    sysblk.iplcpu = regs->cpuad;
    sysblk.ipllcss = lcss;

    /* Finish up... */
    return ARCH_DEP(common_load_finish) (regs);
} /* end function load_ipl */