示例#1
0
int irods_reli_md5( const char *host, const char *path, char *digest )
{
	dataObjInp_t request;
	int result;
	char *str = 0;

	struct irods_server *server = connect_to_host(host);
	if(!server) return -1;

	memset(&request,0,sizeof(request));
	strcpy(request.objPath,path);
	
	debug(D_IRODS,"rcDataObjChksum %s %s",host,path);
	result = rcDataObjChksum(server->conn,&request,&str);
	debug(D_IRODS,"= %d",result);

	if(result<0) {
		errno = irods_reli_errno(result);
		return -1;
	} else {
		/* rcDataObjChecksum returns the checksum as ASCII */
		/* but Parrot is expecting 16 bytes of binary data */
		int i;

		for(i=0;i<16;i++) {
			digest[i] = hex_to_byte(&str[2*i]);
		}

		debug(D_IRODS,"%s",str);
		free(str);
		return 0;
	}
}
示例#2
0
void WolClient::parseMacAddress(const char* string, uint8_t* target) {
    uint8_t i = 0;
    uint8_t j = 0;
    uint8_t max = 17; // MAC String is 17 characters.
    while (i < max) {
        target[j++] = hex_to_byte(string[i], string[i + 1]);
        i += 3;
    }
}
示例#3
0
文件: http2.c 项目: Netping/DKSF-70
unsigned http_post_data_part(char *src_text, void *data, unsigned len) // LBS 24.02.2011
{
  char *d = data;
  for(int n=0; n<len; ++n)
  {
    d[n] = hex_to_byte(&src_text[n<<1]);
  }
  return len<<1;
}
示例#4
0
	boost::tribool
	consume( OutputIterator data, char input )
	{
		switch (state_) {
			case expecting_backslash:
				if (input == '\\') {
					state_ = expecting_x;
					return boost::indeterminate;
				} else {
					return false;
				}
			case expecting_x:
				if (input == 'x') {
					state_ = nibble_one;
					return true;
				} else {
					return false;
				}
			case nibble_one:
				if (std::isxdigit(input)) {
					most_sighificant_nibble_ = hex_to_byte(input);
					state_ = nibble_two;
					return boost::indeterminate;
				} else {
					return false;
				}
			case nibble_two:
				if (std::isxdigit(input)) {
					*data++ = (hex_to_byte(input) << 4) | most_sighificant_nibble_;
					state_ = nibble_one;
					return true;
				} else {
					return false;
				}
			default:
				break;
		}
	}
示例#5
0
文件: uart.c 项目: Phil-adelphia/ohc
void process_cmd(void)
{
	uart_putstr("Processing command: ");
	uart_putstr(cmdbuf);
	UART_PUTS("\r\n");
	
	if ((cmdbuf[0] == 'w') && (strlen(cmdbuf) == 5))
	{
		if (enable_write_eeprom)
		{
			uint16_t adr = hex_to_byte((uint8_t)cmdbuf[1]) * 16 + hex_to_byte((uint8_t)cmdbuf[2]);
			uint8_t val = hex_to_uint8((uint8_t *)cmdbuf, 3);
			UART_PUTF2("Writing data 0x%x to EEPROM pos 0x%x.\r\n", val, adr);
			eeprom_write_byte((uint8_t *)adr, val);
		}
		else
		{
			UART_PUTS("Ignoring EEPROM write, since write mode is DISABLED.\r\n");
		}
	}
	else if ((cmdbuf[0] == 'r') && (strlen(cmdbuf) == 3))
	{
		
		uint16_t adr = hex_to_byte((uint8_t)cmdbuf[1]) * 16 + hex_to_byte((uint8_t)cmdbuf[2]);
		uint8_t val = eeprom_read_byte((uint8_t *)adr);
		UART_PUTF2("EEPROM value at position 0x%x is 0x%x.\r\n", adr, val);
	}
	else if ((cmdbuf[0] == 's') && (strlen(cmdbuf) > 4))
	{
		strcpy(sendbuf, cmdbuf + 1);
		send_data_avail = true;
	}
	else
	{
		UART_PUTS("Unknown command.\r\n");
	}
}
示例#6
0
struct ether_addr Ethernet::readMAC(const char* buf)
{
	struct ether_addr temp;
	memset(&temp, 0, sizeof(temp));
	unsigned char* start = (unsigned char*)&temp;
	unsigned char* end = start + sizeof(temp);
	bool go_next = false;
	while(start < end)
	{
		if(!go_next)
		{
			int ret = hex_to_byte(*(buf++));
			if(ret == -1)
			{
				continue;
			}
			unsigned char current = (unsigned char)ret;
			current = current << 4;
			*start |= current;
			go_next = true;
		}
		else
		{
			int ret = hex_to_byte(*(buf++));
			if(ret == -1)
			{
				continue;
			}
			unsigned char current = (unsigned char)ret;
			*start |= current;
			go_next = false;
			start++;
		}
	}
	return temp;
}
示例#7
0
void parseCANStr(char *pBuf, OpenLcbCanBuffer *pCAN, uint8_t len)
{
  if( (pBuf[0] == ':') && (pBuf[len-1] == ';') && (len >= 4) && ( (pBuf[1] == 'X') || (pBuf[1] == 'S') ) )
  {
    memset(pCAN, 0, sizeof(tCAN));

    if (pBuf[1] == 'X') {
        pCAN->flags.extended = true ;
    } else {
        return;  // skip standard frames
    }
    
    char *pEnd;

    pCAN->id = strtoul(pBuf+2, &pEnd, 16);
    
    // If Standard Frame then check to see if Id is in the valid 11-bit range
    if((pCAN->flags.extended && (pCAN->id > 0x1FFFFFFF)) || (!pCAN->flags.extended && (pCAN->id > 0x07FF)))
      return;

    if(*pEnd == 'N')
    {
      pEnd++;
      pCAN->length = 0;
      while(isxdigit(*pEnd))
      {
        pCAN->data[pCAN->length] = hex_to_byte(pEnd);
        pCAN->length++;
        pEnd += 2;
      }
    }
    else if(*pEnd == 'R')
    {  
      pCAN->flags.rtr = 1;
      char tChar = *(pEnd+1);
      if(isdigit(tChar))
        pCAN->length = *(pEnd+1) - '0';
    }
    return;
  }
  return;
} 
uint8_t hex_set_to_byte(const char a, const char b)
{
  return ((hex_to_byte(a) << 4) +  hex_to_byte(b));
}
示例#9
0
static bool tlm_stream_decode(FILE *file, tlm_component *p_comp)
{
    /* Stream is: <Name>:<Var Size in Bytes>:<Array size>:<Type>:<HEX Bytes>\n */
    uint32_t exp_byte_cnt = 0; /* expected byte count */

    /* Get the header information prior to the hex data */
    char header[128] = { 0 };
    int i = 0, colon_count = 0;
    const int colon_count_of_hex_data = 4;
    for ( ; i < sizeof(header)-1; i++) {
        int c = fgetc(file);
        if (c == EOF) {
            goto decode_error;
        }
        if (c == ':' && (++colon_count) >= colon_count_of_hex_data) {
            break;
        }
        header[i] = c;
    }

    /* Break the header into pieces */
    char *tok_itr = 0;
    char *tok_name     = strtok_r(header, ":", &tok_itr);
    char *tok_var_size = strtok_r(NULL, ":", &tok_itr);
    char *tok_arr_size = strtok_r(NULL, ":", &tok_itr);
    if (NULL != tok_name && NULL != tok_var_size && NULL != tok_arr_size) {
        exp_byte_cnt = atoi(tok_var_size) * atoi(tok_arr_size);
    }
    else {
        goto decode_error;
    }

    /* Decode hex bytes after the header */
    const tlm_reg_var_type *reg_var = tlm_variable_get_by_name(p_comp, tok_name);
    if (NULL != reg_var &&
        (reg_var->elm_size_bytes) * (reg_var->elm_arr_size) == exp_byte_cnt)
    {
        char *dst = (char*)(reg_var->data_ptr);
        int terminator = EOF;

        for ( ; exp_byte_cnt != 0; --exp_byte_cnt) {
            char byte1 = fgetc(file);
            char byte2 = fgetc(file);
            terminator = fgetc(file); /* could be comma, \n or EOF */
            if (EOF == terminator) {
                goto decode_error;
            }

            char hex_bytes[] = { byte1, byte2, 0};
            char byte = hex_to_byte(hex_bytes);
            memcpy(dst, &byte, sizeof(byte));
            dst += sizeof(byte);
        }

        /* After we decode all hex bytes, the last char should be the
         * newline character because we still should have the last line
         * of telemetry stream containing "END:<comp name>"
         */
        if ('\n' != terminator) {
            goto decode_error;
        }
    } else {
        /* Handle unregistered variable */
    }

    return true;
    decode_error :
        return false;
}
示例#10
0
// ----------------------------------------------------------------------------
bool usbcan_decode_message(char *str, uint8_t length)
{
	can_t msg;
	uint8_t dlc_pos;
	bool extended;
	
	if (str[0] == 'R' || str[0] == 'T') {
		extended = true;
		dlc_pos = 9;
	}
	else {
		extended = false;
		dlc_pos = 4;
	}
	
	if (length < dlc_pos + 1)
		return false;
	
	// get the number of data-bytes for this message
	msg.length = str[dlc_pos] - '0';
	
	if (msg.length > 8)
		return false;		// too many data-bytes
	
	
	if (str[0] == 'r' || str[0] == 'R') {
		msg.flags.rtr = true;
		if (length != (dlc_pos + 1))
			return false;
	}
	else {
		msg.flags.rtr = false;
		if (length != (msg.length * 2 + dlc_pos + 1))
			return false;
	}
	
	// read the messge-identifier
	if (extended)
	{
		uint16_t id;
		uint16_t id2;
		
		id  = hex_to_byte(&str[1]) << 8;
		id |= hex_to_byte(&str[3]);
		
		id2  = hex_to_byte(&str[5]) << 8;
		id2 |= hex_to_byte(&str[7]);
		
		msg.id = (uint32_t) id << 16 | id2;
	}
	else {
		uint16_t id;
		
		id  = char_to_byte(&str[1]) << 8;
		id |= hex_to_byte(&str[2]);
		
		msg.id = id;
	}
	
	msg.flags.extended = extended;
	
	// read data if the message is no rtr-frame
	if (!msg.flags.rtr)
	{
		char *buf = str + dlc_pos + 1;
		uint8_t i;
		
		for (i=0; i < msg.length; i++)
		{
			msg.data[i] = hex_to_byte(buf);
			buf += 2;
		}
	}
	
	// finally try to send the message
	if (can_send_message( &msg ))
		return true;
	else
		return false;
}
示例#11
0
void parse_args(const unsigned int argc, char * const argv[])
{
	struct option long_options[] = {{"help", no_argument, 0, 'h'},
									{"version", no_argument, 0, 'v'},
									{"recursive", no_argument, 0, 'r'},
									{"path", required_argument, 0, 'p'},
									{"hex", required_argument, 0, 'n'},
									{"string", required_argument, 0, 's'},
									{"output", required_argument, 0, 'o'},
									{"threads", required_argument, 0, 't'},
									{"extension", required_argument, 0, 'e'},
									{0, 0, 0, 0}};

	int i = 0, c;

	while (1) {
		c = getopt_long(argc, argv, "hvrp:n:s:o:t:e:", long_options, &i);

		if (c == -1) break;

		switch (c) {
			case 'h':
				print_help();
			break;

			case 'v':
				print_version();
			break;

			case 'r':
				flags.recursive = 1;
			break;

			case 'p':
				input = optarg;
			break;

			case 't': {
				char *endptr = NULL;
				flags.threads = strtol(optarg, &endptr, 0);
				if (errno == ERANGE || *endptr != '\0') {
					fprintf(stderr, "Invalid or out of range number of threads.\n");
					exit(EXIT_FAILURE);
				}
			}
			break;

			case 'e':
				flags.extension = optarg;
			break;

			case 's':
				flags.chunkString = optarg;
			break;

			case 'o':
				flags.output = optarg;
			break;

			case 'n':
				flags.chunkString = hex_to_byte(optarg);
			break;

			case '?':
			default:
				print_help();
		}
	}

	if (!flags.chunkString) {
		fprintf(stderr, "The sequence to be identified has to be specified.\n\n");
		print_help();
	}
}
示例#12
0
文件: uart.c 项目: Phil-adelphia/ohc
uint16_t hex_to_uint8(uint8_t * buf, uint8_t offset)
{
	return hex_to_byte(buf[offset]) * 16 + hex_to_byte(buf[offset + 1]);
}
示例#13
0
文件: uart.c 项目: Phil-adelphia/ohc
// Process all bytes in the rxbuffer. This function should be called in the main loop.
// It can be interrupted by a UART RX interrupt, so additional bytes can be added into the ringbuffer while this function is running.
void process_rxbuf(void)
{
	while (rxbuf_count > 0)
	{
		char input;
		
		// get one char from the ringbuffer and reduce it's size without interruption through the UART ISR
		cli();
		input = rxbuf[rxbuf_startpos];
		rxbuf_startpos = (rxbuf_startpos + 1) % RXBUF_LENGTH;
		rxbuf_count--;
		sei();
		
		// process character	
		if (uart_timeout == 0)
		{
			bytes_to_read = bytes_pos = 0;
		}
		
		if (bytes_to_read > bytes_pos)
		{
			if (input == 13)
			{
				bytes_to_read = bytes_pos;
			}
			else if (((input >= 48) && (input <= 57)) || ((input >= 65) && (input <= 70)) || ((input >= 97) && (input <= 102)))
			{
				cmdbuf[bytes_pos] = input;
				bytes_pos++;
				UART_PUTF4("*** Received character %c (ASCII %u) = value 0x%x, %u bytes to go. ***\r\n", input, input, hex_to_byte(input), bytes_to_read - bytes_pos);
			}
			else
			{
				UART_PUTS("*** Illegal character. Use only 0..9, a..f, A..F. ***\r\n");
			}
			
			if (bytes_pos == bytes_to_read)
			{
				cmdbuf[bytes_pos] = '\0';
				process_cmd();
			}
		}	
		else if (input == 'h')
		{
			UART_PUTS("*** Help ***\r\n");
			UART_PUTS("h.........this help\r\n");
			UART_PUTS("rAA.......read EEPROM at hex address AA\r\n");
			UART_PUTS("wAAXX.....write EEPROM at hex address AA to hex value XX\r\n");
			UART_PUTS("x.........enable writing to EEPROM\r\n");
			UART_PUTS("z.........disable writing to EEPROM\r\n");
			UART_PUTS("sKKCCXX...Use AES key KK to send a packet with command ID CC and data XX (0..22 bytes).\r\n");
			UART_PUTS("          End data with ENTER. Packet number and CRC are automatically added.\r\n");
		}
		else if (input == 'x')
		{
			enable_write_eeprom = true;
			UART_PUTS("*** Writing to EEPROM is now ENABLED. ***\r\n");
		}
		else if (input == 'z')
		{
			enable_write_eeprom = false;
			UART_PUTS("*** Writing to EEPROM is now DISABLED. ***\r\n");
		}
		else if (input == 'r')
		{
			UART_PUTS("*** Read from EEPROM. Enter address (2 characters). ***\r\n");
			cmdbuf[0] = 'r';
			bytes_to_read = 3;
			bytes_pos = 1;
		}
		else if (input == 'w')
		{
			UART_PUTS("*** Write to EEPROM. Enter address and data (4 characters). ***\r\n");
			cmdbuf[0] = 'w';
			bytes_to_read = 5;
			bytes_pos = 1;
		}
		else if (input == 's')
		{
			UART_PUTS("*** Enter AES key nr, command ID and data in hex format to send, finish with ENTER. ***\r\n");
			cmdbuf[0] = 's';
			bytes_to_read = 49; // 's' + 2 characters for key nr + 2 characters for command ID + 2*22 characters for data
			bytes_pos = 1;
		}
		else
		{
			UART_PUTS("*** Character ignored. Press h for help. ***\r\n");
		}
		
		// enable user timeout if waiting for further input
		uart_timeout = bytes_to_read == bytes_pos ? 0 : 255;
	}
}
示例#14
0
// Process all bytes in the UART RX ringbuffer ("rxbuf"). This function should be called in the
// main loop. It can be interrupted by a UART RX interrupt, so additional bytes can be added
// into the ringbuffer while this function is running.
void process_rxbuf(void)
{
	// Only process characters if the cmdbuf is clear to be overwritten.
	// If not, wait for the main loop to clear it by processing the user "send" command.	
	if (send_data_avail)
	{
		return;
	}
	
	while (rxbuf_count > 0)
	{
		char input;
		
		// get one char from the ringbuffer and reduce its size without interruption through the UART ISR
		cli();
		input = rxbuf[rxbuf_startpos];
		rxbuf_startpos = (rxbuf_startpos + 1) % RXBUF_LENGTH;
		rxbuf_count--;
		sei();
		
		// process character	
		if (uart_timeout == 0)
		{
			bytes_to_read = bytes_pos = 0;
		}
		
		if (bytes_to_read > bytes_pos)
		{
			if (input == 13)
			{
				bytes_to_read = bytes_pos;
			}
			else if (((input >= 48) && (input <= 57)) || ((input >= 65) && (input <= 70)) || ((input >= 97) && (input <= 102)))
			{
				cmdbuf[bytes_pos] = input;
				bytes_pos++;
				UART_PUTF("*** 0x%x\r\n", hex_to_byte(input));
			}
			else
			{
				UART_PUTS("*** Illegal character. Use only 0..9, a..f, A..F. ***\r\n");
			}
			
			if (bytes_pos == bytes_to_read)
			{
				cmdbuf[bytes_pos] = '\0';
				//led_dbg(1);
				process_cmd();
			}
		}	
		else if (input == 'h')
		{
			UART_PUTS("*** Help ***\r\n");
			UART_PUTS("h..............this help\r\n");
			UART_PUTS("rAA............read EEPROM at hex address AA\r\n");
			UART_PUTS("wAAXX..........write EEPROM at hex address AA to hex value XX\r\n");
			UART_PUTS("x..............enable writing to EEPROM\r\n");
			UART_PUTS("z..............disable writing to EEPROM\r\n");
			UART_PUTS("sKKTT{D}.......Use AES key KK to send a packet with MessageType TT, followed\r\n");
			UART_PUTS("               by all necessary extension header fields and message data D.\r\n");
			UART_PUTS("               Fields are: ReceiverID (RRRR), MessageGroup (GG), MessageID (MM)\r\n");
			UART_PUTS("               AckSenderID (SSSS), AckPacketCounter (PPPPPP), Error (EE).\r\n");
			UART_PUTS("               MessageData (DD) can be 0..17 bytes with bits moved to the left.\r\n");
			UART_PUTS("               End data with ENTER. SenderID, PacketCounter and CRC are automatically added.\r\n");
			UART_PUTS("sKK00RRRRGGMMDD...........Get\r\n");
			UART_PUTS("sKK01RRRRGGMMDD...........Set\r\n");
			UART_PUTS("sKK02RRRRGGMMDD...........SetGet\r\n");
			UART_PUTS("sKK08GGMMDD...............Status\r\n");
			UART_PUTS("sKK09SSSSPPPPPPEE.........Ack\r\n");
			UART_PUTS("sKK0ASSSSPPPPPPEEGGMMDD...AckStatus\r\n");
			UART_PUTS("cKKTT{D}{CRC}..Same as s..., but a CRC32 checksum of the command has to be appended.\r\n");
			UART_PUTS("               If it doesn't match, the command is ignored.\r\n");
		}
		else if (input == 'x')
		{
			enable_write_eeprom = true;
			UART_PUTS("*** Writing to EEPROM is now ENABLED. ***\r\n");
		}
		else if (input == 'z')
		{
			enable_write_eeprom = false;
			UART_PUTS("*** Writing to EEPROM is now DISABLED. ***\r\n");
		}
		else if (input == 'r')
		{
			UART_PUTS("*** Read from EEPROM. Enter address (2 characters). ***\r\n");
			cmdbuf[0] = 'r';
			bytes_to_read = 3;
			bytes_pos = 1;
		}
		else if (input == 'w')
		{
			UART_PUTS("*** Write to EEPROM. Enter address and data (4 characters). ***\r\n");
			cmdbuf[0] = 'w';
			bytes_to_read = 5;
			bytes_pos = 1;
		}
		else if (input == 's')
		{
			UART_PUTS("*** Enter data, finish with ENTER. ***\r\n");
			cmdbuf[0] = 's';
			bytes_to_read = 54; // 2 characters for key nr + 2 characters for MessageType + 16 characters for hdr.ext. + 2*17 characters for data
			bytes_pos = 1;
		}
		else if (input == 'c')
		{
			UART_PUTS("*** Enter data, finish with ENTER. ***\r\n");
			cmdbuf[0] = 'c';
			bytes_to_read = 62; // 2 characters for key nr + 2 characters for MessageType + 16 characters for hdr.ext. + 2*17 characters for data + 8 characters for CRC
			bytes_pos = 1;
		}
		else
		{
			UART_PUTS("*** Character ignored. Press h for help. ***\r\n");
		}
		
		// enable user timeout if waiting for further input
		uart_timeout = bytes_to_read == bytes_pos ? 0 : 255;
	}
}
示例#15
0
文件: jamrouter.c 项目: EQ4/jamrouter
/*****************************************************************************
 * main()
 *
 * Parse command line, load patch, start midi_tx, midi_rx, and jack threads.
 *****************************************************************************/
int
main(int argc, char **argv)
{
	char            thread_name[16];
	char            opts[NUM_OPTS * 2 + 1];
	struct option   *op;
	char            *cp;
	char            *p;
	char            *term;
	char            *tokbuf;
	int             c;
	int             j                       = 0;
	int             ret                     = 0;
	int             saved_errno;
	int             argcount                = 0;
	char            **argvals               = argv;
	char            **envp                  = environ;
	char            *argvend                = (char *)argv;
	size_t          argsize;
	unsigned char   rx_channel;

	setlocale(LC_ALL, "C");

	jamrouter_instance = get_instance_num();
	fprintf(stderr, "Starting jamrouter instance %d.\n", jamrouter_instance);

	/* Start debug thread.  debug_class is not set until arguemnts are parsed,
	   so use fprintf() until then. */
	if ((ret = pthread_create(&debug_thread_p, NULL, &jamrouter_debug_thread, NULL)) != 0) {
		fprintf(stderr, "***** ERROR:  Unable to start debug thread.\n");
	}

	/* lock down memory (rt hates page faults) */
	if (mlockall(MCL_CURRENT | MCL_FUTURE) != 0) {
		saved_errno = errno;
		fprintf(stderr, "Unable to unlock memory:  errno=%d (%s)\n",
		        saved_errno, strerror(saved_errno));
	}

	/* init lash client */
#ifndef WITHOUT_LASH
	for (j = 0; j < argc; j++) {
		if ((strcmp(argv[j], "-L") == 0) || (strcmp(argv[j], "--disable-lash") == 0) ||
		    (strcmp(argv[j], "-h") == 0) || (strcmp(argv[j], "--help") == 0) ||
		    (strcmp(argv[j], "-l") == 0) || (strcmp(argv[j], "--list") == 0) ||
		    (strcmp(argv[j], "-v") == 0) || (strcmp(argv[j], "--version") == 0) ||
		    (strcmp(argv[j], "-D") == 0) || (strcmp(argv[j], "--session-dir") == 0) ||
		    (strcmp(argv[j], "-u") == 0) || (strcmp(argv[j], "--uuid") == 0)) {
			lash_disabled = 1;
			break;
		}
	}
	if (!lash_disabled) {
		snprintf(thread_name, 16, "jamrouter%c-lash", ('0' + jamrouter_instance));
		pthread_setname_np(pthread_self(), thread_name);
		if (lash_client_init(&argc, &argv) == 0) {
			lash_poll_event();
		}
		snprintf(thread_name, 16, "jamrouter%c-main", ('0' + jamrouter_instance));
		pthread_setname_np(pthread_self(), thread_name);
	}
#endif

	/* startup initializations */
	init_midi_event_queue();
	init_jack_audio_driver();
	select_midi_driver(NULL, DEFAULT_MIDI_DRIVER);

	/* save original command line for session handling */
	if (jamrouter_cmdline[0] == '\0') {
		jamrouter_cmdline[0] = '\0';
		for (j = 0; j < argc; j++) {
			strcat(&(jamrouter_cmdline[0]), argv[j]);
			strcat(&(jamrouter_cmdline[0]), " ");
		}
		jamrouter_cmdline[strlen(jamrouter_cmdline) - 1] = '\0';
		term = get_color_terminal();
		if (term == NULL) {
			strcpy(jamrouter_full_cmdline, jamrouter_cmdline);
		}
		else {
			snprintf(jamrouter_full_cmdline, 512, "%s -e \"%s \"",
			         term, jamrouter_cmdline);
		}
		argcount = argc;
		argvals  = argv;
	}
	/* command line args supplied by session manager */
	else {
		argcount = 0;
		cp = strdup(jamrouter_cmdline);
		p = cp;
		while ((p = index(p, ' ')) != NULL) {
			p++;
			argcount++;
		}
		if ((argvals = malloc(((size_t)(argcount) + 1UL) *
		                      (size_t)sizeof(char *))) == NULL) {
			fprintf(stderr, "Out of Memory!\n");
			return -1;
		}
		if ((tokbuf = alloca(strlen(jamrouter_cmdline) * 4)) == NULL) {
			fprintf(stderr, "Out of Memory!\n");
			return -1;
		}
		while ((p = strtok_r(cp, " ", &tokbuf)) != NULL) {
			cp = NULL;
			argvals[j++] = p;
		}
		argvals[argcount] = NULL;
	}

	/* build the short option string */
	cp = opts;
	for (op = long_opts; op < &long_opts[NUM_OPTS]; op++) {
		*cp++ = (char) op->val;
		if (op->has_arg) {
			*cp++ = ':';
		}
	}

	/* handle options */
	for (;;) {
		c = getopt_long(argcount, argvals, opts, long_opts, NULL);
		if (c == -1) {
			break;
		}

		switch (c) {
		case 'M':   /* MIDI driver */
			select_midi_driver(optarg, -1);
			break;
		case 'D':   /* MIDI Rx/Tx port/device */
			midi_rx_port_name = strdup(optarg);
			midi_tx_port_name = strdup(optarg);
			break;
		case 'r':   /* MIDI Rx port/device */
			midi_rx_port_name = strdup(optarg);
			break;
		case 't':   /* MIDI Tx port/device */
			midi_tx_port_name = strdup(optarg);
			break;
		case 'x':   /* MIDI Rx latency periods */
			rx_latency_periods = atoi(optarg);
			break;
		case 'X':   /* MIDI Tx latency periods */
			tx_latency_periods = atoi(optarg);
			break;
		case 'g':   /* Tx byte guard time in usec */
			byte_guard_time_usec = atoi(optarg);
			break;
		case 'G':   /* Tx event guard time in usec */
			event_guard_time_usec = atoi(optarg);
			break;
		case 'i':   /* JACK MIDI input port */
			jack_input_port_name = strdup(optarg);
			break;
		case 'o':   /* JACK MIDI output port */
			jack_output_port_name = strdup(optarg);
			break;
		case 'j':   /* Jitter correction mode */
			jitter_correct_mode = 1;
			break;
		case 'z':   /* JACK wake phase within MIDI Rx/Tx period */
			setting_midi_phase_lock = (timecalc_t)(atof(optarg));
			if (setting_midi_phase_lock < (timecalc_t)(0.0625)) {
				setting_midi_phase_lock = (timecalc_t)(0.0625);
			}
			else if (setting_midi_phase_lock > (timecalc_t)(0.9375)) {
				setting_midi_phase_lock = (timecalc_t)(0.9375);
			}
			break;
#ifndef WITHOUT_JACK_DLL
		case '4':   /* JACK DLL timing level 4 */
			jack_dll_level = 4;
			break;
		case '3':   /* JACK DLL timing level 3 */
			jack_dll_level = 3;
			break;
		case '2':   /* JACK DLL timing level 2 */
			jack_dll_level = 2;
			break;
		case '1':   /* JACK DLL timing level 1 */
			jack_dll_level = 1;
			break;
#endif
		case 'k':   /* key to controller mapping */
			if (optarg != NULL) {
				if ((tokbuf = alloca(strlen((const char *)optarg) * 4)) == NULL) {
					jamrouter_shutdown("Out of memory!\n");
				}
				if ((p = strtok_r(optarg, ",", &tokbuf)) != NULL) {
					rx_channel = (atoi(p) - 1) & 0x0F;
					if ((p = strtok_r(NULL, ",", &tokbuf)) != NULL) {
						keymap_tx_channel[rx_channel] = (atoi(p) - 1) & 0x0F;
						if ((p = strtok_r(NULL, ",", &tokbuf)) != NULL) {
							keymap_tx_controller[rx_channel] = atoi(p) & 0x7F;
						}
					}
					JAMROUTER_DEBUG(DEBUG_CLASS_INIT, "Key --> Controller Map:  "
					                "rx_channel=%0d  tx_channel=%d  tx_cc=%d\n",
					                rx_channel + 1,
					                keymap_tx_channel[rx_channel] + 1,
					                keymap_tx_controller[rx_channel]);
				}
			}
			break;
		case 'p':   /* key to pitchbend translation */
			if (optarg != NULL) {
				if ((tokbuf = alloca(strlen((const char *)optarg) * 4)) == NULL) {
					jamrouter_shutdown("Out of memory!\n");
				}
				if ((p = strtok_r(optarg, ",", &tokbuf)) != NULL) {
					rx_channel = (atoi(p) - 1) & 0x0F;
					if ((p = strtok_r(NULL, ",", &tokbuf)) != NULL) {
						pitchmap_tx_channel[rx_channel] = (atoi(p) - 1) & 0x0F;
						if ((p = strtok_r(NULL, ",", &tokbuf)) != NULL) {
							pitchmap_center_note[rx_channel] = atoi(p) & 0x7F;
							if ((p = strtok_r(NULL, ",", &tokbuf)) != NULL) {
								pitchmap_bend_range[rx_channel] = atoi(p) & 0x7F;
							}
						}
					}
					JAMROUTER_DEBUG(DEBUG_CLASS_INIT,
					                "Key --> Pitchbend Map:  "
					                "rx_chan=%0d  tx_chan=%d  center=%d  range=%d\n",
					                rx_channel + 1, pitchmap_tx_channel[rx_channel] + 1,
					                pitchmap_center_note[rx_channel],
					                pitchmap_bend_range[rx_channel]);
				}
			}
			break;
		case 'q':   /* pitchbend to controller translation */
			if (optarg != NULL) {
				if ((tokbuf = alloca(strlen((const char *)optarg) * 4)) == NULL) {
					jamrouter_shutdown("Out of memory!\n");
				}
				if ((p = strtok_r(optarg, ",", &tokbuf)) != NULL) {
					rx_channel = (atoi(p) - 1) & 0x0F;
					if ((p = strtok_r(NULL, ",", &tokbuf)) != NULL) {
						pitchcontrol_tx_channel[rx_channel] = (atoi(p) - 1) & 0x0F;
						if ((p = strtok_r(NULL, ",", &tokbuf)) != NULL) {
							pitchcontrol_controller[rx_channel] = atoi(p) & 0x7F;
						}
					}
					JAMROUTER_DEBUG(DEBUG_CLASS_INIT,
					                "Pitchbend --> Controller Map:  "
					                "rx_chan=%0d  tx_chan=%d  controller=%d\n",
					                rx_channel + 1, pitchcontrol_tx_channel[rx_channel] + 1,
					                pitchcontrol_controller[rx_channel]);
				}
			}
			break;
#ifndef WITHOUT_JUNO
		case 'J':   /* Juno-106 sysex controller translation */
			translate_juno_sysex = 1;
			break;
		case 's':   /* echo sysex translations back to originator */
			echosysex = 1;
			break;
#endif
		case 'e':   /* echo pitchbend and controller translations back to originator */
			echotrans = 1;
			break;
		case 'T':   /* alternate sysex terminator byte */
			sysex_terminator = hex_to_byte(optarg);
			break;
		case 'U':   /* alternate sysex terminator byte */
			sysex_extra_terminator = hex_to_byte(optarg);
			break;
		case 'A':   /* Active-Sensing mode */
			if (strcmp(optarg, "on") == 0) {
				active_sensing_mode = ACTIVE_SENSING_MODE_ON;
			}
			else if (strcmp(optarg, "thru") == 0) {
				active_sensing_mode = ACTIVE_SENSING_MODE_THRU;
			}
			else if (strcmp(optarg, "drop") == 0) {
				active_sensing_mode = ACTIVE_SENSING_MODE_DROP;
			}
			break;
		case 'R':   /* Omit running status byte on MIDI Tx */
			use_running_status = 1;
			break;
		case 'n':   /* Note-On Velocity */
			note_on_velocity = hex_to_byte(optarg);
			break;
		case 'N':   /* Note-Off Velocity */
			note_off_velocity = hex_to_byte(optarg);
			break;
		case 'f':   /* Send multiple Note-Off messages as All-Notes-Off */
			tx_prefer_all_notes_off = 1;
			break;
		case 'F':   /* Tx send real Note-Off instead of Velocity-0-Note-On */
			tx_prefer_real_note_off = 1;
			break;
		case '0':   /* Rx queue real Note-Off instead of Velocity-0-Note-On */
			rx_queue_real_note_off = 1;
			break;
		case 'y':   /* MIDI Rx thread priority */
			if ((midi_rx_thread_priority = atoi(optarg)) <= 0) {
				midi_rx_thread_priority = MIDI_RX_THREAD_PRIORITY;
			}
			break;
		case 'Y':   /* MIDI Tx thread priority */
			if ((midi_tx_thread_priority = atoi(optarg)) <= 0) {
				midi_tx_thread_priority = MIDI_TX_THREAD_PRIORITY;
			}
			break;
		case 'd':   /* debug */
			debug = 1;
			for (j = 0; debug_class_list[j].name != NULL; j++) {
				if (strcmp(debug_class_list[j].name, optarg) == 0) {
					debug_class |= debug_class_list[j].id;
				}
			}
			break;
		case 'v':   /* version */
			printf("jamrouter-%s\n", PACKAGE_VERSION);
			return 0;
		case 'L':   /* disable lash */
			lash_disabled = 1;
			break;
		case 'l':   /* list midi devices */
			scan_midi();
			return 0;
		case 'u':   /* jack session uuid */
			jack_session_uuid = strdup(optarg);
			break;
		case '?':
		case 'h':   /* help */
		default:
			showusage(argv[0]);
			return -1;
		}
	}

	/* Rewrite process title */
	argcount = argc;
	argvals  = argv;
	for (j = 0; j <= argcount; j++) {
		if ((j == 0) || ((argvend + 1) == argvals[j])) {
			argvend = argvals[j] + strlen(argvals[j]);
		}
		else {
			continue;
		}
	}

	/* steal space from first environment entry */
	if (envp[0] != NULL) {
		argvend = envp[0] + strlen (envp[0]);
	}

	/* calculate size we have for process title */
	argsize = (size_t)((char *)argvend - (char *)*argvals - 1);
	memset (*argvals, 0, argsize);

	/* rewrite process title */
	argc = 0;
	snprintf((char *)*argvals, argsize, "jamrouter%d", jamrouter_instance);

	/* signal handlers for clean shutdown */
	init_signal_handlers();

	/* init MIDI system based on selected driver */
	JAMROUTER_DEBUG(DEBUG_CLASS_INIT, "Initializing MIDI:  driver=%s.\n",
	                midi_driver_names[midi_driver]);
	init_sync_info(0, 0);
	init_midi();

	/* initialize JACK audio system based on selected driver */
	snprintf(thread_name, 16, "jamrouter%c-clnt", ('0' + jamrouter_instance));
	pthread_setname_np(pthread_self(), thread_name);
	init_jack_audio();
	while (sample_rate == 0) {
		JAMROUTER_DEBUG(DEBUG_CLASS_INIT,
		                "JACK did not set sample rate.  Re-initializing...\n");
		init_jack_audio();
		usleep(125000);
	}

	/* start the JACK audio system */
	start_jack_audio();

	/* wait for JACK audio to start before starting midi. */
	wait_jack_audio_start();

	snprintf(thread_name, 16, "jamrouter%c-main", ('0' + jamrouter_instance));
	pthread_setname_np(pthread_self(), thread_name);

	/* start MIDI Rx/Tx threads. */
	start_midi_rx();
	wait_midi_rx_start();
	start_midi_tx();
	wait_midi_tx_start();

	/* debug thread not needed once watchdog is running */
	debug_done = 1;
	pthread_join(debug_thread_p, NULL);

	/* Jamrouter watchdog handles restarting threads on config changes,
	   runs driver supplied watchdog loop iterations, and handles debug
	   output. */
	jamrouter_watchdog();
	stop_midi_tx();
	stop_midi_rx();
	stop_jack_audio();
	output_pending_debug();

	/* Wait for threads created directly by JAMROUTER to terminate. */
	if (midi_rx_thread_p != 0) {
		pthread_join(midi_rx_thread_p,  NULL);
	}
	if (midi_tx_thread_p != 0) {
		pthread_join(midi_tx_thread_p,  NULL);
	}
	output_pending_debug();

	return 0;
}