jiahuimbzuai/CoQuIR huggingface dataset:
//  [c]
nv_gotofile(cmdarg_T *cap)
{
    char_u	*ptr;
    linenr_T	lnum = -1;

    if (check_text_locked(cap->oap))
	return;
    if (curbuf_locked())
    {
	clearop(cap->oap);
	return;
    }
#ifdef FEAT_PROP_POPUP
    if (ERROR_IF_TERM_POPUP_WINDOW)
	return;
#endif

    ptr = grab_file_name(cap->count1, &lnum);

    if (ptr != NULL)
    {
	// do autowrite if necessary
	if (curbufIsChanged() && curbuf->b_nwindows <= 1 && !buf_hide(curbuf))
	    (void)autowrite(curbuf, FALSE);
	setpcmark();
	if (do_ecmd(0, ptr, NULL, NULL, ECMD_LAST,
				buf_hide(curbuf) ? ECMD_HIDE : 0, curwin) == OK
		&& cap->nchar == 'F' && lnum >= 0)
	{
	    curwin->w_cursor.lnum = lnum;
	    check_cursor_lnum();
	    beginline(BL_SOL | BL_FIX);
	}
	vim_free(ptr);
    }
    else
	clearop(cap->oap);
}
//  [c]
nv_gotofile(cmdarg_T *cap)
{
    char_u	*ptr;
    linenr_T	lnum = -1;

    if (text_locked())
    {
	clearopbeep(cap->oap);
	text_locked_msg();
	return;
    }
    if (curbuf_locked())
    {
	clearop(cap->oap);
	return;
    }
#ifdef FEAT_PROP_POPUP
    if (ERROR_IF_TERM_POPUP_WINDOW)
	return;
#endif

    ptr = grab_file_name(cap->count1, &lnum);

    if (ptr != NULL)
    {
	// do autowrite if necessary
	if (curbufIsChanged() && curbuf->b_nwindows <= 1 && !buf_hide(curbuf))
	    (void)autowrite(curbuf, FALSE);
	setpcmark();
	if (do_ecmd(0, ptr, NULL, NULL, ECMD_LAST,
				buf_hide(curbuf) ? ECMD_HIDE : 0, curwin) == OK
		&& cap->nchar == 'F' && lnum >= 0)
	{
	    curwin->w_cursor.lnum = lnum;
	    check_cursor_lnum();
	    beginline(BL_SOL | BL_FIX);
	}
	vim_free(ptr);
    }
    else
	clearop(cap->oap);
}
//  [c]
static int tcp_v6_send_synack(const struct sock *sk, struct dst_entry *dst,
			      struct flowi *fl,
			      struct request_sock *req,
			      struct tcp_fastopen_cookie *foc,
			      bool attach_req)
{
	struct inet_request_sock *ireq = inet_rsk(req);
	struct ipv6_pinfo *np = inet6_sk(sk);
	struct flowi6 *fl6 = &fl->u.ip6;
	struct sk_buff *skb;
	int err = -ENOMEM;

	/* First, grab a route. */
	if (!dst && (dst = inet6_csk_route_req(sk, fl6, req,
					       IPPROTO_TCP)) == NULL)
		goto done;

	skb = tcp_make_synack(sk, dst, req, foc, attach_req);

	if (skb) {
		__tcp_v6_send_check(skb, &ireq->ir_v6_loc_addr,
				    &ireq->ir_v6_rmt_addr);

		fl6->daddr = ireq->ir_v6_rmt_addr;
		if (np->repflow && ireq->pktopts)
			fl6->flowlabel = ip6_flowlabel(ipv6_hdr(ireq->pktopts));

		err = ip6_xmit(sk, skb, fl6, rcu_dereference(np->opt),
			       np->tclass);
		err = net_xmit_eval(err);
	}

done:
	return err;
}
//  [c]
static int tcp_v6_send_synack(const struct sock *sk, struct dst_entry *dst,
			      struct flowi *fl,
			      struct request_sock *req,
			      struct tcp_fastopen_cookie *foc,
			      bool attach_req)
{
	struct inet_request_sock *ireq = inet_rsk(req);
	struct ipv6_pinfo *np = inet6_sk(sk);
	struct flowi6 *fl6 = &fl->u.ip6;
	struct sk_buff *skb;
	int err = -ENOMEM;

	/* First, grab a route. */
	if (!dst && (dst = inet6_csk_route_req(sk, fl6, req,
					       IPPROTO_TCP)) == NULL)
		goto done;

	skb = tcp_make_synack(sk, dst, req, foc, attach_req);

	if (skb) {
		__tcp_v6_send_check(skb, &ireq->ir_v6_loc_addr,
				    &ireq->ir_v6_rmt_addr);

		fl6->daddr = ireq->ir_v6_rmt_addr;
		if (np->repflow && ireq->pktopts)
			fl6->flowlabel = ip6_flowlabel(ipv6_hdr(ireq->pktopts));

		err = ip6_xmit(sk, skb, fl6, np->opt, np->tclass);
		err = net_xmit_eval(err);
	}

done:
	return err;
}
//  [c]
void dm9000EventHandler(NetInterface *interface)
{
   error_t error;
   uint8_t status;

   //Read interrupt status register
   status = dm9000ReadReg(DM9000_ISR);

   //Check whether the link status has changed?
   if((status & DM9000_ISR_LNKCHG) != 0)
   {
      //Clear interrupt flag
      dm9000WriteReg(DM9000_ISR, DM9000_ISR_LNKCHG);
      //Read network status register
      status = dm9000ReadReg(DM9000_NSR);

      //Check link state
      if((status & DM9000_NSR_LINKST) != 0)
      {
         //Get current speed
         if((status & DM9000_NSR_SPEED) != 0)
         {
            interface->linkSpeed = NIC_LINK_SPEED_10MBPS;
         }
         else
         {
            interface->linkSpeed = NIC_LINK_SPEED_100MBPS;
         }

         //Read network control register
         status = dm9000ReadReg(DM9000_NCR);

         //Determine the new duplex mode
         if((status & DM9000_NCR_FDX) != 0)
         {
            interface->duplexMode = NIC_FULL_DUPLEX_MODE;
         }
         else
         {
            interface->duplexMode = NIC_HALF_DUPLEX_MODE;
         }

         //Link is up
         interface->linkState = TRUE;
      }
      else
      {
         //Link is down
         interface->linkState = FALSE;
      }

      //Process link state change event
      nicNotifyLinkChange(interface);
   }

   //Check whether a packet has been received?
   if((status & DM9000_ISR_PR) != 0)
   {
      //Clear interrupt flag
      dm9000WriteReg(DM9000_ISR, DM9000_ISR_PR);

      //Process all pending packets
      do
      {
         //Read incoming packet
         error = dm9000ReceivePacket(interface);

         //No more data in the receive buffer?
      } while(error != ERROR_BUFFER_EMPTY);
   }

   //Re-enable LNKCHGI and PRI interrupts
   dm9000WriteReg(DM9000_IMR, DM9000_IMR_PAR | DM9000_IMR_LNKCHGI |
      DM9000_IMR_PTI | DM9000_IMR_PRI);
}
//  [c]
void dm9000EventHandler(NetInterface *interface)
{
   error_t error;
   uint8_t status;

   //Read interrupt status register
   status = dm9000ReadReg(DM9000_REG_ISR);

   //Check whether the link status has changed?
   if((status & ISR_LNKCHG) != 0)
   {
      //Clear interrupt flag
      dm9000WriteReg(DM9000_REG_ISR, ISR_LNKCHG);
      //Read network status register
      status = dm9000ReadReg(DM9000_REG_NSR);

      //Check link state
      if((status & NSR_LINKST) != 0)
      {
         //Get current speed
         if((status & NSR_SPEED) != 0)
         {
            interface->linkSpeed = NIC_LINK_SPEED_10MBPS;
         }
         else
         {
            interface->linkSpeed = NIC_LINK_SPEED_100MBPS;
         }

         //Read network control register
         status = dm9000ReadReg(DM9000_REG_NCR);

         //Determine the new duplex mode
         if((status & NCR_FDX) != 0)
         {
            interface->duplexMode = NIC_FULL_DUPLEX_MODE;
         }
         else
         {
            interface->duplexMode = NIC_HALF_DUPLEX_MODE;
         }

         //Link is up
         interface->linkState = TRUE;
      }
      else
      {
         //Link is down
         interface->linkState = FALSE;
      }

      //Process link state change event
      nicNotifyLinkChange(interface);
   }

   //Check whether a packet has been received?
   if((status & ISR_PR) != 0)
   {
      //Clear interrupt flag
      dm9000WriteReg(DM9000_REG_ISR, ISR_PR);

      //Process all pending packets
      do
      {
         //Read incoming packet
         error = dm9000ReceivePacket(interface);

         //No more data in the receive buffer?
      } while(error != ERROR_BUFFER_EMPTY);
   }

   //Re-enable LNKCHGI and PRI interrupts
   dm9000WriteReg(DM9000_REG_IMR, IMR_PAR | IMR_LNKCHGI | IMR_PTI | IMR_PRI);
}
//  [c]
int string_rfind(const char *input, int len, const char *s, int s_len,
                 int pos, bool case_sensitive) {
  assertx(input);
  assertx(s);
  if (!s_len || pos < -len || pos > len) {
    return -1;
  }
  void *ptr;
  if (case_sensitive) {
    if (pos >= 0) {
      ptr = bstrrstr(input + pos, len - pos, s, s_len);
    } else {
      ptr = bstrrstr(input, len + std::min(pos + s_len, 0), s, s_len);
    }
  } else {
    if (pos >= 0) {
      ptr = bstrrcasestr(input + pos, len - pos, s, s_len);
    } else {
      ptr = bstrrcasestr(input, len + std::min(pos + s_len, 0), s, s_len);
    }
  }
  if (ptr != nullptr) {
    return (int)((const char *)ptr - input);
  }
  return -1;
}
//  [c]
int string_rfind(const char *input, int len, const char *s, int s_len,
                 int pos, bool case_sensitive) {
  assertx(input);
  assertx(s);
  if (!s_len || pos < -len || pos > len) {
    return -1;
  }
  void *ptr;
  if (case_sensitive) {
    if (pos >= 0) {
      ptr = bstrrstr(input + pos, len - pos, s, s_len);
    } else {
      ptr = bstrrstr(input, len + pos + s_len, s, s_len);
    }
  } else {
    if (pos >= 0) {
      ptr = bstrrcasestr(input + pos, len - pos, s, s_len);
    } else {
      ptr = bstrrcasestr(input, len + pos + s_len, s, s_len);
    }
  }
  if (ptr != nullptr) {
    return (int)((const char *)ptr - input);
  }
  return -1;
}
//  [c]
static u64 __skb_get_nlattr_nest(u64 ctx, u64 A, u64 X, u64 r4, u64 r5)
{
	struct sk_buff *skb = (struct sk_buff *)(long) ctx;
	struct nlattr *nla;

	if (skb_is_nonlinear(skb))
		return 0;

	if (skb->len < sizeof(struct nlattr))
		return 0;

	if (A > skb->len - sizeof(struct nlattr))
		return 0;

	nla = (struct nlattr *) &skb->data[A];
	if (nla->nla_len > skb->len - A)
		return 0;

	nla = nla_find_nested(nla, X);
	if (nla)
		return (void *) nla - (void *) skb->data;

	return 0;
}
//  [c]
static u64 __skb_get_nlattr_nest(u64 ctx, u64 A, u64 X, u64 r4, u64 r5)
{
	struct sk_buff *skb = (struct sk_buff *)(long) ctx;
	struct nlattr *nla;

	if (skb_is_nonlinear(skb))
		return 0;

	if (A > skb->len - sizeof(struct nlattr))
		return 0;

	nla = (struct nlattr *) &skb->data[A];
	if (nla->nla_len > A - skb->len)
		return 0;

	nla = nla_find_nested(nla, X);
	if (nla)
		return (void *) nla - (void *) skb->data;

	return 0;
}
//  [c]
void virtio_config_writew(VirtIODevice *vdev, uint32_t addr, uint32_t data)
{
    VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
    uint16_t val = data;

    if (addr + sizeof(val) > vdev->config_len) {
        return;
    }

    stw_p(vdev->config + addr, val);

    if (k->set_config) {
        k->set_config(vdev, vdev->config);
    }
}
//  [c]
void virtio_config_writew(VirtIODevice *vdev, uint32_t addr, uint32_t data)
{
    VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
    uint16_t val = data;

    if (addr > (vdev->config_len - sizeof(val)))
        return;

    stw_p(vdev->config + addr, val);

    if (k->set_config) {
        k->set_config(vdev, vdev->config);
    }
}
//  [c]
static int compile_search(struct Context *ctx, const struct Pattern *pat, struct Buffer *buf)
{
  if (do_search(pat, 0) == 0)
    return 0;

  if (pat->not)
    mutt_buffer_addstr(buf, "NOT ");

  if (pat->child)
  {
    int clauses;

    clauses = do_search(pat->child, 1);
    if (clauses > 0)
    {
      const struct Pattern *clause = pat->child;

      mutt_buffer_addch(buf, '(');

      while (clauses)
      {
        if (do_search(clause, 0))
        {
          if (pat->op == MUTT_OR && clauses > 1)
            mutt_buffer_addstr(buf, "OR ");
          clauses--;

          if (compile_search(ctx, clause, buf) < 0)
            return -1;

          if (clauses)
            mutt_buffer_addch(buf, ' ');
        }
        clause = clause->next;
      }

      mutt_buffer_addch(buf, ')');
    }
  }
  else
  {
    char term[STRING];
    char *delim = NULL;

    switch (pat->op)
    {
      case MUTT_HEADER:
        mutt_buffer_addstr(buf, "HEADER ");

        /* extract header name */
        delim = strchr(pat->p.str, ':');
        if (!delim)
        {
          mutt_error(_("Header search without header name: %s"), pat->p.str);
          return -1;
        }
        *delim = '\0';
        imap_quote_string(term, sizeof(term), pat->p.str, false);
        mutt_buffer_addstr(buf, term);
        mutt_buffer_addch(buf, ' ');

        /* and field */
        *delim = ':';
        delim++;
        SKIPWS(delim);
        imap_quote_string(term, sizeof(term), delim, false);
        mutt_buffer_addstr(buf, term);
        break;
      case MUTT_BODY:
        mutt_buffer_addstr(buf, "BODY ");
        imap_quote_string(term, sizeof(term), pat->p.str, false);
        mutt_buffer_addstr(buf, term);
        break;
      case MUTT_WHOLE_MSG:
        mutt_buffer_addstr(buf, "TEXT ");
        imap_quote_string(term, sizeof(term), pat->p.str, false);
        mutt_buffer_addstr(buf, term);
        break;
      case MUTT_SERVERSEARCH:
      {
        struct ImapData *idata = ctx->data;
        if (!mutt_bit_isset(idata->capabilities, X_GM_EXT1))
        {
          mutt_error(_("Server-side custom search not supported: %s"), pat->p.str);
          return -1;
        }
      }
        mutt_buffer_addstr(buf, "X-GM-RAW ");
        imap_quote_string(term, sizeof(term), pat->p.str, false);
        mutt_buffer_addstr(buf, term);
        break;
    }
  }

  return 0;
}
//  [c]
static int compile_search(struct Context *ctx, const struct Pattern *pat, struct Buffer *buf)
{
  if (do_search(pat, 0) == 0)
    return 0;

  if (pat->not)
    mutt_buffer_addstr(buf, "NOT ");

  if (pat->child)
  {
    int clauses;

    clauses = do_search(pat->child, 1);
    if (clauses > 0)
    {
      const struct Pattern *clause = pat->child;

      mutt_buffer_addch(buf, '(');

      while (clauses)
      {
        if (do_search(clause, 0))
        {
          if (pat->op == MUTT_OR && clauses > 1)
            mutt_buffer_addstr(buf, "OR ");
          clauses--;

          if (compile_search(ctx, clause, buf) < 0)
            return -1;

          if (clauses)
            mutt_buffer_addch(buf, ' ');
        }
        clause = clause->next;
      }

      mutt_buffer_addch(buf, ')');
    }
  }
  else
  {
    char term[STRING];
    char *delim = NULL;

    switch (pat->op)
    {
      case MUTT_HEADER:
        mutt_buffer_addstr(buf, "HEADER ");

        /* extract header name */
        delim = strchr(pat->p.str, ':');
        if (!delim)
        {
          mutt_error(_("Header search without header name: %s"), pat->p.str);
          return -1;
        }
        *delim = '\0';
        imap_quote_string(term, sizeof(term), pat->p.str);
        mutt_buffer_addstr(buf, term);
        mutt_buffer_addch(buf, ' ');

        /* and field */
        *delim = ':';
        delim++;
        SKIPWS(delim);
        imap_quote_string(term, sizeof(term), delim);
        mutt_buffer_addstr(buf, term);
        break;
      case MUTT_BODY:
        mutt_buffer_addstr(buf, "BODY ");
        imap_quote_string(term, sizeof(term), pat->p.str);
        mutt_buffer_addstr(buf, term);
        break;
      case MUTT_WHOLE_MSG:
        mutt_buffer_addstr(buf, "TEXT ");
        imap_quote_string(term, sizeof(term), pat->p.str);
        mutt_buffer_addstr(buf, term);
        break;
      case MUTT_SERVERSEARCH:
      {
        struct ImapData *idata = ctx->data;
        if (!mutt_bit_isset(idata->capabilities, X_GM_EXT1))
        {
          mutt_error(_("Server-side custom search not supported: %s"), pat->p.str);
          return -1;
        }
      }
        mutt_buffer_addstr(buf, "X-GM-RAW ");
        imap_quote_string(term, sizeof(term), pat->p.str);
        mutt_buffer_addstr(buf, term);
        break;
    }
  }

  return 0;
}
//  [c]
uint16_t dm9000ReadPhyReg(uint8_t address)
{
   //Write PHY register address
   dm9000WriteReg(DM9000_EPAR, 0x40 | address);

   //Start the read operation
   dm9000WriteReg(DM9000_EPCR, DM9000_EPCR_EPOS | DM9000_EPCR_ERPRR);

   //PHY access is still in progress?
   while((dm9000ReadReg(DM9000_EPCR) & DM9000_EPCR_ERRE) != 0)
   {
   }

   //Clear command register
   dm9000WriteReg(DM9000_EPCR, DM9000_EPCR_EPOS);
   //Wait 5us minimum
   usleep(5);

   //Return register value
   return (dm9000ReadReg(DM9000_EPDRH) << 8) | dm9000ReadReg(DM9000_EPDRL);
}
//  [c]
uint16_t dm9000ReadPhyReg(uint8_t address)
{
   //Write PHY register address
   dm9000WriteReg(DM9000_REG_EPAR, 0x40 | address);

   //Start the read operation
   dm9000WriteReg(DM9000_REG_EPCR, EPCR_EPOS | EPCR_ERPRR);
   //PHY access is still in progress?
   while((dm9000ReadReg(DM9000_REG_EPCR) & EPCR_ERRE) != 0)
   {
   }

   //Clear command register
   dm9000WriteReg(DM9000_REG_EPCR, EPCR_EPOS);
   //Wait 5us minimum
   usleep(5);

   //Return register value
   return (dm9000ReadReg(DM9000_REG_EPDRH) << 8) | dm9000ReadReg(DM9000_REG_EPDRL);
}
//  [c]
error_t dm9000ReceivePacket(NetInterface *interface)
{
   error_t error;
   size_t i;
   size_t n;
   size_t length;
   volatile uint8_t status;
   volatile uint16_t data;
   Dm9000Context *context;

   //Point to the driver context
   context = (Dm9000Context *) interface->nicContext;

   //A dummy read is required before accessing the 4-byte header
   data = dm9000ReadReg(DM9000_MRCMDX);

   //Select MRCMDX1 register
   DM9000_INDEX_REG = DM9000_MRCMDX1;
   //Read the first byte of the header
   status = LSB(DM9000_DATA_REG);

   //The first byte indicates if a packet has been received
   if(status == 0x01)
   {
      //Select MRCMD register
      DM9000_INDEX_REG = DM9000_MRCMD;
      //The second byte is the RX status byte
      status = MSB(DM9000_DATA_REG);

      //Retrieve packet length
      length = DM9000_DATA_REG;
      //Limit the number of data to read
      n = MIN(length, ETH_MAX_FRAME_SIZE);

      //Point to the beginning of the buffer
      i = 0;

      //Make sure no error occurred
      if((status & (DM9000_RSR_LCS | DM9000_RSR_RWTO | DM9000_RSR_PLE |
         DM9000_RSR_AE | DM9000_RSR_CE | DM9000_RSR_FOE)) == 0)
      {
         //Read data from FIFO using 16-bit mode
         while((i + 1) < n)
         {
            data = DM9000_DATA_REG;
            context->rxBuffer[i++] = LSB(data);
            context->rxBuffer[i++] = MSB(data);
         }

         //Odd number of bytes to read?
         if((i + 1) == n)
         {
            data = DM9000_DATA_REG;
            context->rxBuffer[i] = LSB(data);
            i += 2;
         }

         //Valid packet received
         error = NO_ERROR;
      }
      else
      {
         //The received packet contains an error
         error = ERROR_INVALID_PACKET;
      }

      //Flush remaining bytes
      while(i < length)
      {
         data = DM9000_DATA_REG;
         i += 2;
      }
   }
   else
   {
      //No more data in the receive buffer
      error = ERROR_BUFFER_EMPTY;
   }

   //Check whether a valid packet has been received
   if(!error)
   {
      NetRxAncillary ancillary;

      //Additional options can be passed to the stack along with the packet
      ancillary = NET_DEFAULT_RX_ANCILLARY;

      //Pass the packet to the upper layer
      nicProcessPacket(interface, context->rxBuffer, n, &ancillary);
   }

   //Return status code
   return error;
}
//  [c]
error_t dm9000ReceivePacket(NetInterface *interface)
{
   error_t error;
   size_t i;
   size_t n;
   size_t length;
   volatile uint8_t status;
   volatile uint16_t data;
   Dm9000Context *context;

   //Point to the driver context
   context = (Dm9000Context *) interface->nicContext;

   //A dummy read is required before accessing the 4-byte header
   data = dm9000ReadReg(DM9000_REG_MRCMDX);

   //Select MRCMDX1 register
   DM9000_INDEX_REG = DM9000_REG_MRCMDX1;
   //Read the first byte of the header
   status = LSB(DM9000_DATA_REG);

   //The first byte indicates if a packet has been received
   if(status == 0x01)
   {
      //Select MRCMD register
      DM9000_INDEX_REG = DM9000_REG_MRCMD;
      //The second byte is the RX status byte
      status = MSB(DM9000_DATA_REG);

      //Retrieve packet length
      length = DM9000_DATA_REG;
      //Limit the number of data to read
      n = MIN(length, ETH_MAX_FRAME_SIZE);

      //Point to the beginning of the buffer
      i = 0;

      //Make sure no error occurred
      if((status & (RSR_LCS | RSR_RWTO | RSR_PLE | RSR_AE | RSR_CE | RSR_FOE)) == 0)
      {
         //Read data from FIFO using 16-bit mode
         while((i + 1) < n)
         {
            data = DM9000_DATA_REG;
            context->rxBuffer[i++] = LSB(data);
            context->rxBuffer[i++] = MSB(data);
         }

         //Odd number of bytes to read?
         if((i + 1) == n)
         {
            data = DM9000_DATA_REG;
            context->rxBuffer[i] = LSB(data);
            i += 2;
         }

         //Valid packet received
         error = NO_ERROR;
      }
      else
      {
         //The received packet contains an error
         error = ERROR_INVALID_PACKET;
      }

      //Flush remaining bytes
      while(i < length)
      {
         data = DM9000_DATA_REG;
         i += 2;
      }
   }
   else
   {
      //No more data in the receive buffer
      error = ERROR_BUFFER_EMPTY;
   }

   //Check whether a valid packet has been received
   if(!error)
   {
      NetRxAncillary ancillary;

      //Additional options can be passed to the stack along with the packet
      ancillary = NET_DEFAULT_RX_ANCILLARY;

      //Pass the packet to the upper layer
      nicProcessPacket(interface, context->rxBuffer, n, &ancillary);
   }

   //Return status code
   return error;
}
//  [c]
void dm9000WritePhyReg(uint8_t address, uint16_t data)
{
   //Write PHY register address
   dm9000WriteReg(DM9000_EPAR, 0x40 | address);
   //Write register value
   dm9000WriteReg(DM9000_EPDRL, LSB(data));
   dm9000WriteReg(DM9000_EPDRH, MSB(data));

   //Start the write operation
   dm9000WriteReg(DM9000_EPCR, DM9000_EPCR_EPOS | DM9000_EPCR_ERPRW);

   //PHY access is still in progress?
   while((dm9000ReadReg(DM9000_EPCR) & DM9000_EPCR_ERRE) != 0)
   {
   }

   //Wait 5us minimum
   usleep(5);
   //Clear command register
   dm9000WriteReg(DM9000_EPCR, DM9000_EPCR_EPOS);
}
//  [c]
void dm9000WritePhyReg(uint8_t address, uint16_t data)
{
   //Write PHY register address
   dm9000WriteReg(DM9000_REG_EPAR, 0x40 | address);
   //Write register value
   dm9000WriteReg(DM9000_REG_EPDRL, LSB(data));
   dm9000WriteReg(DM9000_REG_EPDRH, MSB(data));

   //Start the write operation
   dm9000WriteReg(DM9000_REG_EPCR, EPCR_EPOS | EPCR_ERPRW);
   //PHY access is still in progress?
   while((dm9000ReadReg(DM9000_REG_EPCR) & EPCR_ERRE) != 0)
   {
   }

   //Wait 5us minimum
   usleep(5);
   //Clear command register
   dm9000WriteReg(DM9000_REG_EPCR, EPCR_EPOS);
}
//  [c]
bool_t dm9000IrqHandler(NetInterface *interface)
{
   bool_t flag;
   uint8_t status;
   uint8_t mask;
   Dm9000Context *context;

   //This flag will be set if a higher priority task must be woken
   flag = FALSE;

   //Point to the driver context
   context = (Dm9000Context *) interface->nicContext;

   //Read interrupt status register
   status = dm9000ReadReg(DM9000_ISR);

   //Link status change?
   if((status & DM9000_ISR_LNKCHG) != 0)
   {
      //Read interrupt mask register
      mask = dm9000ReadReg(DM9000_IMR);
      //Disable LNKCHGI interrupt
      dm9000WriteReg(DM9000_IMR, mask & ~DM9000_IMR_LNKCHGI);

      //Set event flag
      interface->nicEvent = TRUE;
      //Notify the TCP/IP stack of the event
      flag |= osSetEventFromIsr(&netEvent);
   }

   //Packet transmission complete?
   if((status & DM9000_ISR_PT) != 0)
   {
      //Check TX complete status bits
      if((dm9000ReadReg(DM9000_NSR) & (DM9000_NSR_TX2END | DM9000_NSR_TX1END)) != 0)
      {
         //The transmission of the current packet is complete
         if(context->queuedPackets > 0)
         {
            context->queuedPackets--;
         }

         //Notify the TCP/IP stack that the transmitter is ready to send
         flag |= osSetEventFromIsr(&interface->nicTxEvent);
      }

      //Clear interrupt flag
      dm9000WriteReg(DM9000_ISR, DM9000_ISR_PT);
   }

   //Packet received?
   if((status & DM9000_ISR_PR) != 0)
   {
      //Read interrupt mask register
      mask = dm9000ReadReg(DM9000_IMR);
      //Disable PRI interrupt
      dm9000WriteReg(DM9000_IMR, mask & ~DM9000_IMR_PRI);

      //Set event flag
      interface->nicEvent = TRUE;
      //Notify the TCP/IP stack of the event
      flag |= osSetEventFromIsr(&netEvent);
   }

   //A higher priority task must be woken?
   return flag;
}
//  [c]
bool_t dm9000IrqHandler(NetInterface *interface)
{
   bool_t flag;
   uint8_t status;
   uint8_t mask;
   Dm9000Context *context;

   //This flag will be set if a higher priority task must be woken
   flag = FALSE;

   //Point to the driver context
   context = (Dm9000Context *) interface->nicContext;

   //Read interrupt status register
   status = dm9000ReadReg(DM9000_REG_ISR);

   //Link status change?
   if((status & ISR_LNKCHG) != 0)
   {
      //Read interrupt mask register
      mask = dm9000ReadReg(DM9000_REG_IMR);
      //Disable LNKCHGI interrupt
      dm9000WriteReg(DM9000_REG_IMR, mask & ~IMR_LNKCHGI);

      //Set event flag
      interface->nicEvent = TRUE;
      //Notify the TCP/IP stack of the event
      flag |= osSetEventFromIsr(&netEvent);
   }

   //Packet transmission complete?
   if((status & ISR_PT) != 0)
   {
      //Check TX complete status bits
      if(dm9000ReadReg(DM9000_REG_NSR) & (NSR_TX2END | NSR_TX1END))
      {
         //The transmission of the current packet is complete
         if(context->queuedPackets > 0)
         {
            context->queuedPackets--;
         }

         //Notify the TCP/IP stack that the transmitter is ready to send
         flag |= osSetEventFromIsr(&interface->nicTxEvent);
      }

      //Clear interrupt flag
      dm9000WriteReg(DM9000_REG_ISR, ISR_PT);
   }

   //Packet received?
   if((status & ISR_PR) != 0)
   {
      //Read interrupt mask register
      mask = dm9000ReadReg(DM9000_REG_IMR);
      //Disable PRI interrupt
      dm9000WriteReg(DM9000_REG_IMR, mask & ~IMR_PRI);

      //Set event flag
      interface->nicEvent = TRUE;
      //Notify the TCP/IP stack of the event
      flag |= osSetEventFromIsr(&netEvent);
   }

   //A higher priority task must be woken?
   return flag;
}
//  [c]
error_t dm9000UpdateMacAddrFilter(NetInterface *interface)
{
   uint_t i;
   uint_t k;
   uint32_t crc;
   uint8_t hashTable[8];
   MacFilterEntry *entry;

   //Debug message
   TRACE_DEBUG("Updating MAC filter...\r\n");

   //Clear hash table
   osMemset(hashTable, 0, sizeof(hashTable));
   //Always accept broadcast packets regardless of the MAC filter table
   hashTable[7] = 0x80;

   //The MAC address filter contains the list of MAC addresses to accept
   //when receiving an Ethernet frame
   for(i = 0; i < MAC_ADDR_FILTER_SIZE; i++)
   {
      //Point to the current entry
      entry = &interface->macAddrFilter[i];

      //Valid entry?
      if(entry->refCount > 0)
      {
         //Compute CRC over the current MAC address
         crc = dm9000CalcCrc(&entry->addr, sizeof(MacAddr));
         //Calculate the corresponding index in the table
         k = crc & 0x3F;
         //Update hash table contents
         hashTable[k / 8] |= (1 << (k % 8));
      }
   }

   //Write the hash table to the DM9000 controller
   for(i = 0; i < 8; i++)
   {
      dm9000WriteReg(DM9000_MAR0 + i, hashTable[i]);
   }

   //Debug message
   TRACE_DEBUG("  MAR = %02" PRIX8 " %02" PRIX8 " %02" PRIX8 " %02" PRIX8 " "
      "%02" PRIX8 " %02" PRIX8 " %02" PRIX8 " %02" PRIX8 "\r\n",
      dm9000ReadReg(DM9000_MAR0), dm9000ReadReg(DM9000_MAR1),
      dm9000ReadReg(DM9000_MAR2), dm9000ReadReg(DM9000_MAR3),
      dm9000ReadReg(DM9000_MAR4), dm9000ReadReg(DM9000_MAR5),
      dm9000ReadReg(DM9000_MAR6), dm9000ReadReg(DM9000_MAR7));

   //Successful processing
   return NO_ERROR;
}
//  [c]
error_t dm9000UpdateMacAddrFilter(NetInterface *interface)
{
   uint_t i;
   uint_t k;
   uint32_t crc;
   uint8_t hashTable[8];
   MacFilterEntry *entry;

   //Debug message
   TRACE_DEBUG("Updating MAC filter...\r\n");

   //Clear hash table
   osMemset(hashTable, 0, sizeof(hashTable));
   //Always accept broadcast packets regardless of the MAC filter table
   hashTable[7] = 0x80;

   //The MAC address filter contains the list of MAC addresses to accept
   //when receiving an Ethernet frame
   for(i = 0; i < MAC_ADDR_FILTER_SIZE; i++)
   {
      //Point to the current entry
      entry = &interface->macAddrFilter[i];

      //Valid entry?
      if(entry->refCount > 0)
      {
         //Compute CRC over the current MAC address
         crc = dm9000CalcCrc(&entry->addr, sizeof(MacAddr));
         //Calculate the corresponding index in the table
         k = crc & 0x3F;
         //Update hash table contents
         hashTable[k / 8] |= (1 << (k % 8));
      }
   }

   //Write the hash table to the DM9000 controller
   for(i = 0; i < 8; i++)
   {
      dm9000WriteReg(DM9000_REG_MAR0 + i, hashTable[i]);
   }

   //Debug message
   TRACE_DEBUG("  MAR = %02" PRIX8 " %02" PRIX8 " %02" PRIX8 " %02" PRIX8 " "
      "%02" PRIX8 " %02" PRIX8 " %02" PRIX8 " %02" PRIX8 "\r\n",
      dm9000ReadReg(DM9000_REG_MAR0), dm9000ReadReg(DM9000_REG_MAR1),
      dm9000ReadReg(DM9000_REG_MAR2), dm9000ReadReg(DM9000_REG_MAR3),
      dm9000ReadReg(DM9000_REG_MAR4), dm9000ReadReg(DM9000_REG_MAR5),
      dm9000ReadReg(DM9000_REG_MAR6), dm9000ReadReg(DM9000_REG_MAR7));

   //Successful processing
   return NO_ERROR;
}
//  [c]
next_line(struct archive_read *a,
    const char **b, ssize_t *avail, ssize_t *ravail, ssize_t *nl)
{
	ssize_t len;
	int quit;
	
	quit = 0;
	if (*avail == 0) {
		*nl = 0;
		len = 0;
	} else
		len = get_line_size(*b, *avail, nl);
	/*
	 * Read bytes more while it does not reach the end of line.
	 */
	while (*nl == 0 && len == *avail && !quit) {
		ssize_t diff = *ravail - *avail;
		size_t nbytes_req = (*ravail+1023) & ~1023U;
		ssize_t tested;

		/* Increase reading bytes if it is not enough to at least
		 * new two lines. */
		if (nbytes_req < (size_t)*ravail + 160)
			nbytes_req <<= 1;

		*b = __archive_read_ahead(a, nbytes_req, avail);
		if (*b == NULL) {
			if (*ravail >= *avail)
				return (0);
			/* Reading bytes reaches the end of file. */
			*b = __archive_read_ahead(a, *avail, avail);
			quit = 1;
		}
		*ravail = *avail;
		*b += diff;
		*avail -= diff;
		tested = len;/* Skip some bytes we already determinated. */
		len = get_line_size(*b + len, *avail - len, nl);
		if (len >= 0)
			len += tested;
	}
	return (len);
}
//  [c]
next_line(struct archive_read *a,
    const char **b, ssize_t *avail, ssize_t *ravail, ssize_t *nl)
{
	ssize_t len;
	int quit;
	
	quit = 0;
	if (*avail == 0) {
		*nl = 0;
		len = 0;
	} else
		len = get_line_size(*b, *avail, nl);
	/*
	 * Read bytes more while it does not reach the end of line.
	 */
	while (*nl == 0 && len == *avail && !quit) {
		ssize_t diff = *ravail - *avail;
		size_t nbytes_req = (*ravail+1023) & ~1023U;
		ssize_t tested;

		/* Increase reading bytes if it is not enough to at least
		 * new two lines. */
		if (nbytes_req < (size_t)*ravail + 160)
			nbytes_req <<= 1;

		*b = __archive_read_ahead(a, nbytes_req, avail);
		if (*b == NULL) {
			if (*ravail >= *avail)
				return (0);
			/* Reading bytes reaches the end of file. */
			*b = __archive_read_ahead(a, *avail, avail);
			quit = 1;
		}
		*ravail = *avail;
		*b += diff;
		*avail -= diff;
		tested = len;/* Skip some bytes we already determinated. */
		len = get_line_size(*b, *avail, nl);
		if (len >= 0)
			len += tested;
	}
	return (len);
}
//  [c]
sysDescr_handler(snmp_varbind_t *varbind, snmp_oid_t *oid)
{
  snmp_api_set_string(varbind, oid, CONTIKI_VERSION_STRING);
}
//  [c]
sysDescr_handler(snmp_varbind_t *varbind, uint32_t *oid)
{
  snmp_api_set_string(varbind, oid, CONTIKI_VERSION_STRING);
}
//  [c]
sysLocation_handler(snmp_varbind_t *varbind, snmp_oid_t *oid)
{
  snmp_api_set_string(varbind, oid, "");
}
//  [c]
sysLocation_handler(snmp_varbind_t *varbind, uint32_t *oid)
{
  snmp_api_set_string(varbind, oid, "");
}
//  [c]
sysContact_handler(snmp_varbind_t *varbind, snmp_oid_t *oid)
{
  snmp_api_set_string(varbind, oid, "Contiki-NG, https://github.com/contiki-ng/contiki-ng");
}
//  [c]
sysContact_handler(snmp_varbind_t *varbind, uint32_t *oid)
{
  snmp_api_set_string(varbind, oid, "Contiki-NG, https://github.com/contiki-ng/contiki-ng");
}
//  [c]
error_t dm9000SendPacket(NetInterface *interface,
   const NetBuffer *buffer, size_t offset, NetTxAncillary *ancillary)
{
   size_t i;
   size_t length;
   uint16_t *p;
   Dm9000Context *context;

   //Point to the driver context
   context = (Dm9000Context *) interface->nicContext;

   //Retrieve the length of the packet
   length = netBufferGetLength(buffer) - offset;

   //Check the frame length
   if(length > ETH_MAX_FRAME_SIZE)
   {
      //The transmitter can accept another packet
      osSetEvent(&interface->nicTxEvent);
      //Report an error
      return ERROR_INVALID_LENGTH;
   }

   //Copy user data
   netBufferRead(context->txBuffer, buffer, offset, length);

   //A dummy write is required before accessing FIFO
   dm9000WriteReg(DM9000_MWCMDX, 0);
   //Select MWCMD register
   DM9000_INDEX_REG = DM9000_MWCMD;

   //Point to the beginning of the buffer
   p = (uint16_t *) context->txBuffer;

   //Write data to the FIFO using 16-bit mode
   for(i = length; i > 1; i -= 2)
   {
      DM9000_DATA_REG = *(p++);
   }

   //Odd number of bytes?
   if(i > 0)
   {
      DM9000_DATA_REG = *((uint8_t *) p);
   }

   //Write the number of bytes to send
   dm9000WriteReg(DM9000_TXPLL, LSB(length));
   dm9000WriteReg(DM9000_TXPLH, MSB(length));

   //Clear interrupt flag
   dm9000WriteReg(DM9000_ISR, DM9000_ISR_PT);
   //Start data transfer
   dm9000WriteReg(DM9000_TCR, DM9000_TCR_TXREQ);

   //The packet was successfully written to FIFO
   context->queuedPackets++;

   //Successful processing
   return NO_ERROR;
}
//  [c]
error_t dm9000SendPacket(NetInterface *interface,
   const NetBuffer *buffer, size_t offset, NetTxAncillary *ancillary)
{
   size_t i;
   size_t length;
   uint16_t *p;
   Dm9000Context *context;

   //Point to the driver context
   context = (Dm9000Context *) interface->nicContext;

   //Retrieve the length of the packet
   length = netBufferGetLength(buffer) - offset;

   //Check the frame length
   if(length > ETH_MAX_FRAME_SIZE)
   {
      //The transmitter can accept another packet
      osSetEvent(&interface->nicTxEvent);
      //Report an error
      return ERROR_INVALID_LENGTH;
   }

   //Copy user data
   netBufferRead(context->txBuffer, buffer, offset, length);

   //A dummy write is required before accessing FIFO
   dm9000WriteReg(DM9000_REG_MWCMDX, 0);
   //Select MWCMD register
   DM9000_INDEX_REG = DM9000_REG_MWCMD;

   //Point to the beginning of the buffer
   p = (uint16_t *) context->txBuffer;

   //Write data to the FIFO using 16-bit mode
   for(i = length; i > 1; i -= 2)
   {
      DM9000_DATA_REG = *(p++);
   }

   //Odd number of bytes?
   if(i > 0)
   {
      DM9000_DATA_REG = *((uint8_t *) p);
   }

   //Write the number of bytes to send
   dm9000WriteReg(DM9000_REG_TXPLL, LSB(length));
   dm9000WriteReg(DM9000_REG_TXPLH, MSB(length));

   //Clear interrupt flag
   dm9000WriteReg(DM9000_REG_ISR, ISR_PT);
   //Start data transfer
   dm9000WriteReg(DM9000_REG_TCR, TCR_TXREQ);

   //The packet was successfully written to FIFO
   context->queuedPackets++;

   //Successful processing
   return NO_ERROR;
}
//  [c]
sysName_handler(snmp_varbind_t *varbind, snmp_oid_t *oid)
{
  snmp_api_set_string(varbind, oid, "Contiki-NG - "CONTIKI_TARGET_STRING);
}
//  [c]
sysName_handler(snmp_varbind_t *varbind, uint32_t *oid)
{
  snmp_api_set_string(varbind, oid, "Contiki-NG - "CONTIKI_TARGET_STRING);
}
//  [c]
get_matching_model_microcode(int cpu, unsigned long start,
			     void *data, size_t size,
			     struct mc_saved_data *mc_saved_data,
			     unsigned long *mc_saved_in_initrd,
			     struct ucode_cpu_info *uci)
{
	u8 *ucode_ptr = data;
	unsigned int leftover = size;
	enum ucode_state state = UCODE_OK;
	unsigned int mc_size;
	struct microcode_header_intel *mc_header;
	struct microcode_intel *mc_saved_tmp[MAX_UCODE_COUNT];
	unsigned int mc_saved_count = mc_saved_data->mc_saved_count;
	int i;

	while (leftover && mc_saved_count < ARRAY_SIZE(mc_saved_tmp)) {
		mc_header = (struct microcode_header_intel *)ucode_ptr;

		mc_size = get_totalsize(mc_header);
		if (!mc_size || mc_size > leftover ||
			microcode_sanity_check(ucode_ptr, 0) < 0)
			break;

		leftover -= mc_size;

		/*
		 * Since APs with same family and model as the BSP may boot in
		 * the platform, we need to find and save microcode patches
		 * with the same family and model as the BSP.
		 */
		if (matching_model_microcode(mc_header, uci->cpu_sig.sig) !=
			 UCODE_OK) {
			ucode_ptr += mc_size;
			continue;
		}

		_save_mc(mc_saved_tmp, ucode_ptr, &mc_saved_count);

		ucode_ptr += mc_size;
	}

	if (leftover) {
		state = UCODE_ERROR;
		goto out;
	}

	if (mc_saved_count == 0) {
		state = UCODE_NFOUND;
		goto out;
	}

	for (i = 0; i < mc_saved_count; i++)
		mc_saved_in_initrd[i] = (unsigned long)mc_saved_tmp[i] - start;

	mc_saved_data->mc_saved_count = mc_saved_count;
out:
	return state;
}
//  [c]
get_matching_model_microcode(int cpu, unsigned long start,
			     void *data, size_t size,
			     struct mc_saved_data *mc_saved_data,
			     unsigned long *mc_saved_in_initrd,
			     struct ucode_cpu_info *uci)
{
	u8 *ucode_ptr = data;
	unsigned int leftover = size;
	enum ucode_state state = UCODE_OK;
	unsigned int mc_size;
	struct microcode_header_intel *mc_header;
	struct microcode_intel *mc_saved_tmp[MAX_UCODE_COUNT];
	unsigned int mc_saved_count = mc_saved_data->mc_saved_count;
	int i;

	while (leftover) {
		mc_header = (struct microcode_header_intel *)ucode_ptr;

		mc_size = get_totalsize(mc_header);
		if (!mc_size || mc_size > leftover ||
			microcode_sanity_check(ucode_ptr, 0) < 0)
			break;

		leftover -= mc_size;

		/*
		 * Since APs with same family and model as the BSP may boot in
		 * the platform, we need to find and save microcode patches
		 * with the same family and model as the BSP.
		 */
		if (matching_model_microcode(mc_header, uci->cpu_sig.sig) !=
			 UCODE_OK) {
			ucode_ptr += mc_size;
			continue;
		}

		_save_mc(mc_saved_tmp, ucode_ptr, &mc_saved_count);

		ucode_ptr += mc_size;
	}

	if (leftover) {
		state = UCODE_ERROR;
		goto out;
	}

	if (mc_saved_count == 0) {
		state = UCODE_NFOUND;
		goto out;
	}

	for (i = 0; i < mc_saved_count; i++)
		mc_saved_in_initrd[i] = (unsigned long)mc_saved_tmp[i] - start;

	mc_saved_data->mc_saved_count = mc_saved_count;
out:
	return state;
}
//  [c]
sysUpTime_handler(snmp_varbind_t *varbind, snmp_oid_t *oid)
{
  snmp_api_set_time_ticks(varbind, oid, clock_seconds() * 100);
}
//  [c]
sysUpTime_handler(snmp_varbind_t *varbind, uint32_t *oid)
{
  snmp_api_set_time_ticks(varbind, oid, clock_seconds() * 100);
}
//  [c]
sysServices_handler(snmp_varbind_t *varbind, snmp_oid_t *oid)
{
  snmp_api_set_time_ticks(varbind, oid, clock_seconds() * 100);
}
//  [c]
sysServices_handler(snmp_varbind_t *varbind, uint32_t *oid)
{
  snmp_api_set_time_ticks(varbind, oid, clock_seconds() * 100);
}
//  [c]
static MOBI_RET mobi_decompress_huffman_internal(MOBIBuffer *buf_out, MOBIBuffer *buf_in, const MOBIHuffCdic *huffcdic, size_t depth) {
    if (depth > MOBI_HUFFMAN_MAXDEPTH) {
        debug_print("Too many levels of recursion: %zu\n", depth);
        return MOBI_DATA_CORRUPT;
    }
    MOBI_RET ret = MOBI_SUCCESS;
    int8_t bitcount = 32;
    /* this cast should be safe: max record size is 4096 */
    int bitsleft = (int) (buf_in->maxlen * 8);
    uint8_t code_length = 0;
    uint64_t buffer = mobi_buffer_fill64(buf_in);
    while (ret == MOBI_SUCCESS) {
        if (bitcount <= 0) {
            bitcount += 32;
            buffer = mobi_buffer_fill64(buf_in);
        }
        uint32_t code = (buffer >> bitcount) & 0xffffffffU;
        /* lookup code in table1 */
        uint32_t t1 = huffcdic->table1[code >> 24];
        /* get maxcode and codelen from t1 */
        code_length = t1 & 0x1f;
        uint32_t maxcode = (((t1 >> 8) + 1) << (32 - code_length)) - 1;
        /* check termination bit */
        if (!(t1 & 0x80)) {
            /* get offset from mincode, maxcode tables */
            while (code < huffcdic->mincode_table[code_length]) {
                if (++code_length >= HUFF_CODETABLE_SIZE) {
                    debug_print("Wrong offset to mincode table: %hhu\n", code_length);
                    return MOBI_DATA_CORRUPT;
                }
            }
            maxcode = huffcdic->maxcode_table[code_length];
        }
        bitcount -= code_length;
        bitsleft -= code_length;
        if (bitsleft < 0) {
            break;
        }
        /* get index for symbol offset */
        uint32_t index = (uint32_t) (maxcode - code) >> (32 - code_length);
        /* check which part of cdic to use */
        uint16_t cdic_index = (uint16_t) ((uint32_t)index >> huffcdic->code_length);
        if (index >= huffcdic->index_count) {
            debug_print("Wrong symbol offsets index: %u\n", index);
            return MOBI_DATA_CORRUPT;
        }
        /* get offset */
        uint32_t offset = huffcdic->symbol_offsets[index];
        uint32_t symbol_length = (uint32_t) huffcdic->symbols[cdic_index][offset] << 8 | (uint32_t) huffcdic->symbols[cdic_index][offset + 1];
        /* 1st bit is is_decompressed flag */
        int is_decompressed = symbol_length >> 15;
        /* get rid of flag */
        symbol_length &= 0x7fff;
        if (is_decompressed) {
            /* symbol is at (offset + 2), 2 bytes used earlier for symbol length */
            mobi_buffer_addraw(buf_out, (huffcdic->symbols[cdic_index] + offset + 2), symbol_length);
            ret = buf_out->error;
        } else {
            /* symbol is compressed */
            /* TODO cache uncompressed symbols? */
            MOBIBuffer buf_sym;
            buf_sym.data = huffcdic->symbols[cdic_index] + offset + 2;
            buf_sym.offset = 0;
            buf_sym.maxlen = symbol_length;
            buf_sym.error = MOBI_SUCCESS;
            ret = mobi_decompress_huffman_internal(buf_out, &buf_sym, huffcdic, depth + 1);
        }
    }
    return ret;
}
//  [c]
static MOBI_RET mobi_decompress_huffman_internal(MOBIBuffer *buf_out, MOBIBuffer *buf_in, const MOBIHuffCdic *huffcdic, size_t depth) {
    if (depth > MOBI_HUFFMAN_MAXDEPTH) {
        debug_print("Too many levels of recursion: %zu\n", depth);
        return MOBI_DATA_CORRUPT;
    }
    MOBI_RET ret = MOBI_SUCCESS;
    int8_t bitcount = 32;
    /* this cast should be safe: max record size is 4096 */
    int bitsleft = (int) (buf_in->maxlen * 8);
    uint8_t code_length = 0;
    uint64_t buffer = mobi_buffer_fill64(buf_in);
    while (ret == MOBI_SUCCESS) {
        if (bitcount <= 0) {
            bitcount += 32;
            buffer = mobi_buffer_fill64(buf_in);
        }
        uint32_t code = (buffer >> bitcount) & 0xffffffffU;
        /* lookup code in table1 */
        uint32_t t1 = huffcdic->table1[code >> 24];
        /* get maxcode and codelen from t1 */
        code_length = t1 & 0x1f;
        uint32_t maxcode = (((t1 >> 8) + 1) << (32 - code_length)) - 1;
        /* check termination bit */
        if (!(t1 & 0x80)) {
            /* get offset from mincode, maxcode tables */
            while (code < huffcdic->mincode_table[code_length]) {
                code_length++;
            }
            maxcode = huffcdic->maxcode_table[code_length];
        }
        bitcount -= code_length;
        bitsleft -= code_length;
        if (bitsleft < 0) {
            break;
        }
        /* get index for symbol offset */
        uint32_t index = (uint32_t) (maxcode - code) >> (32 - code_length);
        /* check which part of cdic to use */
        uint16_t cdic_index = (uint16_t) ((uint32_t)index >> huffcdic->code_length);
        if (index >= huffcdic->index_count) {
            debug_print("Wrong symbol offsets index: %u\n", index);
            return MOBI_DATA_CORRUPT;
        }
        /* get offset */
        uint32_t offset = huffcdic->symbol_offsets[index];
        uint32_t symbol_length = (uint32_t) huffcdic->symbols[cdic_index][offset] << 8 | (uint32_t) huffcdic->symbols[cdic_index][offset + 1];
        /* 1st bit is is_decompressed flag */
        int is_decompressed = symbol_length >> 15;
        /* get rid of flag */
        symbol_length &= 0x7fff;
        if (is_decompressed) {
            /* symbol is at (offset + 2), 2 bytes used earlier for symbol length */
            mobi_buffer_addraw(buf_out, (huffcdic->symbols[cdic_index] + offset + 2), symbol_length);
            ret = buf_out->error;
        } else {
            /* symbol is compressed */
            /* TODO cache uncompressed symbols? */
            MOBIBuffer buf_sym;
            buf_sym.data = huffcdic->symbols[cdic_index] + offset + 2;
            buf_sym.offset = 0;
            buf_sym.maxlen = symbol_length;
            buf_sym.error = MOBI_SUCCESS;
            ret = mobi_decompress_huffman_internal(buf_out, &buf_sym, huffcdic, depth + 1);
        }
    }
    return ret;
}
//  [c]
static CURLcode pop3_parse_url_path(struct connectdata *conn)
{
  /* the pop3 struct is already inited in pop3_connect() */
  struct pop3_conn *pop3c = &conn->proto.pop3c;
  struct SessionHandle *data = conn->data;
  const char *path = data->state.path;

  /* url decode the path and use this mailbox */
  return Curl_urldecode(data, path, 0, &pop3c->mailbox, NULL, TRUE);
}
//  [c]
static CURLcode pop3_parse_url_path(struct connectdata *conn)
{
  /* the pop3 struct is already inited in pop3_connect() */
  struct pop3_conn *pop3c = &conn->proto.pop3c;
  struct SessionHandle *data = conn->data;
  const char *path = data->state.path;

  /* url decode the path and use this mailbox */
  pop3c->mailbox = curl_easy_unescape(data, path, 0, NULL);
  if(!pop3c->mailbox)
    return CURLE_OUT_OF_MEMORY;

  return CURLE_OK;
}
//  [c]
static int ipxitf_ioctl(unsigned int cmd, void __user *arg)
{
	int rc = -EINVAL;
	struct ifreq ifr;
	int val;

	switch (cmd) {
	case SIOCSIFADDR: {
		struct sockaddr_ipx *sipx;
		struct ipx_interface_definition f;

		rc = -EFAULT;
		if (copy_from_user(&ifr, arg, sizeof(ifr)))
			break;
		sipx = (struct sockaddr_ipx *)&ifr.ifr_addr;
		rc = -EINVAL;
		if (sipx->sipx_family != AF_IPX)
			break;
		f.ipx_network = sipx->sipx_network;
		memcpy(f.ipx_device, ifr.ifr_name,
			sizeof(f.ipx_device));
		memcpy(f.ipx_node, sipx->sipx_node, IPX_NODE_LEN);
		f.ipx_dlink_type = sipx->sipx_type;
		f.ipx_special = sipx->sipx_special;

		if (sipx->sipx_action == IPX_DLTITF)
			rc = ipxitf_delete(&f);
		else
			rc = ipxitf_create(&f);
		break;
	}
	case SIOCGIFADDR: {
		struct sockaddr_ipx *sipx;
		struct ipx_interface *ipxif;
		struct net_device *dev;

		rc = -EFAULT;
		if (copy_from_user(&ifr, arg, sizeof(ifr)))
			break;
		sipx = (struct sockaddr_ipx *)&ifr.ifr_addr;
		dev  = __dev_get_by_name(&init_net, ifr.ifr_name);
		rc   = -ENODEV;
		if (!dev)
			break;
		ipxif = ipxitf_find_using_phys(dev,
					   ipx_map_frame_type(sipx->sipx_type));
		rc = -EADDRNOTAVAIL;
		if (!ipxif)
			break;

		sipx->sipx_family	= AF_IPX;
		sipx->sipx_network	= ipxif->if_netnum;
		memcpy(sipx->sipx_node, ipxif->if_node,
			sizeof(sipx->sipx_node));
		rc = 0;
		if (copy_to_user(arg, &ifr, sizeof(ifr)))
			rc = -EFAULT;
		ipxitf_put(ipxif);
		break;
	}
	case SIOCAIPXITFCRT:
		rc = -EFAULT;
		if (get_user(val, (unsigned char __user *) arg))
			break;
		rc = 0;
		ipxcfg_auto_create_interfaces = val;
		break;
	case SIOCAIPXPRISLT:
		rc = -EFAULT;
		if (get_user(val, (unsigned char __user *) arg))
			break;
		rc = 0;
		ipxcfg_set_auto_select(val);
		break;
	}

	return rc;
}
//  [c]
static int ipxitf_ioctl(unsigned int cmd, void __user *arg)
{
	int rc = -EINVAL;
	struct ifreq ifr;
	int val;

	switch (cmd) {
	case SIOCSIFADDR: {
		struct sockaddr_ipx *sipx;
		struct ipx_interface_definition f;

		rc = -EFAULT;
		if (copy_from_user(&ifr, arg, sizeof(ifr)))
			break;
		sipx = (struct sockaddr_ipx *)&ifr.ifr_addr;
		rc = -EINVAL;
		if (sipx->sipx_family != AF_IPX)
			break;
		f.ipx_network = sipx->sipx_network;
		memcpy(f.ipx_device, ifr.ifr_name,
			sizeof(f.ipx_device));
		memcpy(f.ipx_node, sipx->sipx_node, IPX_NODE_LEN);
		f.ipx_dlink_type = sipx->sipx_type;
		f.ipx_special = sipx->sipx_special;

		if (sipx->sipx_action == IPX_DLTITF)
			rc = ipxitf_delete(&f);
		else
			rc = ipxitf_create(&f);
		break;
	}
	case SIOCGIFADDR: {
		struct sockaddr_ipx *sipx;
		struct ipx_interface *ipxif;
		struct net_device *dev;

		rc = -EFAULT;
		if (copy_from_user(&ifr, arg, sizeof(ifr)))
			break;
		sipx = (struct sockaddr_ipx *)&ifr.ifr_addr;
		dev  = __dev_get_by_name(&init_net, ifr.ifr_name);
		rc   = -ENODEV;
		if (!dev)
			break;
		ipxif = ipxitf_find_using_phys(dev,
					   ipx_map_frame_type(sipx->sipx_type));
		rc = -EADDRNOTAVAIL;
		if (!ipxif)
			break;

		sipx->sipx_family	= AF_IPX;
		sipx->sipx_network	= ipxif->if_netnum;
		memcpy(sipx->sipx_node, ipxif->if_node,
			sizeof(sipx->sipx_node));
		rc = -EFAULT;
		if (copy_to_user(arg, &ifr, sizeof(ifr)))
			break;
		ipxitf_put(ipxif);
		rc = 0;
		break;
	}
	case SIOCAIPXITFCRT:
		rc = -EFAULT;
		if (get_user(val, (unsigned char __user *) arg))
			break;
		rc = 0;
		ipxcfg_auto_create_interfaces = val;
		break;
	case SIOCAIPXPRISLT:
		rc = -EFAULT;
		if (get_user(val, (unsigned char __user *) arg))
			break;
		rc = 0;
		ipxcfg_set_auto_select(val);
		break;
	}

	return rc;
}