Ejemplo n.º 1
0
int DINO_EXPORT response_printf(DHANDLE dhandle, const char *fmt, ...) {
    // Points to each unnamed arg in turn
    //
    va_list ap;

    // make ap point to 1st unnamed arg
    //
    va_start(ap, fmt);

    char *result = NULL;
    if (vasprintf(&result, fmt, ap) > 0) {
        if (NULL != result) {
            // now call the send method
            //
            response_send(dhandle, result, strlen(result));

            // Free the memory
            memory_free(result);
        }
    }

    // clean up when done
    //
    va_end(ap);

    return 0;
}
static void
handle_image_load(int wfd, void *params)
{
   Slave_Msg_Image_Load *load_args = params;
   Slave_Msg_Image_Loaded resp;
   Error_Type err;
   const char *shmfile;
   const char *file, *key, *loader;

   if (!load_args->has_loader_data)
     {
        error_send(wfd, CSERVE2_UNKNOWN_FORMAT);
        return;
     }

   memset(&resp, 0, sizeof(resp));

   shmfile = ((const char *)params) + sizeof(Slave_Msg_Image_Load);
   file = shmfile + strlen(shmfile) + 1;
   key = file + strlen(file) + 1;
   loader = key + strlen(key) + 1;
   if ((err = image_load(file, key, shmfile, load_args, &resp, loader))
       != CSERVE2_NONE)
     {
        error_send(wfd, err);
        return;
     }

   response_send(wfd, IMAGE_LOAD, &resp, sizeof(resp));
}
Ejemplo n.º 3
0
static void
handle_image_open(int wfd, void *params)
{
   Slave_Msg_Image_Open *p;
   Slave_Msg_Image_Opened result;
   Error_Type err;
   const char *loader = NULL, *file, *key, *ptr;
   char *resp;
   size_t resp_size;

   p = params;
   file = (const char *)(p + sizeof(Slave_Msg_Image_Open));
   key = file + strlen(file) + 1;
   ptr = key + strlen(key) + 1;
   if (p->has_loader_data)
     loader = ptr;

   memset(&result, 0, sizeof(result));
   if ((err = image_open(file, key, &result, &loader))
       != CSERVE2_NONE)
     {
        printf("OPEN failed at %s:%d\n", __FUNCTION__, __LINE__);
        error_send(wfd, err);
        return;
     }

   result.has_loader_data = EINA_TRUE;

   resp_size = sizeof(Slave_Msg_Image_Opened) + sizeof(int) + strlen(loader) + 1;
   resp = alloca(resp_size);
   memcpy(resp, &result, sizeof(Slave_Msg_Image_Opened));
   memcpy(resp + sizeof(Slave_Msg_Image_Opened), loader, strlen(loader) + 1);
   response_send(wfd, IMAGE_OPEN, resp, resp_size);
}
Ejemplo n.º 4
0
int main(int argc, char const *argv[])
{
    list_t * colaboradores = NULL;
    list_t * retiradas = NULL;
    list_t * relatorio = list_blank_list();
    node_t * node = NULL;
    colaborador_t * colaborador = NULL;
    retirada_t * retirada = NULL;
    char buffer[500];
    unsigned int colaborador_id = 0;
    char * tipo_relatorio = NULL;
    request_t * request = NULL;
    response_t * response = response_empty(NULL);
    var_t * var = NULL;
    error_t error = ERROR_NULL;
    unsigned int user_id;
    unsigned char user_level;

    request_process(&request);

    login_info(request, &user_id, &user_level);

    if (user_level > ANONYMOUS)
    {
        node = request->GET->first;
        while (node != NULL)
        {
            var = (var_t *) node->data;

            if (strcmp(var->name, "por") == 0)
            {
                tipo_relatorio = var->value;
            }

            if (strcmp(var->name, "colaboradorid") == 0)
            {
                colaborador_id = atoi(var->value);
            }

            node = node->next;
        }

        colaboradores_load(&colaboradores, NULL);
        retiradas_load(&retiradas, NULL);

        if (strcmp(tipo_relatorio, "item") == 0)
        {
            process_report(&relatorio, retiradas, 0);

            login_refresh_session(&response, user_id, user_level);
            response_write_template(&response, "templates/header.html");
            response_write_template(&response, "templates/relatorios_item.html");

            if (relatorio->first == NULL)
            {
                response_write(&response, "<p>Não existe informações para serem exibidas</p>");
            }
            else
            {
                response_write(&response, "<table class=\"table table-bordered table-striped\">"
                               "<tr><th>Item</th><th>Retirado por</th><th>Data da última retirada</th>"
                               "<th>Quantidade restante</th></tr>");
                node = relatorio->first;
                while (node != NULL)
                {
                    retirada = (retirada_t *) node->data;
                    sprintf(buffer,
                            "<tr><td>%s</td><td>%s</td><td>%s</td><td class=\"quantidade\">%u</td></tr>",
                            retirada->item->nome,
                            retirada->colaborador->nome,
                            retirada->data,
                            retirada->item->quantidade);
                    response_write(&response, buffer);
                    retirada_free(&retirada);
                    node = node->next;
                }
                response_write(&response, "</table>");
            }

            response_write(&response, "<script src=\"/js/relatorios.js\"></script>");
            response_write_template(&response, "templates/footer.html");
        }
        else if (strcmp(tipo_relatorio, "colaborador") == 0)
        {
            if (colaborador_id > 0)
            {
                process_report(&relatorio, retiradas, colaborador_id);
            }

            login_refresh_session(&response, user_id, user_level);
            response_write_template(&response, "templates/header.html");
            response_write_template(&response, "templates/relatorios_colaborador.html");

            if (colaborador_id > 0)
            {
                if (relatorio->first == NULL)
                {
                    response_write(&response, "<p>Não existe informações para serem exibidas</p>");
                }
                else
                {
                    response_write(&response, "<table class=\"table table-bordered table-striped\">"
                                   "<tr><th>Item</th><th>Retirado por</th><th>Data da última retirada</th>"
                                   "<th>Quantidade restante</th></tr>");
                    node = relatorio->first;
                    while (node != NULL)
                    {
                        retirada = (retirada_t *) node->data;
                        sprintf(buffer,
                                "<tr><td>%s</td><td>%s</td><td>%s</td><td class=\"quantidade\">%u</td></tr>",
                                retirada->item->nome,
                                retirada->colaborador->nome,
                                retirada->data,
                                retirada->item->quantidade);
                        response_write(&response, buffer);
                        retirada_free(&retirada);
                        node = node->next;
                    }
                    response_write(&response, "</table>");
                }
            }
            else
            {
                response_write(&response, "<p id=\"message\">Para ver o relatório selecione um colaborador acima e aperte \"Ver relatório\"</p>");
            }

            response_write(&response, "<script>var colaboradores = [");

            node = colaboradores->first;
            while (node != NULL)
            {
                colaborador = (colaborador_t *) node->data;
                sprintf(buffer,
                        "{ id: %u, nome: \"%s\" },",
                        colaborador->id,
                        colaborador->nome);
                response_write(&response, buffer);
                colaborador_free(&colaborador);
                node = node->next;
            }

            response_write(&response, "];</script>");

            response_write(&response, "<script src=\"/js/relatorios.js\"></script>");
            response_write(&response, "<script src=\"/js/relatorios_colaborador.js\"></script>");
            response_write_template(&response, "templates/footer.html");
        }
        else
        {
            error = ERROR_RELATORIO_INVALIDO;
        }

        if (error != ERROR_NULL)
        {
            if (error == ERROR_RELATORIO_INVALIDO)
            {
                sprintf(buffer, "/cgi-bin/relatorios?por=item");
            }
            else
            {
                sprintf(buffer, "/cgi-bin/relatorios?por=%s", tipo_relatorio);
            }

            error_page(&response, error, buffer);
        }
    }
    else
    {
        error_page(&response, ERROR_LOGIN_REQUIRED, "/");
    }

    response_send(response);

    request_free(request);

    return 0;
}
Ejemplo n.º 5
0
static int serviceConnection2(
	http_server srv,
	connection conn,
	http_request request,
	http_response response,
	meta_error e)
{
	dynamic_page dp;
	size_t cbSent;
	int status, error = 0;
	size_t max_posted_content = http_server_get_post_limit(srv);

	while(!http_server_shutting_down(srv)) { 
		if(!data_on_socket(conn)) 
			return set_tcpip_error(e, EAGAIN); 

		/* Were we able to read a valid http request? 
		 * If not, what is the cause of the error? If it is a http 
		 * protocol error, we try to send a response back to the client
		 * and close the connection. If it is anything else(tcp/ip, os)
		 * we stop processing. 
		 */
		error = !request_receive(request, conn, max_posted_content, e);

		/* So far, so good. We have a valid HTTP request.
		 * Now see if we can locate a page handler function for it.
		 * If we do, call it. If not, see if it on disk or if the
		 * http_server has a default page handler. If neither is true,
		 * then the page was not found(404).
		 */
		if(error)
			;
		else if( (dp = http_server_lookup(srv, request)) != NULL) {
			if(!handle_dynamic(srv, dp, request, response, e)) {
				error = 1;
			}
		}
		else if(http_server_can_read_files(srv)) {
			if(!send_disk_file(srv, conn, request, response, e)) {
				error = 1;
			}
		}
		else if(http_server_has_default_page_handler(srv)) {
			if(!http_server_run_default_page_handler(srv, request, response, e)) {
				error = 1;
			}
		}
		else {
			/* We didn't find the page */
			response_set_status(response, HTTP_404_NOT_FOUND);
			response_set_connection(response, "close");
		}

		if(error) {
			if(is_protocol_error(e)) {
				status = get_error_code(e);
				response_set_status(response, status);
				response_set_connection(response, "close");
				cbSent = response_send(response, conn, e);
				http_server_add_logentry(srv, conn, request, status, cbSent);
			}

			return 0;
		}

		/*
		 * Some extra stuff for HTTP 1.0 clients. If client is 1.0
		 * and connection_close() == 1 and connection header field
		 * isn't set, then we set the connection flag to close.
		 * Done so that 1.0 clients (Lynx) can detect closure.
		 */
		if(request_get_version(request) != VERSION_11
		&& !connection_is_persistent(conn)
		&& strlen(response_get_connection(response)) == 0) 
			response_set_connection(response, "close");
		
		cbSent = response_send(response, conn, e);
		http_server_add_logentry(srv, conn, request, response_get_status(response), cbSent);
		if(cbSent == 0)
			return 0;

		/* Did the user set the Connection header field to "close" */
		if(strcmp(response_get_connection(response), "close") == 0)
			return 1;

		if(!connection_is_persistent(conn))
			return 1;

		/**
		 * NOTE: Her må/bør vi legge inn ny funksjonalitet:
		 * Disconnect connections som 
		 * a) Har kjørt lengst i tid
		 * b) Har overført mest bytes (opp eller ned)
		 * eller c) har dårligst transfer rate
		 * Grunnen er at dersom vi har n worker threads og n 
		 * persistent connections, havner alle nye connections i kø.
		 * De får aldri kjøretid. Så disconnect-regelen over gjelder derfor
		 * kun om køen har > 0 entries. 
		 */

		connection_flush(conn);
		request_recycle(request);
		response_recycle(response);
	}

	/* Shutdown detected */
	return 1;
}
static Eina_Bool
error_send(int fd, Error_Type err)
{
   return response_send(fd, ERROR, &err, sizeof(Error_Type));
}
Ejemplo n.º 7
0
static void on_packet_received(serial_dfu_t * p_dfu)
{
    nrf_dfu_req_t       dfu_req;
    nrf_dfu_res_t       dfu_res = {{{0}}};

    serial_dfu_response_t serial_response;

    memset(&dfu_req, 0, sizeof(nrf_dfu_req_t));

    const serial_dfu_op_code_t op_code             = (serial_dfu_op_code_t)p_dfu->recv_buffer[0];
    const uint16_t             packet_payload_len  = p_dfu->slip.current_index - 1;
    uint8_t * p_payload                            = &p_dfu->recv_buffer[1];

    serial_response.op_code = op_code;

    nrf_gpio_pin_clear(CONNECTED_LED_PIN_NO);
    nrf_gpio_pin_set(AVAILABLE_LED_PIN_NO);

    switch (op_code)
    {
        case SERIAL_DFU_OP_CODE_CREATE_OBJECT:

            if (packet_payload_len != CREATE_OBJECT_REQUEST_LEN)
            {
                serial_response.resp_val = NRF_DFU_RES_CODE_INVALID_PARAMETER;
                break;
            }

            NRF_LOG_DEBUG("Received create object\r\n");

            // Reset the packet receipt notification on create object
            p_dfu->pkt_notif_target_count = p_dfu->pkt_notif_target;

            // Get type parameter
            dfu_req.obj_type    =  p_payload[0];

            // Get length value
            dfu_req.object_size = uint32_decode(&p_payload[1]);

            // Set req type
            dfu_req.req_type        = NRF_DFU_OBJECT_OP_CREATE;

            serial_response.resp_val = nrf_dfu_req_handler_on_req(NULL, &dfu_req, &dfu_res);
            break;

        case SERIAL_DFU_OP_CODE_SET_RECEIPT_NOTIF:
            NRF_LOG_DEBUG("Set receipt notif\r\n");
            if (packet_payload_len != SET_RECEIPT_NOTIF_REQUEST_LEN)
            {
                serial_response.resp_val = NRF_DFU_RES_CODE_INVALID_PARAMETER;
                break;
            }

            p_dfu->pkt_notif_target = uint16_decode(&p_payload[0]);
            p_dfu->pkt_notif_target_count   = p_dfu->pkt_notif_target;

            serial_response.resp_val = NRF_DFU_RES_CODE_SUCCESS;
            break;

        case SERIAL_DFU_OP_CODE_CALCULATE_CRC:
            NRF_LOG_DEBUG("Received calculate CRC\r\n");

            dfu_req.req_type     =  NRF_DFU_OBJECT_OP_CRC;

            serial_response.resp_val = nrf_dfu_req_handler_on_req(NULL, &dfu_req, &dfu_res);
            serial_response.crc_response.offset = dfu_res.offset;
            serial_response.crc_response.crc    = dfu_res.crc;
            break;

        case SERIAL_DFU_OP_CODE_EXECUTE_OBJECT:
            NRF_LOG_DEBUG("Received execute object\r\n");

            // Set req type
            dfu_req.req_type     =  NRF_DFU_OBJECT_OP_EXECUTE;

            serial_response.resp_val = nrf_dfu_req_handler_on_req(NULL, &dfu_req, &dfu_res);
            break;

        case SERIAL_DFU_OP_CODE_SELECT_OBJECT:

            NRF_LOG_DEBUG("Received select object\r\n");
            if (packet_payload_len != SELECT_OBJECT_REQUEST_LEN)
            {
                serial_response.resp_val = NRF_DFU_RES_CODE_INVALID_PARAMETER;
                break;
            }

            // Set object type to read info about
            dfu_req.obj_type = p_payload[0];

            dfu_req.req_type = NRF_DFU_OBJECT_OP_SELECT;

            serial_response.resp_val = nrf_dfu_req_handler_on_req(NULL, &dfu_req, &dfu_res);
            serial_response.select_response.max_size = dfu_res.max_size;
            serial_response.select_response.offset   = dfu_res.offset;
            serial_response.select_response.crc      = dfu_res.crc;
            break;

        case SERIAL_DFU_OP_CODE_GET_SERIAL_MTU:
            NRF_LOG_DEBUG("Received get serial mtu\r\n");

            serial_response.resp_val = NRF_DFU_RES_CODE_SUCCESS;
            serial_response.serial_mtu_response.mtu = sizeof(p_dfu->recv_buffer);
            break;

        case SERIAL_DFU_OP_CODE_WRITE_OBJECT:
             // Set req type
            dfu_req.req_type =  NRF_DFU_OBJECT_OP_WRITE;

            // Set data and length
            dfu_req.p_req    =  &p_payload[0];
            dfu_req.req_len  =  packet_payload_len;

            serial_response.resp_val = nrf_dfu_req_handler_on_req(NULL, &dfu_req, &dfu_res);
            if(serial_response.resp_val != NRF_DFU_RES_CODE_SUCCESS)
            {
                NRF_LOG_ERROR("Failure to run packet write\r\n");
            }

            // Check if a packet receipt notification is needed to be sent.
            if (p_dfu->pkt_notif_target != 0 && --p_dfu->pkt_notif_target_count == 0)
            {
                serial_response.op_code = SERIAL_DFU_OP_CODE_CALCULATE_CRC;
                serial_response.crc_response.offset = dfu_res.offset;
                serial_response.crc_response.crc    = dfu_res.crc;

                // Reset the counter for the number of firmware packets.
                p_dfu->pkt_notif_target_count = p_dfu->pkt_notif_target;
            }
            break;

        default:
            // Unsupported op code.
            NRF_LOG_WARNING("Received unsupported OP code\r\n");
            serial_response.resp_val = NRF_DFU_RES_CODE_INVALID_PARAMETER;
            break;
    }

    if (op_code != SERIAL_DFU_OP_CODE_WRITE_OBJECT)
    {
        response_send(p_dfu, &serial_response);
    }
}
Ejemplo n.º 8
0
/**@brief     Function for handling a Write event on the Control Point characteristic.
 *
 * @param[in] p_dfu             DFU Service Structure.
 * @param[in] p_ble_write_evt   Pointer to the write event received from BLE stack.
 *
 * @return    NRF_SUCCESS on successful processing of control point write. Otherwise an error code.
 */
