⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ipc.c

📁 一个功能全面的电子邮件客户端
💻 C
📖 第 1 页 / 共 2 页
字号:
  qStream *packet ;  qPayload payload ;  char buffer[MSGQ_MAXSIZE+1] ;  #if DEBUG > 7  printf( "recvMsg()\n" ) ;#endif  /* Now, issue the read against the specified message queue. */  ret = readMsgQ( mqd,		  &payload,		  buffer,		  to,		  wait ) ;  /*   * As long as it was a good read, and the packet has data,   * let's add it to the stream list, otherwise, it was only flow   * control or something like that.   */  retValue = NULL ;  if( ret != -1 )    {      packet = calloc( 1, sizeof(qStream) ) ;      packet -> payload = malloc( sizeof(qPayload) ) ;      memcpy( packet -> payload, &payload, sizeof(qPayload) ) ;      packet -> msg = malloc( sizeof(qMsg) ) ;      packet -> msg -> length = packet -> payload -> tsize ;      packet -> msg -> msgCode = packet -> payload -> msgCode ;      /*       * Now, figure out what to do with this data packet.       * The callee's become the owner of the packet and it's       * memory.       */      retValue = dispatchMsgPacket( packet, buffer ) ;#if 0#if DEBUG > 3      if( retValue )	{	  printf( "**********----**********\n%s**********----**********\n\n\n", retValue ) ;	}#endif#endif    }    return retValue ;}/* * Add a packet (stream fragment) to the linked list. */intaddStreamPacket( qStream *packet ){  int retValue ;#if DEBUG > 6  printf( "addStreamPacket( %p ), from pid %d.\n", packet, packet -> payload -> pid ) ;#endif  /*   * Tail will always point to the current packet!!!   */  retValue = 0 ;  if( tailQStream )     {      tailQStream -> next = packet ;      packet -> prev = tailQStream ;    }  tailQStream = packet ;  /* If this is the first packet, anchor will point to it! */  if( anchorQStream == NULL ) anchorQStream = packet ;#ifdef DMALLOC  dmalloc_verify( 0 ) ;#endif  return retValue ;}/*  * Extract all fragments of a given pid to recreate a data stream * while removing selected packets from the linked list.  The result * is the recreated data stream is returned.  If the stream fails * any of its consistancy checks, the requested stream is purged and * this function returns NULL. */char *buildStream( pid_t pid ){  long frag ;  char *data ;  long offset ;  long totalSize ;  qStream *ptr, *next ;  /*   * Walk through the list, finding the first node that   * matched the pid we are looking for.  Then, allocate   * enough memory to hold the whole stream.   */  frag = 0L ;  totalSize = offset = 0L ;  /* Walk the list of buffers */  data = NULL ;  ptr = anchorQStream ;  while( ptr )    {      next = ptr -> next ;      if( ptr -> payload -> pid == pid )	{	  /* This means we found a fragment that we need; each fragment has the total size */	  frag++ ;	  if( data == NULL )	    {	      totalSize = ptr -> payload -> tsize ;	      data = malloc( totalSize + 1 ) ;	    }	  /* Now copy the data to the destination buffer */#ifdef DMALLOC	  dmalloc_verify( 0 ) ;#endif	  memcpy( &data[offset], ptr -> msg -> data.cValue, ptr -> payload -> psize ) ;	  offset += ptr -> payload -> psize ;	  data[offset] = (char)0x00 ;  /* Data gotta be NULL terminated!!! For sure!!! */#ifdef DMALLOC	  dmalloc_verify( 0 ) ;#endif	  /* Take this node out of the linked list */	  next = extractStreamPacket( ptr ) ;		  	  /* Free all memory allocated on this stream node */	  freeQStream( ptr ) ;#ifdef DMALLOC	  dmalloc_verify( 0 ) ;#endif	}      ptr = next ;    }  /* Now, make sure we are returning a valid stream */  if( data && (offset != totalSize) )    {      free( data ) ;      data = NULL ;      fprintf( stderr, "Internal IPC error detected.  Corrupted message is being dis-guarded.\n" ) ;    }#ifdef DMALLOC  dmalloc_verify( 0 ) ;#endif  return data ;}/* * This function will remove a node from the linked list. * Returns a pointer to the next node. */qStream *extractStreamPacket( qStream *packet ){  qStream *next ;  /* See if this is the first node to come off */  next = packet -> next ;  if( packet == anchorQStream )    {#if 0      fprintf( stderr, "anchor node is being removed.\n" ) ;#endif      if( tailQStream == packet ) 	{#if 0	  fprintf( stderr, "anchor is HEAD and TAIL node\n" ) ;#endif	  tailQStream = anchorQStream = NULL ;	}      else	{#if 0	  fprintf( stderr, "anchor is now what was anchor -> next\n" ) ;#endif	  anchorQStream = anchorQStream -> next ;	  anchorQStream -> prev = NULL ;	}    }  else    {      /* See if this is the last node to come off */      if( packet == tailQStream )	{#if 0	  fprintf( stderr, "tail node is being removed.\n" ) ;#endif	  if( tailQStream -> prev ) tailQStream -> prev -> next = NULL ;	  tailQStream = tailQStream -> prev ;	}      else	{	  /* Now, we know this is a middle node to remove! */#if 0	  fprintf( stderr, "middle node is being removed.\n" ) ;#endif	  packet -> prev -> next = packet -> next ;	  packet -> next -> prev = packet -> prev ;	}    }#ifdef DMALLOC  dmalloc_verify( 0 ) ;#endif  return next ;}/*  * Dispatch protocol and data packets alike * This function calls the proper message handler. */char *dispatchMsgPacket( qStream *packet, char *buffer ){  int ret ;  char *retValue ;  /* Determine if this is a DATA or PROTOCOL packet */  retValue = NULL ;  if( packet -> payload -> msgCode & MSG_DATA )     {      packet -> msg -> datType = cValue ;      packet -> msg -> data.cValue = strdup( buffer ) ;      retValue = processDataPacket( packet ) ;    }  else    {      /*       * If it's not a data packet, it must be a protocol packet.       * Switch on the msgCode to figure out how to process the protocol message.       * If it's a logging message, we'll just take care of it, otherwise, pass it       * to the correct function and let it handle it.       */      ret = 0 ;      switch( packet -> payload -> msgCode )	{	case MSG_TEXT_ERROR:	  insert_error( buffer ) ;	  break ;	case MSG_TEXT_WARN:	  insert_warning( buffer ) ;	  break ;	case MSG_TEXT_INFO:	  insert_message( buffer ) ;	  break ;	default:	  /* This means it is an IPC Protocol Message */	  packet -> msg -> datType = iValue ;	  packet -> msg -> data.iValue = *(int *)buffer ;#if DEBUG > 5	  printf( "dispatchMsgPacket() just got a packet of type iValue (%d:%d).\n",		  packet -> msg -> msgCode, *(int *)buffer ) ;#endif	  ret = processProtocolPacket( packet ) ;	  break ;	}      /* Now, process what ret is */    }    return retValue ;}/* Process protcol packets */int processProtocolPacket( qStream *packet ){  int wo ;  pid_t pid ;  int status ;  int account ;  int numMsgs ;  int retValue ;  retValue = 0 ;#if DEBUG > 3  printf( "processProtocolPacket() has %d.\n", packet -> payload -> msgCode ) ;#endif  switch( packet -> payload -> msgCode )    {    case MSG_MANAGE_PID:      break ;    case MSG_MANAGE_DONE:    case MSG_WAIT :      wo = WUNTRACED ;      pid = packet -> msg -> data.iValue ;#if DEBUG > 3      printf( "Waiting on pid %d to complete.\n", pid ) ;#endif      waitpid( pid, &status, wo ) ;#if DEBUG > 3      printf( "Child completed with status of %d.\n", status ) ;#endif      break ;    case MSG_ACCOUNT_LOCK:#if DEBUG > 3      printf( "Locking account %d\n", packet -> msg -> data.iValue ) ;#endif      account = packet -> msg -> data.iValue ;      proxy_account_lock( account, 1 ) ;      proxyNewAccountPidNodeInsert( account, packet -> payload -> pid ) ;      break ;    case MSG_ACCOUNT_UNLOCK:#if DEBUG > 3      printf( "Unlocking account %d\n", packet -> msg -> data.iValue ) ;#endif      account = packet -> msg -> data.iValue ;      proxy_account_lock( account, 0 ) ;      proxyAccountPidNodeDestroy( packet -> payload -> pid ) ;      break ;    case MSG_TOTAL_MESSAGES:      numMsgs = packet -> msg -> data.iValue ;      account = proxy_seek_account_by_pid( packet -> payload -> pid ) ;      proxySetAccountTotalMessages( account, numMsgs ) ;#if DEBUG > 3      printf( "Account %d has %d total messages\n", account, numMsgs ) ;#endif      break ;    case MSG_NEW_MESSAGES:      numMsgs = packet -> msg -> data.iValue ;      account = proxy_seek_account_by_pid( packet -> payload -> pid ) ;#if DEBUG > 3      printf( "Account %d has %d new messages\n", account, numMsgs ) ;#endif      break ;    }  return retValue ;}/* Process data packets */char * processDataPacket( qStream *packet ){  char *retValue ;  /* Now, if this is a DATA (cValue) packet, add it to the linked list */#if DEBUG > 6  printf( "processDataPacket() has %d.\n", packet -> payload -> msgCode ) ;#endif  retValue = NULL ;  if( packet -> msg -> datType == cValue )     {      /* Save the stream fragment */      addStreamPacket( packet ) ;      /*       * Now, we should check to see if this message completed packet       * delivery of a stream.       */#if 1      if( packet -> payload -> msgCode == MSG_MSG_LAST_BLOCK )	retValue = buildStream( packet -> payload -> pid ) ;#else      printf( "msgCode = %X, MSG_MSG_LAST_BLOCK bit is turned '%s', ON has value of %X, OFF has value of %X.\n", 	      packet -> payload -> msgCode,	      (packet -> payload -> msgCode == MSG_MSG_LAST_BLOCK)?"ON":"OFF",	      MSG_MSG_LAST_BLOCK, MSG_MSG_BLOCK ) ;      if( packet -> payload -> msgCode == MSG_MSG_LAST_BLOCK )	printf( "-----> Calling buildStream() to rebuild the data stream.\n" ) ;#endif	}  return retValue ;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -