Exemple #1
0
/*
 * Recieves HTTP request from a client connected over socket and sends
 * back requested resource.
 */
static int respond(int socket) {
    char rec_msg[99999];
    char* request[3];
    char* reqline;
    int bytes_rec, bytes_sent;
    
    memset(rec_msg, 0, sizeof(rec_msg));

    bytes_rec = recv(socket, rec_msg, sizeof(rec_msg), 0);
    printf("Msg: %d\n%s\n", bytes_rec, rec_msg);

    reqline = strtok(rec_msg, "\n");
    request[0] = strtok(reqline, " \t");
    request[1] = strtok(NULL, " \t");
    request[2] = strtok(NULL, " \t");
    char* http10 = "HTTP/1.0";
    char* http11 = "HTTP/1.1";

    if (strncmp(request[2], http10, strlen(http10)) != 0
            && strncmp(request[2], http11, strlen(http11)) != 0) {
        bytes_sent = send_all(socket, "HTTP/1.0 400 Bad Request\n");
    } else {
        printf("Request type: %s\n", request[0]);
        if (strncmp(request[0], "GET", 3) == 0) {
            get_req(socket, request[1]);
        } else {
            bytes_sent = send_all(socket, "Only supports GET\n");
        }
    }

    return bytes_sent;
}
Exemple #2
0
static void
main_loop ()
{
  DDEV_REQ		req;	/* 受信する要求パケット */
  ER			err;
  extern ER		sys_errno;

  /*
   * 要求受信 - 処理のループ
   */
  for (;;)
    {
      W	rsize;

      /* 要求の受信 */
/*      dbg_printf ("call get_req ()\n"); */
      rsize = sizeof (req);
      get_req (recvport, &req, &rsize);
      switch (sys_errno)
	{
	case E_OK:
	  /* 正常ケース */
/*	  dbg_printf ("console: receive packet type = %d\n", req.header.msgtyp);	/* */
	  doit (&req);
	  break;

	default:
	  /* Unknown error */
	  dbg_printf ("CONSOLE: get_req() Unknown error(error = %d)\n", err);
	  break;
	}
    }

  /* ここの行には、来ない */
}
Exemple #3
0
static int send_inquiry_cmd(struct scsi_device *sdev, int page,
			    struct clariion_dh_data *csdev)
{
	struct request *rq = get_req(sdev, INQUIRY, csdev->buffer);
	int err;

	if (!rq)
		return SCSI_DH_RES_TEMP_UNAVAIL;

	rq->sense = csdev->sense;
	memset(rq->sense, 0, SCSI_SENSE_BUFFERSIZE);
	rq->sense_len = csdev->senselen = 0;

	rq->cmd[0] = INQUIRY;
	if (page != 0) {
		rq->cmd[1] = 1;
		rq->cmd[2] = page;
	}
	err = blk_execute_rq(sdev->request_queue, NULL, rq, 1);
	if (err == -EIO) {
		sdev_printk(KERN_INFO, sdev,
			    "%s: failed to send %s INQUIRY: %x\n",
			    CLARIION_NAME, page?"EVPD":"standard",
			    rq->errors);
		csdev->senselen = rq->sense_len;
		err = SCSI_DH_IO;
	}

	blk_put_request(rq);

	return err;
}
Exemple #4
0
/*
 * プロセスマネージャの main 関数。
 *
 */
int
_main (void)
{
  pm_msg_t	request;

  init_process_manager ();

  banner ();

  /*
   * メッセージの受信 - 処理 - 返答のループ
   */
  for (;;)
    {
      /* メッセージの受信 (get_req は libkernel.a にある関数) */
      if (get_req (recvport, &request, sizeof (request)) > 0)
	{
	  /*
	   * リクエストの処理:返答も doit() で行う。
	   */
	  doit (&request);
	}
      else
	{
	  /* 
	   * 受信でエラーとなった。
	   * エラーとなった原因を reject して、次の要求を受けつける。
	   */
	}
    }
  /* DO NOT REACHED */
}
Exemple #5
0
static void smd_try_to_send(struct diag_context *ctxt)
{
	if (ctxt->ch) {
		int r = smd_read_avail(ctxt->ch);
		if (r > RXN_MAX) {
			printk(KERN_ERR "The SMD data is too large to send (%d) !!\n", r);
//			return;
            r = RXN_MAX;
		}
		if (r > 0) {
			struct diag_request *req = get_req(ctxt, &ctxt->rx_arm9_idle);
			if (!req) {
				printk(KERN_ERR "There is no enough request to ARM11!!\n");
				return;
			}
			smd_read(ctxt->ch, req->buf, r);
			smd_xfer_count_func(r, data_set_rx);
			//req->length = r;
			//printk(KERN_ERR "ARM9 data to ARM11 %s\n", (char *)req->buf);
			req->actual = r;
			put_req(ctxt, &ctxt->rx_arm9_done, req);
			wake_up(&ctxt->read_arm9_wq);
		}
	}
}
Exemple #6
0
int add_write(const char *fname, const char *buf, int size, char flags, function_to_call_t *fun) {
    if (fname) {
        aiob *aio = get_aiob();
        memset(aio, 0, sizeof(aiob));
        int fd = open(fname, flags & 1 ? O_CREAT|O_WRONLY
                : O_CREAT|O_WRONLY|O_APPEND, S_IRWXU|S_IRWXG);
        aio->aio_fildes = fd;
        aio->aio_buf = buf;
        aio->aio_nbytes = size;
        struct request *req = get_req();
        req->aio = aio;
        req->fun = fun;
        req->type = awrite;
        assign_svalue_no_free(&req->tmp, sp-2);
        add_req(req);
#ifdef PACKAGE_COMPRESS
        if(flags & 2)
            return aio_gzwrite(aio);
        else
#endif
            return aio_write(aio);
    } else
        error("permission denied\n");
    return 1;
}
Exemple #7
0
int add_db_exec(int handle, function_to_call_t *fun) {
	struct request *req = get_req();
	req->fun = fun;
	req->type = adbexec;
	req->buf = (char *)handle;
	assign_svalue_no_free(&req->tmp, sp-1);
	return aio_db_exec(req);
}
Exemple #8
0
static int send_cmd(struct scsi_device *sdev, int cmd)
{
	struct request *rq = get_req(sdev, cmd);

	if (!rq)
		return SCSI_DH_RES_TEMP_UNAVAIL;

	return blk_execute_rq(sdev->request_queue, NULL, rq, 1);
}
Exemple #9
0
int add_getdir(const char *fname, function_to_call_t *fun) {
	if (fname) {
		//printf("fname: %s\n", fname);
		struct request *req = get_req();
		req->buf = (char *)MALLOC(sizeof(struct dirent) * max_array_size);
		req->size = sizeof(struct dirent) * max_array_size;
		req->fun = fun;
		req->type = agetdir;
		strcpy(req->path, fname);
		return aio_getdir(req);
	}else
		error("permission denied\n");
	return 1;
}
Exemple #10
0
static int send_trespass_cmd(struct scsi_device *sdev,
			    struct clariion_dh_data *csdev)
{
	struct request *rq;
	unsigned char *page22;
	int err, len, cmd;

	if (csdev->flags & CLARIION_SHORT_TRESPASS) {
		page22 = short_trespass;
		if (!(csdev->flags & CLARIION_HONOR_RESERVATIONS))
			/* Set Honor Reservations bit */
			page22[6] |= 0x80;
		len = sizeof(short_trespass);
		cmd = MODE_SELECT;
	} else {
		page22 = long_trespass;
		if (!(csdev->flags & CLARIION_HONOR_RESERVATIONS))
			/* Set Honor Reservations bit */
			page22[10] |= 0x80;
		len = sizeof(long_trespass);
		cmd = MODE_SELECT_10;
	}
	BUG_ON((len > CLARIION_BUFFER_SIZE));
	memcpy(csdev->buffer, page22, len);

	rq = get_req(sdev, cmd, csdev->buffer);
	if (!rq)
		return SCSI_DH_RES_TEMP_UNAVAIL;

	rq->sense = csdev->sense;
	memset(rq->sense, 0, SCSI_SENSE_BUFFERSIZE);
	rq->sense_len = csdev->senselen = 0;

	err = blk_execute_rq(sdev->request_queue, NULL, rq, 1);
	if (err == -EIO) {
		if (rq->sense_len) {
			err = trespass_endio(sdev, csdev->sense);
		} else {
			sdev_printk(KERN_INFO, sdev,
				    "%s: failed to send MODE SELECT: %x\n",
				    CLARIION_NAME, rq->errors);
		}
	}

	blk_put_request(rq);

	return err;
}
Exemple #11
0
void* thread_consumer() {
	req_t req_d;
	int ressz, req_i;
	snfs_msg_res_t res;
	
	while(1) {
		sthread_monitor_enter(mon);
		// get request from queue
		while (!available_reqs) sthread_monitor_wait(mon);
		
		req_d = get_req();
		available_reqs--;
		sthread_monitor_signal(mon); 
		sthread_monitor_exit(mon); 

		
		// clean response
		memset(&res,0,sizeof(res));
		
		// find request handler
		req_i = -1;
		for (int i = 0; i < NUM_REQ_HANDLERS; i++) {
			if (req_d->req.type == Service[i].type) {
				req_i = i;
				break;
			}
		}

      		// serve the request
		if (req_i == -1) {
			res.status = RES_UNKNOWN;
			ressz = sizeof(res) - sizeof(res.body);
			printf("[snfs_srv] unknown request.\n");
		} else {
			Service[req_i].handler(&(req_d->req),req_d->reqsz,&res,&ressz);
		}

      		// send response to client
		srv_send_response(&res,ressz,&(req_d->cliaddr),req_d->clilen);
		
		// free stuff
		free(req_d); req_d = NULL;
		
		// force request processing
		sthread_yield();
	}
}
Exemple #12
0
int add_read(const char *fname, function_to_call_t *fun) {
	if (fname) {
		struct request *req = get_req();
		//printf("fname: %s\n", fname);
		req->buf = (char *)MALLOC(READ_FILE_MAX_SIZE);
		req->size = READ_FILE_MAX_SIZE;
		req->fun = fun;
		req->type = aread;
		strcpy(req->path, fname);
#ifdef PACKAGE_COMPRESS
		return aio_gzread(req);
#else
		return aio_read(req);
#endif
	}else
		error("permission denied\n");
	return 1;
}
Exemple #13
0
int add_getdir(const char *fname, function_to_call_t *fun) {
    if (fname) {
        aiob *aio= get_aiob();
        memset(aio, 0, sizeof(aiob));
        //printf("fname: %s\n", fname);
        int fd = open(fname, O_RDONLY);
        aio->aio_fildes = fd;
        aio->aio_buf = (char *)MALLOC(sizeof(struct dirent) * max_array_size);
        aio->aio_nbytes = sizeof(struct dirent) * max_array_size;
        struct request *req = get_req();
        req->aio = aio;
        req->fun = fun;
        req->type = agetdir;
        add_req(req);
        return aio_getdir(aio);
    }else
        error("permission denied\n");
    return 1;
}
static void diag_unbind(void *_ctxt)
{
	struct diag_context *ctxt = _ctxt;
	struct diag_request *req;

	printk(KERN_DEBUG "diag_unbind()\n");

	smd_xfer_count_func(0,data_set_clear);

	while ((req = get_req(ctxt, &ctxt->rx_arm9_idle))) {
		kfree(req->buf);
        kfree(req);
	}

	ctxt->online = 0;
	ctxt->error = 1;

	/* readers may be blocked waiting for us to go online */
	wake_up(&ctxt->read_arm9_wq);
}
Exemple #15
0
int add_write(const char *fname, const char *buf, int size, char flags, function_to_call_t *fun) {
	if (fname) {
		struct request *req = get_req();
		req->buf = buf;
		req->size = size;
		req->fun = fun;
		req->type = awrite;
		req->flags = flags;
		strcpy(req->path, fname);
		assign_svalue_no_free(&req->tmp, sp-2);
#ifdef PACKAGE_COMPRESS
		if(flags & 2)
			return aio_gzwrite(req);
		else
#endif
			return aio_write(req);
	} else
		error("permission denied\n");
	return 1;
}
static int diag2arm9_release(struct inode *ip, struct file *fp)
{
	struct diag_context *ctxt = &_context;
	struct diag_request *req;

    DBG_OP("+%s\n", __func__);

    diag_configure(0, ctxt);
    
    msm_diag_smd_close();

	/* recycle unhandled rx reqs to user if any */
	while ((req = get_req(ctxt, &ctxt->rx_arm9_done)))
		put_req(ctxt, &ctxt->rx_arm9_idle, req);

    /* Release readers that might be blocked */
	wake_up(&ctxt->read_arm9_wq);

	_unlock(&ctxt->open_arm9_excl);

    DBG_OP("-%s\n", __func__);
	return 0;
}
Exemple #17
0
int add_read(const char *fname, function_to_call_t *fun) {
    if (fname) {
        aiob *aio = get_aiob();
        memset(aio, 0, sizeof(aiob));
        //printf("fname: %s\n", fname);
        int fd = open(fname, O_RDONLY);
        aio->aio_fildes = fd;
        aio->aio_buf = (char *)MALLOC(READ_FILE_MAX_SIZE);
        aio->aio_nbytes = READ_FILE_MAX_SIZE;
        struct request *req = get_req();
        req->aio = aio;
        req->fun = fun;
        req->type = aread;
        add_req(req);
#ifdef PACKAGE_COMPRESS
        return aio_gzread(aio);
#else
        return aio_read(aio);
#endif
    }else
        error("permission denied\n");
    return 1;
}
Exemple #18
0
static int
parse_req(int argc, char **argv)
{
  int idx;
  uint8_t rt = 0;

  for (idx = 0; argc != 0 && idx <= 6; argc--, idx++)
    switch (idx)
      {
      case 0:
	/* dir[ection]: i[n] | o[ut] */
	if (*argv[idx] == 'i')
	  rt |= 0x80;
	else if (*argv[idx] == 'o')
	  /* nop */;
	else
	  {
	    fprintf(stderr, "request direction must be \"in\" or \"out\" (got %s)\n",
		    argv[idx]);
	    return -1;
	  }
	break;

      case 1:
	/* type: s[tandard] | c[lass] | v[endor] */
	if (*argv[idx] == 's')
	  /* nop */;
	else if (*argv[idx] == 'c')
	  rt |= 0x20;
	else if (*argv[idx] == 'v')
	  rt |= 0x40;
	else
	  {
	    fprintf(stderr,
		    "request type must be one of \"standard\", \"class\", or \"vendor\" (got %s)\n",
		    argv[idx]);
	    return -1;
	  }
	break;

      case 2:
	/* rcpt: d[evice], i[nterface], e[ndpoint], o[ther] */
	if (*argv[idx] == 'd')
	  /* nop */;
	else if (*argv[idx] == 'i')
	  rt |= 1;
	else if (*argv[idx] == 'e')
	  rt |= 2;
	else if (*argv[idx] == 'o')
	  rt |= 3;
	else
	  {
	    fprintf(stderr,
		    "recipient must be one of \"device\", \"interface\", \"endpoint\", or \"other\" (got %s)\n",
		    argv[idx]);
	    return -1;
	  }
	setup.bmRequestType = rt;
	break;

      case 3:
	setup.bRequest = get_req(argv[idx]);
	break;

      case 4:
	setup.wValue = strtoul(argv[idx], 0, 0);
	break;

      case 5:
	setup.wIndex = strtoul(argv[idx], 0, 0);
	break;

      case 6:
	setup.wLength = strtoul(argv[idx], 0, 0);
	break;
      }

  return argc;
}
Exemple #19
0
static ssize_t diag2arm9_read(struct file *fp, char __user *buf,
			size_t count, loff_t *pos)
{
	struct diag_context *ctxt = &_context;
	struct diag_request *req;
	int r = 0, xfer;
	int ret;
	//ctxt->isRead = 1;

	DBG("diag2arm9_read(%d)\n", count);
	
	if (_lock(&ctxt->read_arm9_excl))
		return -EBUSY;

	/* we will block until we're offline */
	/*
	while (ctxt->online) {
		ret = wait_event_interruptible(ctxt->read_arm9_wq, !(ctxt->online));
		if (ret < 0) {
			_unlock(&ctxt->read_arm9_excl);
			return ret;
		}
	}
	*/
	while (count > 0) {
		/*
		if (ctxt->error) {
			r = -EIO;
			break;
		}
		*/
		/* if we have idle read requests, get them queued */
		/*
		while ((req = get_req(ctxt, &ctxt->rx_idle))) {
requeue_req:
			req->length = TXN_MAX;
			ret = usb_ept_queue_xfer(ctxt->out, req);
			if (ret < 0) {
				DBG("diag_read: failed to queue req %p (%d)\n", req, ret);
				r = -EIO;
				ctxt->error = 1;
				put_req(ctxt, &ctxt->rx_idle, req);
				goto fail;
			} else {
				DBG("rx %p queue\n", req);
			}
		}
		*/
		
		/* if we have data pending, give it to userspace */
		if (ctxt->read_arm9_count > 0) {
			xfer = (ctxt->read_arm9_count < count) ? ctxt->read_arm9_count : count;
			if (copy_to_user(buf, ctxt->read_arm9_buf, xfer)) {
				DBG("diag: copy_to_user fail\n");
				r = -EFAULT;
				break;
			}
			ctxt->read_arm9_buf += xfer;
			ctxt->read_arm9_count -= xfer;
			buf += xfer;
			count -= xfer;
			r += xfer;

			/* if we've emptied the buffer, release the request */
			if (ctxt->read_arm9_count == 0) {
				put_req(ctxt, &ctxt->rx_arm9_idle, ctxt->read_arm9_req);
				ctxt->read_arm9_req = 0;
			}
			continue;
		}

		/* wait for a request to complete */
		req = 0;
		ret = wait_event_interruptible(ctxt->read_arm9_wq,
					       ((req = get_req(ctxt, &ctxt->rx_arm9_done)) || ctxt->error));

		if (req != 0) {
			/* if we got a 0-len one we need to put it back into
			** service.  if we made it the current read req we'd
			** be stuck forever
			*/
			if (req->actual == 0) {
			//	goto requeue_req;
				put_req(ctxt, &ctxt->rx_arm9_idle, req);
				continue;
			}

			ctxt->read_arm9_req = req;
			ctxt->read_arm9_count = req->actual;
			ctxt->read_arm9_buf = req->buf;
			if (ctxt->read_arm9_count < count)
				count = ctxt->read_arm9_count;
			DBG("rx %p %d\n", req, req->actual);
		}

		if (ret < 0) {
            DBG_OP("%s: ret < 0\n", __func__);
			r = ret;
			break;
		}
	}

//fail:
	_unlock(&ctxt->read_arm9_excl);
	//ctxt->isRead = 0;
	return r;
}
Exemple #20
0
// Attempt to get html page from http server.
bool project3::Http::httpGetRawHtml(const std::vector<std::string> &token, 
								 	std::vector<unsigned char> &raw_html)
{
	bool ret = false;

	if(token.empty() && token[0].empty())
	{
		#if DEBUG == 1
			Logger::instance().log("URI cannot be empty.",
									project3::Logger::m_logLevelError);
		#endif

		return ret;
	}

	std::string url;

	if(token[1].empty())
	{
		url = "http://";
		url.append(token[0]);
	}
	else
	{
		url = token[0];
	}

	// Prepare GET request.
	std::string get_req("GET ");
	get_req.append(url);
	get_req.append(" HTTP/1.0 \r\n\r\n");

	// Send GET request.
	int bytes_sent;
	if((bytes_sent = send(m_sockfd, get_req.c_str(), get_req.length(), 0)) < 0)
	{
		#if DEBUG == 1

			std::string err_msg;

			if(ECONNRESET == errno)
			{
				err_msg = "The connection was reset by the server.";
			}
			else if(EINTR == errno)
			{
				err_msg = "An interrupt signal occured.";
			}
			else if(EINVAL == errno)
			{
				err_msg = "Invalid argument passed.";
			}
			else if(ENOTCONN == errno)
			{
				err_msg = "The socket is not connected.";
			}
			else if(ENOMEM == errno)
			{
				err_msg = "No memory available.";
			}

			Logger::instance().log(err_msg,
									project3::Logger::m_logLevelError);
		#endif

		return ret;
	}

	// Get default socket SO_RCVBUF size.
	int sock_rcvbufval;
	unsigned int sock_rcvbufvalsze = sizeof(sock_rcvbufval);
	getsockopt(m_sockfd, SOL_SOCKET, SO_RCVBUF, &sock_rcvbufval, &sock_rcvbufvalsze);

	// Store receiving data to local copy vector.
	std::vector<unsigned char> buf(RCV_BUF_SZE, '0');
	int bytes_recv;
	int total_bytes_recv = 0;

	// Begin receiving data from http server.
	while(true)
	{
		if((bytes_recv = recv(m_sockfd, &(buf)[0], buf.size(), MSG_WAITALL)) < 0)
		{
			#if DEBUG == 1

				std::string err_msg;

				if(ECONNREFUSED == errno)
				{
					err_msg = "The web server is not listening on port number 80.";
				}
				else if(EINTR == errno)
				{
					err_msg = "An interrupt occured while receiving packets.";
				}

				Logger::instance().log(err_msg,
										project3::Logger::m_logLevelError);
			#endif

			return ret;
		}
		else if(bytes_recv == 0)
		{
			break;
		}
		else
		{
			total_bytes_recv += bytes_recv;

			// Make exclusive copy of retruned http character stream for this object.
			std::copy(buf.cbegin(), 
					  buf.cend(), 
					  std::back_inserter(raw_html));
		}
	}

	// Resize caller char vector.
	raw_html.resize(total_bytes_recv);

	// The GET request was successful.
	return true;
}
static ssize_t diag2arm9_read(struct file *fp, char __user *buf,
			size_t count, loff_t *pos)
{
	struct diag_context *ctxt = &_context;
	struct diag_request *req;
	int r = 0, xfer;
	int ret;

	DBG("diag2arm9_read(%d)\n", count);
	
	if (_lock(&ctxt->read_arm9_excl))
		return -EBUSY;

	while (count > 0) {
		
		/* if we have data pending, give it to userspace */
		if (ctxt->read_arm9_count > 0) {
			xfer = (ctxt->read_arm9_count < count) ? ctxt->read_arm9_count : count;
			if (copy_to_user(buf, ctxt->read_arm9_buf, xfer)) {
				DBG("diag: copy_to_user fail\n");
				r = -EFAULT;
				break;
			}
			ctxt->read_arm9_buf += xfer;
			ctxt->read_arm9_count -= xfer;
			buf += xfer;
			count -= xfer;
			r += xfer;

			/* if we've emptied the buffer, release the request */
			if (ctxt->read_arm9_count == 0) {
				put_req(ctxt, &ctxt->rx_arm9_idle, ctxt->read_arm9_req);
				ctxt->read_arm9_req = 0;
			}
			continue;
		}

		/* wait for a request to complete */
		req = 0;
		ret = wait_event_interruptible(ctxt->read_arm9_wq,
					       ((req = get_req(ctxt, &ctxt->rx_arm9_done)) || ctxt->error));

		if (req != 0) {
			/* if we got a 0-len one we need to put it back into
			** service.  if we made it the current read req we'd
			** be stuck forever
			*/
			if (req->actual == 0) {
				put_req(ctxt, &ctxt->rx_arm9_idle, req);
				continue;
			}

			ctxt->read_arm9_req = req;
			ctxt->read_arm9_count = req->actual;
			ctxt->read_arm9_buf = req->buf;
			if (ctxt->read_arm9_count < count)
				count = ctxt->read_arm9_count;
			DBG("rx %p %d\n", req, req->actual);
		}

		if (ret < 0) {
            DBG_OP("%s: ret < 0\n", __func__);
			r = ret;
			break;
		}
	}

	_unlock(&ctxt->read_arm9_excl);
	return r;
}
Exemple #22
0
void MediaThread::run()
{
	const char *url = url_.c_str();
	ic_ = 0;

	int rc = avformat_open_input(&ic_, url, 0, 0);
	if (rc < 0) {
		fprintf(stderr, "ERR: avformat_open_input can't open %s\n", url);
		return;
	}

	rc = avformat_find_stream_info(ic_, 0);
	if (rc < 0) {
		fprintf(stderr, "ERR: avformat_find_stream_info fault!\n");
		avformat_close_input(&ic_);
		return;
	}

	av_dump_format(ic_, -1, url, 0);

	for (int i = 0; i < ic_->nb_streams; i++) {
		AVCodecContext *ctx = ic_->streams[i]->codec;
		AVCodec *codec = avcodec_find_decoder(ctx->codec_id);
		if (!codec) {
			fprintf(stderr, "ERR: avcodec_find_decoder NOT find %d\n", ctx->codec_id);
			avformat_close_input(&ic_);
			return;
		}

		avcodec_open2(ctx, codec, 0);
	}

	bool err = false;
	AVFrame *frame = av_frame_alloc();

	while (1) {
		int code;
		if (chk_req(0, &code)) {
			if (code == 0) {
				reply(0);
                break;
			}
		}

		if (err) {
			code = get_req();
			if (code == 0) {
				reply(0);
				break;
			}
		}
		else {
			AVPacket pkg;
			rc = av_read_frame(ic_, &pkg);
			if (rc < 0) {
				err = true;
				continue;
			}

			int got;
			do {
				got = decode_frame(frame, &pkg);
				if (got) {
					dr_->save_video_frame(frame);
				}
			} while (got);

			av_free_packet(&pkg);
		}
	}

	avformat_close_input(&ic_);
	av_frame_free(&frame);
}