Ejemplo n.º 1
0
Archivo: egchan.c Proyecto: nclack/chan
void* producer(void* arg)
{ Chan* writer;
  int*  buf;
  int id;
  
  id = GETID(arg);
  printf("Producer %d starting"ENDL,id);
  writer = Chan_Open(GETCHAN(arg),CHAN_WRITE);
  buf = (int*)Chan_Token_Buffer_Alloc(writer);
  do
  { buf[0] = InterlockedIncrement(&item);
    usleep(1);
    usleep(1);
    printf("Producer: item %4d [   + ] %d"ENDL, buf[0], id);
#pragma omp critical
    {
      mymax(&pmax,*buf);
    }
    Chan_Next(writer,(void**)&buf,sizeof(int));
  } while(!stop);
  Chan_Token_Buffer_Free(buf);
  Chan_Close(writer);
  printf("Producer %d exiting"ENDL,id);
  return NULL;
}
Ejemplo n.º 2
0
Archivo: egchan.c Proyecto: nclack/chan
void* consumer(void* arg)
{ Chan* reader;
  int*  buf,id;
  
  id = GETID(arg);
  printf("Consumer %d starting\n",id);
  reader = Chan_Open(GETCHAN(arg),CHAN_READ);
  buf = (int*)Chan_Token_Buffer_Alloc(reader);
  while(CHAN_SUCCESS(Chan_Next(reader,(void**)&buf,sizeof(int))))
  { //i=InterlockedDecrement(&item);
    printf("Consumer: item %4d [ -   ] %d"ENDL, buf[0], id);
#pragma omp critical
    {
      mymax(&cmax,buf[0]);
    }
  } 
  Chan_Token_Buffer_Free(buf);
  Chan_Close(reader);
  printf("Consumer %d exiting"ENDL,id);
  return NULL;
}
int qcs__parse_qchat_msg(
	const char * pmsg, ssize_t pmsg_len,
	qcs_msg * msg )
{
	char ch;

	assert( pmsg && pmsg_len && msg );

	qcs__cleanupmsg(msg);

	GETCHAR(ch);
	switch(ch) {
	case '0':
		msg->msg = QCS_MSG_REFRESH_REQUEST;
		GETSTR(msg->src);
		break;
	case '1':
		msg->msg = QCS_MSG_REFRESH_ACK;
		GETSTR(msg->dst);
		GETSTR(msg->src);
		GETMODE(msg->umode);
		if( pmsg_len ) {
			/* check for `ACTIVE' bit in qc16 messages */
			GETACTIVE(msg->uactive);
		} else {
			/* uactive=TRUE per default */
			msg->uactive = 1;
		}
		break;
	case '2':
		msg->msg = QCS_MSG_CHANNEL_BROADCAST;
		GETCHAN(msg->chan);
		GETSTR(msg->src);
		GETSTR(msg->text);
		break;
	case '4':
		msg->msg = QCS_MSG_CHANNEL_JOIN;
		GETSTR(msg->src);
		GETCHAN(msg->chan);
		GETMODE(msg->umode);
		/*dummy byte skipped*/
		break;
	case '5':
		msg->msg = QCS_MSG_CHANNEL_LEAVE;
		GETSTR(msg->src);
		GETCHAN(msg->chan);
		/*dummy*/
		break;
	case 'A':
		msg->msg = QCS_MSG_CHANNEL_ME;
		GETCHAN(msg->chan);
		GETSTR(msg->src);
		GETSTR(msg->text);
		break;
	case '7':
		msg->msg = QCS_MSG_MESSAGE_ACK;
		GETMODE(msg->umode);
		GETSTR(msg->dst);
		GETSTR(msg->src);
		GETCHAR(ch);	/* dummy */
		GETSTR(msg->text);
		break;
	case 'E':
		msg->msg = QCS_MSG_MESSAGE_MASS;
		GETSTR(msg->src);
		GETSTR(msg->dst);
		GETSTR(msg->text);
		break;
	case '6':
		msg->msg = QCS_MSG_MESSAGE_SEND;
		GETSTR(msg->src);
		GETSTR(msg->dst);
		GETSTR(msg->text);
		break;
	case '3':
		msg->msg = QCS_MSG_RENAME;
		GETSTR(msg->src);
		GETSTR(msg->text);
		/*dummy*/
		break;
	case 'D':
		msg->msg = QCS_MSG_MODE_CHANGE;
		GETSTR(msg->src);
		GETMODE(msg->umode);
		/* dummy byte passed by */
		break;
	case 'M':
		msg->msg = QCS_MSG_ACTIVE_CHANGE;
		GETSTR(msg->src);
		GETACTIVE(msg->uactive);
		break;
	case 'C':
		msg->msg = QCS_MSG_TOPIC_REPLY;
		GETSTR(msg->dst);
		GETSTR(msg->text);
		
		/* add "Main" as msg->chan */
		msg->chan = malloc(5);
		if(!msg->chan) {
			qcs__cleanupmsg(msg);
			errno = ENOMEM;
			return 0;
		}
		memcpy(msg->chan, "Main", 5);
		break;
	case 'B':
		msg->msg = QCS_MSG_TOPIC_CHANGE;
		GETSTR(msg->text);
		
		/* fill in "Main": this is unsupported in qc,
		 * thus we need to fill it in */
		msg->chan = malloc(5);
		if(!msg->chan) {
			qcs__cleanupmsg(msg);
			errno = ENOMEM;
			return 0;
		}
		memcpy(msg->chan, "Main", 5);
		break;
	case 'G':
		msg->msg = QCS_MSG_INFO_REPLY;
		GETSTR(msg->dst);
		GETSTR(msg->src);
		GETSTR(msg->text);
		/* skip 3 strings - not used */
		GETSTR(msg->chan);free(msg->chan);
		GETSTR(msg->chan);free(msg->chan);
		GETSTR(msg->chan);free(msg->chan);
		GETSTR(msg->chan);
		GETSTR(msg->supp);
		break;
	case 'F':
		msg->msg = QCS_MSG_INFO_REQUEST;
		GETSTR(msg->dst);
		GETSTR(msg->src);
		break;
	case 'K':
		msg->msg = QCS_MSG_CHANMEMBER_REPLY;
		GETSTR(msg->dst);
		GETSTR(msg->chan);
		GETSTR(msg->src);
		break;
	case 'L':
		msg->msg = QCS_MSG_CHANMEMBER_REQUEST;
		GETSTR(msg->src);
		break;
	case 'O':
		msg->msg = QCS_MSG_CHANLIST_REPLY;
		GETSTR(msg->dst);
		GETSTR(msg->chan);
		break;
	case 'N':
		msg->msg = QCS_MSG_CHANLIST_REQUEST;
		GETSTR(msg->src);
		break;
	case 'H':
		GETCHAR(ch);
		switch(ch) {
		case '1': msg->msg = QCS_MSG_BEEP_ACK;	break;
		case '0': msg->msg = QCS_MSG_BEEP_SEND;	break;
		default: errno = ENOMSG;
			 return 0;
		}
		GETSTR(msg->dst);
		GETSTR(msg->src);
		/* dummy byte when 'H1' */
		break;
	case 'J':
		GETCHAR(ch);
		switch(ch) {
		case '0':msg->msg = QCS_MSG_PRIVATE_OPEN;	break;
		case '1':msg->msg = QCS_MSG_PRIVATE_CLOSE;	break;
		case '2':msg->msg = QCS_MSG_PRIVATE_TEXT;	break;
		case '3':msg->msg = QCS_MSG_PRIVATE_ME;		break;
		default: errno = ENOMSG;
			 return 0;
		}
		GETSTR(msg->src);
		GETSTR(msg->dst);
		if(ch=='2'||ch=='3') {
			GETSTR(msg->text);
		}
		break;
	default:
		errno = ENOMSG;
		return 0;
	}
	return 1;
}
int qcs__parse_vypress_msg(
	const char * src, int src_len,
	qcs_msg * msg )
{
	int parsed_ok;
	char ch;

	qcs__cleanupmsg(msg);

	/* check for signature consistency and duplicates */
	if( src_len < (QCS_SIGNATURE_LENGTH + 2) ) {
		/* not a vypress extension packet */
		errno = ENOMSG;
		return 0;
	}
	if( qcs__known_dup_entry(src+1)) {
		/* duplicate encountered: ignore */
		return 1;
	} else {
		/* not seen before: register */
		qcs__insert_dup_entry(src+1);
	}

	/* skip signature: already parsed */
	src += QCS_SIGNATURE_LENGTH + 1;
	src_len -= QCS_SIGNATURE_LENGTH + 1;

	/* parse message contents */
	switch( *(src++) )
	{
	case 'B':
		msg->msg = QCS_MSG_TOPIC_CHANGE;
		GETCHAN(msg->chan);
		GETSTR(msg->text);
		break;
	case 'C':
		msg->msg = QCS_MSG_TOPIC_REPLY;
		GETSTR(msg->dst);
		GETCHAN(msg->chan);
		GETSTR(msg->text);
		break;
	case 'G':
		msg->msg = QCS_MSG_INFO_REPLY;
		GETSTR(msg->dst);
		GETSTR(msg->src);
		GETSTR(msg->text);
		GETSTR(msg->chan);free(msg->chan);
		GETSTR(msg->chan);free(msg->chan);
		GETSTR(msg->chan);
		GETSTR(msg->supp);
		break;
	default:
		/* where it doesn't diff: parse with qc parser */
		parsed_ok = qcs__parse_qchat_msg(src-1, src_len, msg);

		/* flush msg id cache if the user has left the net
		 * (seems like, vypress chat v1.0 repeats the same
		 * msg id, if restarted: unseeded rand() ??)
		 */
		if(parsed_ok && msg->msg==QCS_MSG_CHANNEL_LEAVE
			&& !strcasecmp(msg->chan, "main"))
		{
			qcs__cleanup_dup();
		}

		return parsed_ok;
	}

	return 1;
}