static uint32_t on_ctrl_pt_write(ble_dfu_t * p_dfu, ble_gatts_evt_write_t * p_ble_write_evt)
{
    nrf_dfu_res_code_t  res_code;
    nrf_dfu_req_t       dfu_req;
    nrf_dfu_res_t       dfu_res = {{{0}}};

    memset(&dfu_req, 0, sizeof(nrf_dfu_req_t));

    switch (p_ble_write_evt->data[0])
    {
        case BLE_DFU_OP_CODE_CREATE_OBJECT:

            if (p_ble_write_evt->len != PKT_CREATE_PARAM_LEN)
            {
                return response_send(p_dfu,
                                     BLE_DFU_OP_CODE_CREATE_OBJECT,
                                     NRF_DFU_RES_CODE_INVALID_PARAMETER);
            }

            NRF_LOG_INFO("Received create object\r\n");

            // Reset the packet receipt notification on create object
            m_pkt_notif_target_cnt = m_pkt_notif_target;

            // Get type parameter
            //lint -save -e415
            dfu_req.obj_type    =  p_ble_write_evt->data[1];
            //lint -restore

            // Get length value
            //lint -save -e416
            dfu_req.object_size = uint32_decode(&(p_ble_write_evt->data[2]));
            //lint -restore

            // Set req type
            dfu_req.req_type        = NRF_DFU_OBJECT_OP_CREATE;

            res_code = nrf_dfu_req_handler_on_req(NULL, &dfu_req, &dfu_res);
            return response_send(p_dfu, BLE_DFU_OP_CODE_CREATE_OBJECT, res_code);

        case BLE_DFU_OP_CODE_EXECUTE_OBJECT:
            NRF_LOG_INFO("Received execute object\r\n");

            // Set req type
            dfu_req.req_type     =  NRF_DFU_OBJECT_OP_EXECUTE;

            res_code = nrf_dfu_req_handler_on_req(NULL, &dfu_req, &dfu_res);
            return response_send(p_dfu, BLE_DFU_OP_CODE_EXECUTE_OBJECT, res_code);

        case BLE_DFU_OP_CODE_SET_RECEIPT_NOTIF:
            NRF_LOG_INFO("Set receipt notif\r\n");
            if (p_ble_write_evt->len != PKT_SET_PRN_PARAM_LEN)
            {
                return (response_send(p_dfu,
                                      BLE_DFU_OP_CODE_SET_RECEIPT_NOTIF,
                                      NRF_DFU_RES_CODE_INVALID_PARAMETER));
            }

            //lint -save -e415
            m_pkt_notif_target = uint16_decode(&(p_ble_write_evt->data[1]));
            //lint -restore
            m_pkt_notif_target_cnt   = m_pkt_notif_target;

            return response_send(p_dfu, BLE_DFU_OP_CODE_SET_RECEIPT_NOTIF, NRF_DFU_RES_CODE_SUCCESS);

        case BLE_DFU_OP_CODE_CALCULATE_CRC:
            NRF_LOG_INFO("Received calculate CRC\r\n");

            dfu_req.req_type     =  NRF_DFU_OBJECT_OP_CRC;

            res_code = nrf_dfu_req_handler_on_req(NULL, &dfu_req, &dfu_res);
            if (res_code == NRF_DFU_RES_CODE_SUCCESS)
            {
                return response_crc_cmd_send(p_dfu, dfu_res.offset, dfu_res.crc);
            }
            else
            {
                return response_send(p_dfu, BLE_DFU_OP_CODE_CALCULATE_CRC, res_code);
            }

        case BLE_DFU_OP_CODE_SELECT_OBJECT:

            NRF_LOG_INFO("Received select object\r\n");
            if (p_ble_write_evt->len != PKT_READ_OBJECT_INFO_PARAM_LEN)
            {
                return response_send(p_dfu,
                                     BLE_DFU_OP_CODE_SELECT_OBJECT,
                                     NRF_DFU_RES_CODE_INVALID_PARAMETER);
            }

            // Set object type to read info about
            //lint -save -e415
            dfu_req.obj_type = p_ble_write_evt->data[1];
            //lint -restore

            dfu_req.req_type = NRF_DFU_OBJECT_OP_SELECT;

            res_code = nrf_dfu_req_handler_on_req(NULL, &dfu_req, &dfu_res);
            if (res_code == NRF_DFU_RES_CODE_SUCCESS)
            {
                return response_select_object_cmd_send(p_dfu, dfu_res.max_size, dfu_res.offset, dfu_res.crc);
            }
            else
            {
                return response_send(p_dfu, BLE_DFU_OP_CODE_SELECT_OBJECT, res_code);
            }

        default:
            NRF_LOG_INFO("Received unsupported OP code\r\n");
            // Unsupported op code.
            return response_send(p_dfu,
                                 p_ble_write_evt->data[0],
                                 NRF_DFU_RES_CODE_INVALID_PARAMETER);
    }
}
Ejemplo n.º 9
0
int main(int argc, char const *argv[])
{
    list_t * list = NULL;
    node_t * node = NULL;
    item_t * item = NULL;
    item_t * novo_item = NULL;
    char buffer[500];
    request_t * request = NULL;
    response_t * response = response_empty(NULL);
    var_t * var = NULL;
    char * query = NULL;
    error_t error = ERROR_NULL;
    unsigned int user_id;
    unsigned char user_level;

    request_process(&request);

    login_info(request, &user_id, &user_level);

    if (user_level > ANONYMOUS)
    {
        node = request->GET->first;
        while (node != NULL)
        {
            var = (var_t *) node->data;

            if (strcmp(var->name, "q") == 0)
            {
                query = var->value;
            }

            node = node->next;
        }

        itens_load(&list, query);

        if (list->last != NULL)
        {
            item = (item_t *) list->last->data;
            last_id = item->id;
        }

        if (request->method == POST)
        {
            novo_item = form_process(request);
            if (novo_item != NULL)
            {
                if (novo_item->id == 0)
                {
                    novo_item->id = ++last_id;
                    list_add(list, novo_item);
                }
                else
                {
                    node = list->first;
                    while (node != NULL)
                    {
                        item = (item_t *) node->data;

                        if (item->id == novo_item->id)
                        {
                            item->quantidade = novo_item->quantidade;
                            item->fim_estoque = novo_item->fim_estoque;
                            break;
                        }

                        node = node->next;
                    }
                }

                itens_save(list);
            }
            else
            {
                error = ERROR_ITEM;
            }
        }

        if (error != ERROR_NULL)
        {
            error_page(&response, error, "/cgi-bin/itens");
        }
        else
        {
            login_refresh_session(&response, user_id, user_level);
            response_write_template(&response, "templates/header.html");
            response_write_template(&response, "templates/itens.html");

            if (list->first == NULL)
            {
                response_write(&response, "<p>Nenhum item encontrado</p>");
            }
            else
            {
                response_write(&response, "<table class=\"table table-bordered table-striped\">"
                    "<tr><th>Id</th><th>Nome</th><th>Tipo</th><th>Descrição</th>"
                    "<th>Quantidade</th><th>Previsão de fim de estoque</th>"
                    "<th class=\"edit\">Ações</th></tr>");
                node = list->first;
                while (node != NULL)
                {
                    item = (item_t *) node->data;
                    sprintf(buffer,
                        "<tr><td>%u</td><td class=\"nome\">%s</td><td class=\"tipo\">%s</td>"
                        "<td class=\"descricao\">%s</td><td class=\"quantidade\">%u</td>"
                        "<td class=\"fimestoque\">%s</td><td class=\"edit\">"
                        "<div class=\"btn-group\">"
                        "<button class=\"btn edit-btn\" data-id=\"%u\"><i class=\"icon-pencil\"></i></button>"
                        "</div>"
                        "</td></tr>",
                        item->id,
                        item->nome,
                        item->tipo,
                        item->descricao,
                        item->quantidade,
                        item->fim_estoque,
                        item->id);
                    response_write(&response, buffer);
                    item_free(&item);
                    node = node->next;
                }
                response_write(&response, "</table>");
            }

            response_write(&response, "<script src=\"/js/itens.js\"></script>");
            response_write_template(&response, "templates/footer.html");
        }
    }
    else
    {
        error_page(&response, ERROR_LOGIN_REQUIRED, "/");
    }

    response_send(response);

    request_free(request);

    return 0;
}