Ejemplo n.º 1
0
Archivo: achtool.c Proyecto: KimBP/ach
int main( int argc, char **argv ) {
    /* Parse Options */
    int c, i = 0;
    opterr = 0;
    while( (c = getopt( argc, argv, "C:U:D:F:vn:m:o:1thH?V")) != -1 ) {
        switch(c) {
        case 'C':   /* create   */
            parse_cmd( cmd_create, optarg );
            break;
        case 'U':   /* unlink   */
            parse_cmd( cmd_unlink, optarg );
            break;
        case 'D':   /* dump     */
            parse_cmd( cmd_dump, optarg );
            break;
        case 'F':   /* file     */
            parse_cmd( cmd_file, optarg );
            break;
        case 'n':   /* msg-size */
            opt_msg_size = (size_t)atoi( optarg );
            break;
        case 'm':   /* msg-cnt  */
            opt_msg_cnt = (size_t)atoi( optarg );
            break;
        case 'o':   /* mode     */
            opt_mode = parse_mode( optarg );
            break;
        case 't':   /* truncate */
            opt_truncate++;
            break;
        case 'v':   /* verbose  */
            opt_verbosity++;
            break;
        case '1':   /* once     */
            opt_1++;
            break;
        case 'V':   /* version     */
            ach_print_version("ach");
            exit(EXIT_SUCCESS);
        case '?':   /* help     */
        case 'h':
        case 'H':
            puts( "Usage: ach [OPTION...] [mk|rm|chmod|dump|file] [mode] [channel-name]\n"
                  "General tool to interact with ach channels\n"
                  "\n"
                  "Options:\n"
                  /* "  -C CHANNEL-NAME,          Create a new channel\n" */
                  /* "  -U CHANNEL-NAME,          Unlink (delete) a channel\n" */
                  /* "  -D CHANNEL-NAME,          Dump info about channel\n" */
                  "  -1,                       With 'mk', accept an already created channel\n"
                  /* "  -F CHANNEL-NAME,          Print filename for channel (Linux-only)\n" */
                  "  -m MSG-COUNT,             Number of messages to buffer\n"
                  "  -n MSG-SIZE,              Nominal size of a message\n"
                  "  -o OCTAL,                 Mode for created channel\n"
                  "  -t,                       Truncate and reinit newly create channel.\n"
                  "                            WARNING: this will clobber processes\n"
                  "                            Currently using the channel.\n"
                  "  -v,                       Make output more verbose\n"
                  "  -?,                       Give program help list\n"
                  "  -V,                       Print program version\n"
                  "\n"
                  "Examples:\n"
                  "  ach mk foo                Create channel 'foo' with default buffer sizes.\n"
                  "  ach mk foo -m 10 -n 256   Create channel 'foo' which can buffer up to 10\n"
                  "                            messages of nominal size 256 bytes.\n"
                  "                            Bigger/smaller messages are OK, up to 10*256\n"
                  "                            bytes max (only one message of that size can be\n"
                  "                            buffered at a time).\n"
                  "  ach rm foo                Remove channel 'foo'\n"
                  "  ach mk -1 foo             Create channel 'foo' unless it already exists,\n"
                  "                            in which case leave it alone.\n"
                  "  ach mk foo -o 600         Create channel 'foo' with octal permissions\n"
                  "                            '600'. Note that r/w (6) permission necessary\n"
                  "                            for channel access in order to properly\n"
                  "                            synchronize.\n"
                  "  ach chmod 666 foo         Set permissions of channel 'foo' to '666'\n"
                  "  ach search foo            Search mDNS for host and port of channel 'foo'\n"
                  "\n"
                  "Report bugs to <*****@*****.**>"
                );
            exit(EXIT_SUCCESS);
        default:
            posarg(i++, optarg);
        }
    }
    while( optind < argc ) {
        posarg(i++, argv[optind++]);
    }

    /* Be Verbose */
    if( opt_verbosity >= 2 ) {
        fprintf(stderr, "Verbosity:    %d\n", opt_verbosity);
        fprintf(stderr, "Channel Name: %s\n", opt_chan_name);
        fprintf(stderr, "Message Size: %"PRIuPTR"\n", opt_msg_size);
        fprintf(stderr, "Message Cnt:  %"PRIuPTR"\n", opt_msg_cnt);
    }
    /* Do Something */
    int r;
    errno = 0;
    if( opt_command ) {
        r = opt_command();
    } else if ( opt_chan_name && opt_mode >= 0 ) {
        r = cmd_chmod();
    } else{
        fprintf(stderr, "Must specify a command. Say `ach -H' for help.\n");
        r = EXIT_FAILURE;
    }
    cleanup();
    return r;
}
Ejemplo n.º 2
0
int main( int argc, char **argv ) {
    /* Check if we're running under achcop */
    if( getenv("ACHCOP") ) {
        ach_pid_notify = getppid();
    }

    int c;
    while( (c = getopt( argc, argv, "zlnh?V")) != -1 ) {
        switch(c) {
        case 'v':
            ach_verbosity ++;
            break;
        case 'l':
            opt_last = 1;
            break;
        case 'n':
            opt_last = 0;
            break;
        case 'z':
            opt_gzip = 1;
            break;
        /* case 'f': */
        /*     opt_freq = atof(optarg); */
        /*     break; */
        case 'V':   /* version     */
            ach_print_version("achpipe.bin");
            exit(EXIT_SUCCESS);
        case '?':
        case 'h':
        case 'H':
            puts( "Usage: achlog [OPTIONS] channels...\n"
                  "Log ach channels to files"
                  "\n"
                  "Options:\n"
                  "  -?,                  Show help\n"
                  "  -z,                  Filter output through gzip\n"
                  "\n"
                  "Examples:\n"
                  "  achlog foo bar       Log channels foo and bar\n"
                  "\n"
                  "Report bugs to <*****@*****.**>"
                );
            exit(EXIT_SUCCESS);
        default:
            posarg(optarg);
        }
    }
    while( optind < argc ) {
        posarg(argv[optind++]);
    }
    if( 0 == n_log ) ACH_DIE("No channels to log\n");

    /* Block Signals */
    /* Have to block these before forking so ctrl-C doesn't kill the
     * gzip */
    int sigs[] = {SIGTERM, SIGINT, 0};
    ach_sig_block_dummy( sigs );

    /* Open Channels */
    size_t i;
    for( i = 0; i < n_log; i ++ ) {
        ach_status_t r = ach_open(&log_desc[i].chan, log_desc[i].name, NULL);
        if( ACH_OK != r ) {
            ACH_DIE( "Could not open channel %s: %s\n",
                     log_desc[i].name, ach_result_to_string(r) );
        }
        /* Open log file */
        if( opt_gzip ) {
            log_desc[i].fout = filter( "gzip -c", log_desc[i].name, ".gz" );
        } else {
            log_desc[i].fout = fopen(log_desc[i].name, "w");
        }
        if( NULL == log_desc[i].fout ) {
            ACH_DIE( "Could not open log file for %s: %s\n",
                     log_desc[i].name, strerror(errno) );
        }
    }

    /* get some data */
    if( clock_gettime(ACH_DEFAULT_CLOCK, &now_ach ) ||
        clock_gettime(CLOCK_REALTIME,    &now_real ) )
    {
        ACH_DIE( "Could not get time: %s\n", strerror(errno) );
    }
    if( gethostname( host, sizeof(host) ) ) {
        ACH_LOG(LOG_ERR, "Could not get host name: %s\n", strerror(errno));
    }
    host[sizeof(host)-1] = '\0';
    passwd = getpwuid(getuid());
    if( passwd ) {
        strtok(passwd->pw_gecos, ",");
    }
    now_real_str = ctime( &now_real.tv_sec );

    /* Create Workers */
    pthread_t thread[n_log];
    for( i = 0; i < n_log; i ++ ) {
        int r = pthread_create( thread+i, NULL, worker, (void*)(log_desc+i) );
        if( r ) ACH_DIE( "Couldn't start worker thread: %s\n", strerror(r) );
    }
    ach_notify(ACH_SIG_OK);

    /* Wait for Signal */
    ach_sig_wait( sigs );

    /* Cancel workers */
    ach_cancel_attr_t cattr;
    ach_cancel_attr_init( &cattr );
    cattr.async_unsafe = 1;
    for( i = 0; i < n_log; i ++ ) {
        ach_cancel( &log_desc[i].chan, &cattr );
    }

    /* Join worker threads */
    for( i = 0; i < n_log; i ++ ) {
        int r = pthread_join( thread[i], NULL );
        if( r ) ACH_DIE( "Couldn't join worker thread: %s\n", strerror(r) );
        if( opt_gzip ) {
            if( pclose(log_desc[i].fout) < 0 ) {
                ACH_LOG( LOG_ERR, "Could not pclose output for %s: %s\n",
                         log_desc[i].name, strerror(errno) );
            }
        } else {
            fclose(log_desc[i].fout);
        }
    }

    return 0;
}
Ejemplo n.º 3
0
/* style 2: baud=... parity=... data=... stop=... retry=... */
int serial(int snum, char * what)
{
  unsigned int xbaud, baud, xparity, data, stop, xretry;
  char parity, retry;

#ifdef DMODE
  static long int baudlist[] = { 110, 150, 300, 600,
    1200, 2400, 4800, 9600,   19200, 38400L, 57600L, 115200L
  }; /* baudlist */
#endif

  if ( (what == NULL) || (!strncmp(what, "/STA", 4)) ) {
    int i;
    static char * serbits[] = {
      "delta-CTS", "delta-DSR", "RI-trail", "delta-CD",
      "CTS", "DSR", "RI", "CD",
      /* modem: cleartosend, datasetready, ringindicator, carrierdetect */
      "data-received", "overrun", "parity-error", "frame-error",
      "break-received", "xmit-hold-empty", "xmit-shift-empty", "timeout"
    }; /* serbits */
    printf("*** SERIAL PORT %d STATUS ***\r\n", snum+1);

    r.x.ax = 0x0300; /* read status */
    r.x.dx = snum;
    int86(0x14, &r, &r);
    printf("Port status: [ ");
    for (i=15; i>=0; i--) {
      if ( (r.x.ax & (1<<i)) != 0)
        printf("%s ", serbits[i]);
    }
    printf("]\r\n");

#ifndef DMODE2 /* Tell about BAUDHARD=1 only if /STA... given, unless DMODE2 */
    if ( (what != NULL) && (!strncmp(what, "/STA", 4)) ) {
#else
    {
#endif
      printf("Use MODE COM%d BAUDHARD=1 to read *configuration* from UART.\r\n",
        snum+1);
    }

    return 0;
  }

  if (strchr(what,'=') != NULL) {
    baud   = grabarg(what, "BAUD=");
    xbaud   = grabarg(what, "BAUDHARD="); /* new 4/2004 */
    xparity = grabarg(what, "PARITY=");
    data   = grabarg(what, "DATA=");
    stop   = grabarg(what, "STOP=");
    xretry  = grabarg(what, "RETRY=");
  } else {
    what = skipspace(what);
    if ( (what[0]!=',') && (!isdigit(what[0])) ) {
      printf("Syntax error in 'MODE COMn ...', please check 'MODE /?'.\r\n");
      return 1;
    }
    baud   = posarg(what, 0);
    xbaud = 0;
    xparity = posarg(what, 1);
    data   = posarg(what, 2);
    stop   = posarg(what, 3);
    xretry  = posarg(what, 4);
  }

  if ( (baud==0) && (xparity==0) && (data==0) && (stop==0) && (xretry==0)
    && (xbaud==0) ) {
    printf("Syntax error in 'MODE COMn ...', please check 'MODE /?'.\r\n");
    return 1;
  }

  if ( (data>8) || ((data<5) && (data!=0)) ) {
    printf("Data bits must be 5, 6, 7 or 8.\r\n");
    return 1; /* failed */
  }

  if ( (stop>2) || (stop<0) ) {
    printf("Stop bits must be 1 or 2.\r\n");
    printf("(2 stopbits treated as 1.5 if 5 or 6 data bits).\r\n");
    return 1; /* failed */
  }

  retry = (char)xretry;
  xretry = xlatretry(retry);
  if (xretry<0) return 1; /* error */
  if ((xretry==2) || (xretry==3)) /* if busy: 0 busy  1 error  2 ready */
                                  /*          3 keep trying 4 no retry */
    printf("Not yet supported RETRY value - ignored.\r\n");
    /* Reason: We do not hook int 14h at all (yet) ;-) ! */

  parity = (char)xparity;
  switch (parity) {
    case 'N':
      xparity = 0; /* none */
      break;
    case 'O':
      xparity = 1; /* odd */
      break;
    case 'E':
      xparity = 2; /* even (3 for old style API) */
      break;
    case 'S':
      xparity = 3; /* space? (new style API only) */
      break;
    case 'M':
      xparity = 4; /* mark? (new style API only) */
      break;
    case 0:
      xparity = 0; /* default parity setting: no parity */
      parity = '-';
      break;
    default:
      printf("Parity must be N, O, E, S or M (none, odd, even, space, mark).\r\n");
      return 1; /* failed */
  } /* switch */

  if (stop==0)
    stop = (baud==110) ? 2 : 1; /* default number of stop bits */

  if ((baud % 10) == 0) baud /= 10; /* strip at most 2 trailing zeroes */
  if ((baud % 10) == 0) baud /= 10; /* strip at most 2 trailing zeroes */

  switch (baud) {
    case 11:  /*   110 (caveat: 11 could also abbreviate 115200 (*)) */
      baud = 0;
      break;
    case 15:  /*   150 */
      baud = 1;
      break;
    case 3:   /*   300 (caveat: 3 could also abbreviate 38400 (*)) */
      baud = 2;
      break;
    case 6:   /*   600 (*) */
      baud = 3;
      break;
    case 12:  /*  1200 */
      baud = 4;
      break;
    case 0: /* default baud value is 2400 in most DOS versions */
    case 24:  /*  2400 */
      baud = 5;
      break;
    case 48:  /*  4800 */
      baud = 6;
      break;
    case 96:  /*  9600 */
      baud = 7;
      break;
    /* 14400 ??? */
    case 19:  /* 19200 */
    case 192:
      baud = 8; /* from here on we have to use the new API */
      break;
    /* 28800 ??? */
    case 38:  /* 38400 (supported?) */
    case 384:
      baud = 9;
      break;
    case 57:  /* 57600 (supported?) */
    case 576:
      baud = 10;
      break;
    case 115: /* 115200 (supported?) */
    case 1152:
    case 0xc200: /* 115200 & 0xffff */
      baud = 11;
      break;
    default:
      printf("BIOS-Unsupported baud rate, sorry.\r\n");
      printf("Please use BAUDHARD=value, with value=baud rate / 100\r\n");
      printf("e.g. BAUDHARD=1152 for 115200 baud, to program baud rate\r\n");
      printf("directly into UART hardware. BAUDHARD=1 reads UART config!\r\n");
      return 1;
  } /* switch */
  if ((baud > 8) && (baud < 12)) {
    printf("If your BIOS fails to set this baud rate properly, try\r\n");
    printf("using BAUDHARD=%d instead to program UART hardware directly.\r\n",
      (baud>9) ? ((baud==11) ? 1152 : 576) : 384);
  }

  /* (*) MS MODE only allows full values or 2 or 3 digit abbreviations, */
  /*  while we also allow "omit trailing zeroes" style 1 digit abbrev.! */

  if (data==0)
    data = 8; /* default number of data bits */

  r.x.dx = snum; /* port number */
  if ( (baud > 7) || (xparity > 2) ) { /* need new API? */
    r.x.ax = 0x0401; /* extended setup, no break */
    r.h.bh = xparity;
    r.h.bl = stop-1; /* 0 means 1, 1 means 2 (1.5 if 5 data bits) stop bits */
    r.h.ch = data-5; /* 0..3 means 5..8 data bits */
    r.h.cl = baud;   /* baud rate selector, values 0..8 same for all BIOSes */
    if (xbaud!=1)   /* do not SET before READING config! */
      int86(0x14, &r, &r);
    if (r.x.ax == 0x1954) { /* we got "FOSSIL init successful" */
                            /* which means that BX / CX had no effect */
      printf("FOSSIL driver detected, MODE could not configure port!\r\n");
      printf("You can use MODE with FOSSIL for max 9600 baud / normal parity only.\r\n");
    }
    if (r.x.ax == 0xaa55) {
      printf("MBBIOS detected, please use only 110-9600 baud and set\r\n");
      printf("the MBBIOS high speed option to translate to 9600-330400 baud.\r\n");
      r.x.ax = 0x1954;
    }
  } else {
    if (xparity==2)
      xparity=3; /* translate to old style value */
    r.h.ah = 0; /* initialize port */
    r.h.al = (baud<<5) | (xparity<<3) | ((stop-1)<<1) | (data-5);
    if (xbaud!=1)   /* do not SET before READING config! */
      int86(0x14, &r, &r);
  }
  /* returns status in AX */

  if (xbaud) {
    unsigned int sport = peek(0x40, snum+snum);
    unsigned int scratch;

    if (!sport) {
      printf("This serial port has no UART, sorry.\r\n");
      return 1;
    }

    disable();
    scratch = inportb(sport+7);
    outportb(sport+7, 0xea);
    printf("UART is ");
    if (inportb(sport+7) != 0xea) {
      if (xbaud!=1) {
        printf("8250, reading defaults!");
        xbaud = 1;
      } else
        printf("8250.");
    } else {
      outportb(sport+7, scratch);
      printf("16450 or newer."); /* or 8250A */
    }
    enable();

    printf(" %s:\r\n",
      (xbaud==1) ? "Reading parameters" : "Programming baud rate");
    if (xbaud>1152) { /* limit for 1.8432 MHz clock */
      printf("Maximum baud rate is 115200 (BAUDHARD=1152).\r\n");
      xbaud = 1;
    }

    if (xbaud==1) { /* parameter reading */

      /* line control: DLAB break PPP stop WW */
      /* PPP = 1x1 for sticky ~x parity, ??0 for no parity, 0x1 for */
      /* 0 odd / 1 even parity. stop 0 for 1 stop bit, 1 for 1.5 (WW=0) / 2 */
      /* WW 0..3 for 5..8 data bits */
      scratch = inportb(sport+3);
      if (scratch & 0x40) printf(" break,");
      if (scratch & 0x08) {
        printf(" %s parity,", (scratch & 0x20) ?
            ( (scratch & 0x10) ? "sticky low" : "sticky high" ) :
            ( (scratch & 0x10) ? "even" : "odd" ) );
      } else
        printf(" no parity,");
      printf(" %s, %d bit,", ( (scratch & 0x04) ?
          ( (scratch & 0x03) ? "2 stop bits" : "1.5 stop bits" ) :
          "1 stop bit" ),
        5 + (scratch & 0x03) );

      disable();
      outportb(sport+3, inportb(sport+3) | 0x80); /* divisor access */
#ifdef DIVISOR_WORD
      scratch = inport(sport);	/* divisor word */
#else
      scratch = inportb(sport+1); /* high byte */
      scratch <<= 8;
      scratch |= inportb(sport); /* low byte */ /* better read LO before HI? */
#endif
      outportb(sport+3, inportb(sport+3) & 0x7f);
      enable();

      if (scratch) {
        printf(" %ld baud,", 115200UL / scratch);
        xbaud = 1152 / scratch;
      } else {
        printf(" infinite baud rate!?,");
        xbaud = 9999;
      }
      scratch = inportb(sport+4);
      printf(" RTS %s, DTR %s.\r\n",
        ( (scratch & 2) ? "on" : "auto" ),
        ( (scratch & 1) ? "on" : "auto" ) );
      /* Modem control: ? ? (out0) loopback out2=irqenable out1=0 RTS DTR */
      /* (RTS / DTR set means "forced on" instead of "use for handshake") */

    } else {

      /* registers: +0/+1 divisor latch low/high if DLAB=1, +7 scratch...   */
      /* +3 line control +4 modem control +5 line status +6 modem status... */
      scratch = 1152 / xbaud; /* convert into divisor */
      printf(" %ld %s(divisor ", 115200UL / scratch,
        ((115200UL / scratch) != (100UL * xbaud)) ? "(had to round up) " : "" );

      disable();
      outportb(sport+3, inportb(sport+3) | 0x80); /* divisor access */
#ifdef DIVISOR_WORD
      outport(sport, scratch);	/* divisor word */
#else
      outportb(sport, scratch & 0xff); /* low byte */
      outportb(sport+1, scratch >> 8); /* high byte */
#endif
      outportb(sport+3, inportb(sport+3) & 0x7f);
      enable();

      printf("%d).\r\n", scratch);

#if SET_RTS_DTR
      /* to force RTS / DTR to on: */
      outportb(sport+4, inportb(sport+4) | 3);
      printf("Forcing RTS/DTR on.\r\n");
      /* should be done by drivers, e.g. raising on mouse init */
#endif

    } /* baud rate writing */

  } /* direct UART programming: BAUDHARD argument given */

#ifdef DMODE
  printf("MODE COM%d (x)baud=%ld parity=%c data=%d stop=%d (ignored: retry=%c)\r\n",
    snum+1, (xbaud) ? ((long int)xbaud * 100UL) : baudlist[baud],
    parity, data, stop, retry ? retry : '-');
#endif

  /* TODO: send RETRY setting to TSR part */

  return (r.x.ax==0x1954) ? 1 : 0;
} /* serial */