static void program_scheduler_handle_error(ProgramScheduler *program_scheduler,
                                           bool log_as_error, const char *format, ...) {
	va_list arguments;
	char buffer[1024];
	Program *program = containerof(program_scheduler, Program, scheduler);
	String *message;

	va_start(arguments, format);

	vsnprintf(buffer, sizeof(buffer), format, arguments);

	va_end(arguments);

	if (log_as_error) {
		log_error("Scheduler error for program object (identifier: %s) occurred: %s",
		          program->identifier->buffer, buffer);
	} else {
		log_debug("Scheduler error for program object (identifier: %s) occurred: %s",
		          program->identifier->buffer, buffer);
	}

	if (string_wrap(buffer, NULL,
	                OBJECT_CREATE_FLAG_INTERNAL |
	                OBJECT_CREATE_FLAG_LOCKED,
	                NULL, &message) != API_E_SUCCESS) {
		message = NULL;
	}

	program_scheduler_stop(program_scheduler, message);
}
Example #2
0
static bool
ver_done(jose_io_t *io)
{
    io_t *i = containerof(io, io_t, io);
    const json_t *sig = NULL;
    uint8_t *buf = NULL;
    bool ret = false;
    size_t len = 0;

    sig = json_object_get(i->sig, "signature");
    if (!sig)
        return false;

    len = jose_b64_dec(sig, NULL, 0);
    if (len == SIZE_MAX)
        return false;

    buf = malloc(len);
    if (!buf)
        return false;

    if (jose_b64_dec(sig, buf, len) != len) {
        free(buf);
        return false;
    }

    ret = EVP_DigestVerifyFinal(i->emc, buf, len) == 1;
    free(buf);
    return ret;
}
Example #3
0
static void tcp_close_cb(uv_handle_t *handle)
{
    ls_tcp_t    *tcp;
    lua_State   *l, *nl;

    tcp           = containerof(handle, ls_tcp_t, handle);
    l             = ls_default_state();

    if (ls_object_is_waited(&tcp->wait_object))
    {
        int ref = tcp->wait_object.mthread_ref;
        tcp->wait_object.mthread_ref = LUA_NOREF; 
        ls_getref(l, ref);
        nl = lua_tothread(l, -1);
        lua_pop(l, 1);
        if (nl)
        {
            ls_clear_waiting(nl);
            if (LUA_YIELD == lua_status(nl))
                ls_error_resume(nl, LS_ERRCODE_EOF, "tcp closed");
        }
        ls_unref(l, ref);
    }

    ls_free(l, tcp);
}
Example #4
0
void client_destroy(Client *client) {
    bool destroy_pending_requests = false;
    PendingRequest *pending_request;

    if (client->pending_request_count > 0) {
        log_warn("Destroying client ("CLIENT_SIGNATURE_FORMAT") while %d request(s) are still pending",
                 client_expand_signature(client), client->pending_request_count);

        if (network_create_zombie(client) < 0) {
            log_error("Could not create zombie for %d pending request(s) of ("CLIENT_SIGNATURE_FORMAT")",
                      client->pending_request_count, client_expand_signature(client));

            destroy_pending_requests = true;
        }
    }

    writer_destroy(&client->response_writer);

    event_remove_source(client->io->handle, EVENT_SOURCE_TYPE_GENERIC);
    io_destroy(client->io);
    free(client->io);

    if (destroy_pending_requests) {
        while (client->pending_request_sentinel.next != &client->pending_request_sentinel) {
            pending_request = containerof(client->pending_request_sentinel.next, PendingRequest, client_node);

            pending_request_remove_and_free(pending_request);
        }
    }

    if (client->destroy_done != NULL) {
        client->destroy_done();
    }
}
Example #5
0
static zx_status_t usb_midi_sink_write(void* ctx, const void* data, size_t length,
                                       zx_off_t offset, size_t* actual) {
    usb_midi_sink_t* sink = ctx;

    if (sink->dead) {
        return ZX_ERR_IO_NOT_PRESENT;
    }

    zx_status_t status = ZX_OK;
    size_t out_actual = length;

    const uint8_t* src = (uint8_t *)data;

    while (length > 0) {
        sync_completion_wait(&sink->free_write_completion, ZX_TIME_INFINITE);
        if (sink->dead) {
            return ZX_ERR_IO_NOT_PRESENT;
        }
        mtx_lock(&sink->mutex);
        list_node_t* node = list_remove_head(&sink->free_write_reqs);
        if (list_is_empty(&sink->free_write_reqs)) {
            sync_completion_reset(&sink->free_write_completion);
        }
        mtx_unlock(&sink->mutex);
        if (!node) {
            // shouldn't happen!
            status = ZX_ERR_INTERNAL;
            goto out;
        }
        usb_req_internal_t* req_int = containerof(node, usb_req_internal_t, node);
        usb_request_t* req = REQ_INTERNAL_TO_USB_REQ(req_int, sink->parent_req_size);

        size_t message_length = get_midi_message_length(*src);
        if (message_length < 1 || message_length > length) return ZX_ERR_INVALID_ARGS;

        uint8_t buffer[4];
        buffer[0] = (src[0] & 0xF0) >> 4;
        buffer[1] = src[0];
        buffer[2] = (message_length > 1 ? src[1] : 0);
        buffer[3] = (message_length > 2 ? src[2] : 0);

        usb_request_copy_to(req, buffer, 4, 0);
        req->header.length = 4;
        usb_request_complete_t complete = {
            .callback = usb_midi_sink_write_complete,
            .ctx = sink,
        };
        usb_request_queue(&sink->usb, req, &complete);

        src += message_length;
        length -= message_length;
    }

out:
    update_signals(sink);
    if (status == ZX_OK) {
        *actual = out_actual;
    }
    return status;
}
Example #6
0
static void tcp_read_cb(uv_stream_t *handle, ssize_t nread, uv_buf_t buf)
{
    uv_loop_t *loop = uv_default_loop();
    lua_State *l    = ls_default_state();
    ls_tcp_t  *tcp  = containerof(handle, ls_tcp_t, handle);
    lua_State *nl;

    if (ls_object_is_waited(&tcp->wait_object))
    {
        int ref = tcp->wait_object.mthread_ref;
        ls_getref(l, ref);
        tcp->wait_object.mthread_ref = LUA_NOREF;
        nl = lua_tothread(l, -1);
        lua_pop(l, 1);
        if (nl)
        {
            ls_clear_waiting(nl);
            if (LUA_YIELD == lua_status(nl))
            {
                if (nread == -1)
                    ls_last_error_resume(nl, loop);
                else
                {
                    lua_pushboolean(nl, 1);
                    lua_pushlstring(nl, buf.base, nread);
                    ls_resume(nl, 2);
                }
            }
        }
        ls_unref(l, ref);
    }
}
Example #7
0
// drop all pending requests for the given UID from the global list
static void network_drop_pending_requests(uint32_t uid) {
	Node *pending_request_global_node = _pending_request_sentinel.next;
	Node *pending_request_global_node_next;
	PendingRequest *pending_request;
	char base58[BASE58_MAX_LENGTH];
	int count = 0;

	while (pending_request_global_node != &_pending_request_sentinel) {
		pending_request = containerof(pending_request_global_node,
		                              PendingRequest, global_node);
		pending_request_global_node_next = pending_request_global_node->next;

		if (pending_request->header.uid == uid) {
			pending_request_remove_and_free(pending_request);

			++count;
		}

		pending_request_global_node = pending_request_global_node_next;
	}

	if (count > 0) {
		log_warn("Dropped %d pending request(s) (uid: %s)",
		         count, base58_encode(base58, uint32_from_le(uid)));
	}
}
Example #8
0
static zx_status_t session_io_cb(port_fd_handler_t* fh, unsigned pollevt, uint32_t evt) {
    vc_t* vc = containerof(fh, vc_t, fh);

    if (pollevt & POLLIN) {
        char data[1024];
        ssize_t r = read(vc->fd, data, sizeof(data));
        if (r > 0) {
            vc_write(vc, data, r, 0);
            return ZX_OK;
        }
    }

    if (pollevt & (POLLRDHUP | POLLHUP)) {
        // shell sessions get restarted on exit
        if (vc->is_shell) {
            zx_task_kill(vc->proc);
            vc->proc = ZX_HANDLE_INVALID;

            int fd = openat(vc->fd, "0", O_RDWR);
            if (fd < 0) {
                goto fail;
            }

            if (launch_shell(vc, fd, NULL) < 0) {
                goto fail;
            }
            return ZX_OK;
        }
    }

fail:
    session_destroy(vc);
    return ZX_ERR_STOP;
}
Example #9
0
static u32 send_delta_block(int fd,int connfd)
{
	u32 d_len;
	u64 d_off;
	u32 size_to_send = DELTA_BLOCK_ENTRY_SZ;
	delta_block_entry * dblk;
	list_head * dlst = dblk_link_list_head;
	if(dlst == NULL){
		printf("no delta block to send!\n");
		return 0;
	}
	while(1){
		dblk = containerof(dlst,delta_block_entry,dbe_list);
		d_len = dblk->len;
		d_off = dblk->offset;
		if(dblk->dup_flag == N_DUP_BLOCK){
			size_to_send += d_len;
		}
		lseek(fd,d_off,SEEK_SET);
		if(Read(fd,ptr,d_len) != d_len){
			fprintf(stderr,"send_delta_block : less bytes read from fd!\n");
			return 1;
		}
		memcpy(buf,dblk,DELTA_BLOCK_ENTRY_SZ);
		if(Write(connfd,buf,size_to_send) != size_to_send){
			fprintf(stderr,"send_delta_block : less bytes written to socket!\n");
			return 2;
		}
		if(IS_LAST_ENTRY(dlst)){
			break;
		}
		dlst = dlst->next;
	}
	return 0;
}
Example #10
0
File: hash.c Project: latchset/jose
static void
hsh_free(jose_io_t *io)
{
    io_t *i = containerof(io, io_t, io);
    jose_io_decref(i->next);
    EVP_MD_CTX_free(i->emc);
    free(i);
}
static void program_scheduler_handle_cron(void *opaque) {
	ProgramScheduler *program_scheduler = opaque;
	Program *program = containerof(program_scheduler, Program, scheduler);

	if (program_scheduler->state == PROGRAM_SCHEDULER_STATE_RUNNING &&
	    program->config.start_mode == PROGRAM_START_MODE_CRON) {
		program_scheduler_spawn_process(program_scheduler);
	}
}
Example #12
0
static void
io_free(jose_io_t *io)
{
    io_t *i = containerof(io, io_t, io);
    EVP_MD_CTX_free(i->emc);
    json_decref(i->obj);
    json_decref(i->sig);
    free(i);
}
static void program_scheduler_handle_process_state_change(void *opaque) {
	ProgramScheduler *program_scheduler = opaque;
	Program *program = containerof(program_scheduler, Program, scheduler);
	bool spawn = false;

	if (program_scheduler->state != PROGRAM_SCHEDULER_STATE_RUNNING) {
		return;
	}

	if (program_scheduler->last_spawned_process->state == PROCESS_STATE_EXITED) {
		if (program_scheduler->last_spawned_process->exit_code == 0) {
			if (program->config.start_mode == PROGRAM_START_MODE_ALWAYS) {
				spawn = true;
			}
		} else {
			if (program->config.continue_after_error) {
				if (program->config.start_mode == PROGRAM_START_MODE_ALWAYS) {
					spawn = true;
				}
			} else {
				program_scheduler_stop(program_scheduler, NULL);
			}
		}
	} else if (program_scheduler->last_spawned_process->state == PROCESS_STATE_ERROR ||
	           program_scheduler->last_spawned_process->state == PROCESS_STATE_KILLED) {
		if (program->config.continue_after_error) {
			if (program->config.start_mode == PROGRAM_START_MODE_ALWAYS) {
				spawn = true;
			}
		} else {
			program_scheduler_stop(program_scheduler, NULL);
		}
	}

	if (spawn) {
		// delay next process spawn by 1 second to avoid running into a tight
		// loop of process spawn and process exit events which would basically
		// stop redapid from doing anything else. also if the throughput between
		// redapid and brickv is low then sending to many program-process-spawned
		// callbacks might force brickv into doing nothing else but updating
		// the last-spawned-program-process information
		if (timer_configure(&program_scheduler->timer, 1000000, 0) < 0) {
			program_scheduler_handle_error(program_scheduler, false,
			                               "Could not start timer: %s (%d)",
			                               get_errno_name(errno), errno);

			return;
		}

		log_debug("Started timer for program object (identifier: %s)",
		          program->identifier->buffer);

		program_scheduler->timer_active = true;
	}
}
static void program_scheduler_handle_timer(void *opaque) {
	ProgramScheduler *program_scheduler = opaque;
	Program *program = containerof(program_scheduler, Program, scheduler);

	if (program_scheduler->state == PROGRAM_SCHEDULER_STATE_RUNNING) {
		if (program->config.start_mode == PROGRAM_START_MODE_ALWAYS ||
		    program->config.start_mode == PROGRAM_START_MODE_INTERVAL) {
			program_scheduler_spawn_process(program_scheduler);
		}
	}
}
void program_scheduler_continue(ProgramScheduler *program_scheduler) {
	Program *program = containerof(program_scheduler, Program, scheduler);

	if (program_scheduler->shutdown) {
		return;
	}

	if (program_scheduler->state == PROGRAM_SCHEDULER_STATE_STOPPED &&
	    program->config.start_mode != PROGRAM_START_MODE_NEVER) {
		program_scheduler_start(program_scheduler);
	}
}
Example #16
0
static void tcp_listen_cb(uv_stream_t *handle, int status)
{
    lua_State   *l             = ls_default_state();
    ls_tcp_t    *server        = containerof(handle, ls_tcp_t, handle);
    uv_loop_t   *loop          = uv_default_loop();
    lua_State   *nl;

    if (ls_object_is_waited(&server->wait_object))
    {
        int ref = server->wait_object.mthread_ref;
        server->wait_object.mthread_ref = LUA_NOREF;
        ls_getref(l, ref);
        nl = lua_tothread(l, -1);
        lua_pop(l, 1);

        if (nl)
        {
            ls_clear_waiting(nl);
            if (status != 0)
            {
                ls_last_error_resume(nl, loop);
            }
            else
            {
                ls_tcp_t *client = new_tcp_handle(l);
                if (uv_accept(handle, (uv_stream_t*)&client->handle))
                {
                    ls_free(nl, client);
                    luaL_error(nl, "accept failed");
                }
                if (uv_read_start((uv_stream_t*)&client->handle, tcp_alloc_cb, tcp_read_cb))
                {
                    ls_free(nl, client);
                    luaL_error(nl, "start read failed.");
                }

                if (LUA_YIELD == lua_status(nl))
                {
                    lua_pushboolean(nl, 1);
                    new_tcp_connection_udata(nl, client);
                    ls_resume(nl, 2);
                }
                else
                {
                    ls_free(nl, client);
                }
            }
        }
        ls_unref(l, ref);
    }
}
Example #17
0
File: hash.c Project: latchset/jose
static bool
hsh_done(jose_io_t *io)
{
    io_t *i = containerof(io, io_t, io);
    uint8_t hsh[EVP_MD_CTX_size(i->emc)];
    unsigned int l = 0;

    if (EVP_DigestFinal(i->emc, hsh, &l) <= 0)
        return SIZE_MAX;

    if (!i->next->feed(i->next, hsh, l) || !i->next->done(i->next))
        return SIZE_MAX;

    return l;
}
void program_scheduler_update(ProgramScheduler *program_scheduler, bool try_start) {
	APIE error_code;
	Program *program = containerof(program_scheduler, Program, scheduler);

	if (program_scheduler->shutdown) {
		return;
	}

	// check brickd connection state, if waiting for it
	if (program_scheduler->waiting_for_brickd && network_is_brickd_connected()) {
		program_scheduler->waiting_for_brickd = false;
	}

	// prepare filesystem
	error_code = program_scheduler_prepare_filesystem(program_scheduler);

	if (error_code != API_E_SUCCESS) {
		return;
	}

	if (!try_start) {
		// if starting should not be tried, then exit early
		return;
	}

	if (program->config.start_mode == PROGRAM_START_MODE_NEVER) {
		program_scheduler_stop(program_scheduler, program_scheduler->message);

		return;
	}

	if (program_scheduler->observer_state == PROCESS_OBSERVER_STATE_PENDING) {
		program_scheduler->observer_state = PROCESS_OBSERVER_STATE_WAITING;

		if (process_monitor_add_observer("lxpanel", 30, &program_scheduler->observer) < 0) {
			// if the observer could not be added, then start anyway.
			// this is still better than not starting at all
			program_scheduler->observer_state = PROCESS_OBSERVER_STATE_FINISHED;
		}
	}

	if (program_scheduler->observer_state == PROCESS_OBSERVER_STATE_FINISHED &&
	    !program_scheduler->waiting_for_brickd) {
		program_scheduler_start(program_scheduler);
	}
}
Example #19
0
void network_client_expects_response(Client *client, Packet *request) {
	PendingRequest *pending_request;
	char packet_signature[PACKET_MAX_SIGNATURE_LENGTH];

	if (client->pending_request_count >= CLIENT_MAX_PENDING_REQUESTS) {
		log_warn("Pending requests list for client ("CLIENT_SIGNATURE_FORMAT") is full, dropping %d pending request(s)",
		         client_expand_signature(client),
		         client->pending_request_count - CLIENT_MAX_PENDING_REQUESTS + 1);

		while (client->pending_request_count >= CLIENT_MAX_PENDING_REQUESTS) {
			pending_request = containerof(client->pending_request_sentinel.next, PendingRequest, client_node);

			pending_request_remove_and_free(pending_request);
		}
	}

	pending_request = calloc(1, sizeof(PendingRequest));

	if (pending_request == NULL) {
		log_error("Could not allocate pending request: %s (%d)",
		          get_errno_name(ENOMEM), ENOMEM);

		return;
	}

	node_reset(&pending_request->global_node);
	node_insert_before(&_pending_request_sentinel, &pending_request->global_node);

	node_reset(&pending_request->client_node);
	node_insert_before(&client->pending_request_sentinel, &pending_request->client_node);

	++client->pending_request_count;

	pending_request->client = client;
	pending_request->zombie = NULL;

	memcpy(&pending_request->header, &request->header, sizeof(PacketHeader));

#ifdef BRICKD_WITH_PROFILING
	pending_request->arrival_time = microseconds();
#endif

	log_packet_debug("Added pending request (%s) for client ("CLIENT_SIGNATURE_FORMAT")",
	                 packet_get_request_signature(packet_signature, request),
	                 client_expand_signature(client));
}
Example #20
0
static void tcp_connect_cb(uv_connect_t *connect_req, int status)
{
    ls_tcp_t *client = containerof(connect_req->handle, ls_tcp_t, handle);
    uv_tcp_t *handle = &client->handle;
    lua_State *l = ls_default_state();
    lua_State *nl;
    uv_loop_t *loop = uv_default_loop();

    ls_free(l, connect_req);

    if (ls_object_is_waited(&client->wait_object))
    {
        int ref = client->wait_object.mthread_ref;
        client->wait_object.mthread_ref = LUA_NOREF;
        ls_getref(l, ref);
        nl = lua_tothread(l, -1);
        lua_pop(l, 1);
        if (nl)
        {
            ls_clear_waiting(nl);
            if (status)
            {
                uv_close((uv_handle_t*)handle, tcp_close_cb);
                ls_last_error_resume(nl, loop);
            }
            else
            {
                if (uv_read_start((uv_stream_t*)handle, tcp_alloc_cb, tcp_read_cb))
                {
                    uv_close((uv_handle_t*)handle, tcp_close_cb);
                    ls_last_error_resume(nl, loop);
                }
                else
                {
                    lua_pushboolean(nl, 1);
                    new_tcp_connection_udata(nl, client);
                    ls_resume(nl, 2);
                }
            }
        }
        ls_unref(l, ref);
    }
}
Example #21
0
static void free_dblk_list(void)
{
	u8 last_dblk = 0;
	delta_block_entry * dblk;
	list_head * lst = dblk_link_list_head;
	if(lst == NULL)
		return;
	while(1){
		dblk = containerof(lst,delta_block_entry,dbe_list);
		if(IS_LAST_ENTRY(lst)){
			last_dblk = 1;
		}
		free(dblk);
		if(last_dblk == 1){
			break;
		}
		lst = lst->next;
	}
	return;
}
Example #22
0
static bool
sig_done(jose_io_t *io)
{
    io_t *i = containerof(io, io_t, io);
    size_t len = 0;

    if (EVP_DigestSignFinal(i->emc, NULL, &len) <= 0)
        return false;

    uint8_t buf[len];

    if (EVP_DigestSignFinal(i->emc, buf, &len) <= 0)
        return false;

    if (json_object_set_new(i->sig, "signature",
                            jose_b64_enc(buf, len)) < 0)
        return false;

    return add_entity(i->obj, i->sig,
                      "signatures", "signature", "protected", "header", NULL);
}
Example #23
0
static void tcp_write_cb(uv_write_t *req, int status)
{
    ls_write_t *write_req = containerof(req, ls_write_t, req);
    uv_loop_t *loop = uv_default_loop();
    lua_State *l, *nl;
    int i;

    l = ls_default_state();
    for (i=0; i<write_req->refcnt; i++)
    {
        ls_unref(l, write_req->data_refs[i]);
        lua_pop(l, 1);
        write_req->data_refs[i] = LUA_NOREF;
    }
    write_req->refcnt = 0;

    if (ls_object_is_waited(&write_req->wait_object))
    {
        int ref = write_req->wait_object.mthread_ref;
        write_req->wait_object.mthread_ref = LUA_NOREF;
        ls_getref(l, ref);
        nl = lua_tothread(l, -1);
        lua_pop(l, 1);
        if (nl)
        {
            ls_clear_waiting(nl);
            if (status)
            {
                ls_last_error_resume(nl, req->handle->loop);
            }
            else
            {
                ls_ok_resume(nl);
            }
        }

        ls_unref(l, ref);
    }
    ls_free(l, write_req);
}
static void program_scheduler_stop(ProgramScheduler *program_scheduler,
                                   String *message) {
	static bool recursive = false;
	Program *program = containerof(program_scheduler, Program, scheduler);

	if (recursive) {
		return;
	}

	program_scheduler_abort_observer(program_scheduler);

	if (program_scheduler->timer_active) {
		if (timer_configure(&program_scheduler->timer, 0, 0) < 0) {
			recursive = true;

			program_scheduler_handle_error(program_scheduler, false,
			                               "Could not stop timer: %s (%d)",
			                               get_errno_name(errno), errno);

			recursive = false;
		} else {
			log_debug("Stopped timer for program object (identifier: %s)",
			          program->identifier->buffer);

			program_scheduler->timer_active = false;
		}
	}

	if (program_scheduler->cron_active) {
		cron_remove_entry(program->base.id);

		log_debug("Removed cron entry for program object (identifier: %s)",
		          program->identifier->buffer);

		program_scheduler->cron_active = false;
	}

	program_scheduler_set_state(program_scheduler, PROGRAM_SCHEDULER_STATE_STOPPED,
	                            time(NULL), message);
}
Example #25
0
/* returns process structure by its id */
process_t *proc_get_process_by_id(proc_id pid)
{
    process_t *look4, *proc;
    unsigned int irqs_state;

    /* look for */
    look4 = containerof(&pid, process_t, id);

    /* acquire lock before tree-search */
    irqs_state = spin_lock_irqsave(&processes_lock);

    /* search */
    proc = avl_tree_find(&processes_tree, look4, NULL);

    /* increment refs count on success search */
    if(proc && proc->state != PROCESS_STATE_DEATH)
        atomic_inc((atomic_t*)&proc->ref_count);

    /* release lock */
    spin_unlock_irqrstor(&processes_lock, irqs_state);

    return proc;
}
Example #26
0
static bool
io_feed(jose_io_t *io, const void *in, size_t len)
{
    io_t *i = containerof(io, io_t, io);
    return EVP_DigestUpdate(i->emc, in, len) > 0;
}
Example #27
0
int main()
{
	/* rsync variables */
	u8 file_name[FILE_NAME_LEN] = {'\0'};
	u32 block_sz;
	u32 i;
	list_head ** lst_hd;
	list_head * lh_pre,* lh_next;
	u32 cblk_hash_v;
	/* chunk block */
	u64 chunk_block_nr;
	chunk_file_header cfh;
	reply_to_chunk_file_header rplh;
	chunk_block_entry * cblk;
	chunk_block_entry * cblk_array;
	chunk_block_entry * cblk_p;
	chunk_block_entry * cblk_current;
	u64 chunk_block_no;
	u32 chunk_block_rollin_chksm;
	u32 chunk_block_len;
	u8 * chunk_block_md5;
	u32 brk_v;
	u32 is_first_entry,is_last_entry;
	/* searching for dup blocks */
	u64 remaining_bytes;
	u64 delta_region_off;
	u64 dup_blk_off;
	u32 dup_blk_len;
	u32 rolling_chksm;
	u8 md5[MD5_SZ];
	u32 n;
	u8 * p;
	u32 akl,bkl,skl;
	u8 dup_found;
	u8 oc,nc;
	/* file to sync */
	int fd;
	struct stat file_stat;
	u64 file_sz;
	/* socket variables */
	int port;
    int listenfd,connfd,len;
    char ip_str[INET_ADDRSTRLEN];
    struct sockaddr_in addr,cli_addr;
    listenfd = socket(AF_INET,SOCK_STREAM,0);
    bzero(&addr,sizeof(addr));
    addr.sin_family = AF_INET;
    inet_pton(AF_INET,RSYNC_HOST_IP,(void*)&addr.sin_addr);
    addr.sin_port = htons(RSYNC_SRV_PORT);
    len = sizeof(addr);
    bind(listenfd,(struct sockaddr *)&addr,len);
    listen(listenfd,LISTENQ);
	len = sizeof(cli_addr);
	connfd = accept(listenfd,(struct sockaddr *)&cli_addr,&len);
	bzero(ip_str,INET_ADDRSTRLEN);
	inet_ntop(AF_INET,(void*)&cli_addr.sin_addr,ip_str,INET_ADDRSTRLEN);
	port = ntohs(cli_addr.sin_port);
	printf(" from %s,port %d\n",ip_str,port);
	if(Read(connfd,&cfh,CHUNK_FILE_HEAD_SZ) != CHUNK_FILE_HEAD_SZ){
		perror("read chunk_file_header");
		goto over1;
	}
	printf("--------- read chunk_blk_header ok -----------\n");
	block_sz = cfh.block_sz;
	chunk_block_nr = cfh.block_nr;
	strncpy(file_name,cfh.fn,strlen(cfh.fn));
	printf("---	block_sz		-- # %d\n",block_sz);
	printf("---	block_nr		-- # %d\n",chunk_block_nr);
	printf("---	file_to_sync	-- # %s\n",file_name);
	rplh.err = E_OK;
	if((fd = open(file_name,O_RDONLY)) < 0){
		perror("open src file");
		if(errno == ENOENT){
			/* when file not exist,goto send_delta_file_header
			 * need special disposition */
			/* tell dst to delete file */
			rplh.err = E_SRC_FILE_NOT_EXIST;
			goto SEND_RPL_TO_CFH;
		}
		goto over1;
	}
	if(fstat(fd,&file_stat) != 0){
		perror("fstat");
		goto over2;
	}
	file_sz = file_stat.st_size;
	if(file_sz == 0){
		rplh.err = E_SRC_FILE_NO_BLK;
	}
SEND_RPL_TO_CFH:
	/* send reply to chunk file header */
	if(Write(connfd,&rplh,RPL_TO_CHUNK_FILE_HEADER_SZ) != RPL_TO_CHUNK_FILE_HEADER_SZ){
		perror("write rpl to chunk file header");
		goto over2;
	}
	if(rplh.err != E_OK){
		goto over2;
	}
	/* dst file has 0 block */
	if(chunk_block_nr == 0){
		/* need special disposition */
		printf("dst file has no block!\n");
		update_delta_block_list(0,file_sz,0,NULL,block_sz);
		goto send_delta_file_header;
	}
	cblk_array = (chunk_block_entry*)malloc(chunk_block_nr*CHUNK_BLOCK_ENTRY_SZ);
	if(cblk_array == NULL){
		perror("malloc for chunk_block_entry_array");
		goto over2;
	}
	/* receive chunk block entry */
	for(i = 0;i < chunk_block_nr;i++){
		cblk_p = cblk_array + i;
		if(Read(connfd,cblk_p,CHUNK_BLOCK_ENTRY_SZ) != CHUNK_BLOCK_ENTRY_SZ){
			perror("read chunk_block_entry");
			goto over3;
		}
		chunk_block_rollin_chksm = cblk_p->rolling_chksm;
		chunk_block_len = cblk_p->block_len;
		chunk_block_md5 = cblk_p->md5;
		cblk_p->cbe_hash.next = &(cblk_p->cbe_hash);
		cblk_p->cbe_hash.pre = &(cblk_p->cbe_hash);
		cblk_hash_v = ROLLING_CHECKSUM_HASH(cblk_p->rolling_chksm);
		lst_hd = &chunk_blk_entry_hash[cblk_hash_v];
		if(*lst_hd == NULL){
			*lst_hd = &(cblk_p->cbe_hash);
			continue;
		}
		while(1){
			brk_v = 0;
			cblk_current = containerof(*lst_hd,chunk_block_entry,cbe_hash);
			if(cblk_current->block_len == chunk_block_len && \
		ROLLING_CHKSM_EQUAL(cblk_current->rolling_chksm,chunk_block_rollin_chksm)){
				if(MD5_EQUAL(cblk_current->md5,chunk_block_md5)){
					printf("skip identical chunk_block_entry\n");
					brk_v = 1;
					break;
				}
			}
			if(cblk_current->rolling_chksm > chunk_block_rollin_chksm){
				/* insert into the place before cblk_current */
				brk_v = 2;
				break;
			}
			if(IS_LAST_ENTRY(*lst_hd)){
				/* insert to tail */
				brk_v = 3;
				break;
			}
			lst_hd = &((*lst_hd)->next);
		}
		switch(brk_v){
			case 1:
				break;
			case 2:
				is_first_entry = 0;
				if(IS_FIRST_ENTRY(*lst_hd)){
					is_first_entry = 1;
				}else{
					lh_pre = (*lst_hd)->pre;
				}
				(*lst_hd)->pre = &(cblk_p->cbe_hash);
				cblk_p->cbe_hash.next = *lst_hd;
				if(is_first_entry == 1){
					chunk_blk_entry_hash[cblk_hash_v] = &(cblk_p->cbe_hash);
				}else{
					lh_pre->next = &(cblk_p->cbe_hash);
					cblk_p->cbe_hash.pre = lh_pre;
				}
				break;
			case 3:
				(*lst_hd)->next = &(cblk_p->cbe_hash);
				cblk_p->cbe_hash.pre = *lst_hd;
				break;
			default:
				break;
		}
	}
	printf("%d chunk block entrys received!\n",i);
	/* all chunk_block_entryS have been received 
	 * Now find the duplicate block from the src file */
	dup_blk_off = 0;
	dup_blk_len = block_sz;
	delta_region_off = 0;
	/* initialize buffer */
	buf_init(fd,file_sz);
	dup_found = DUP_FOUND;
	/* find duplicate block 
	 * and generate the list of delta_block */
	while(dup_blk_off < file_sz){
		n = 0;
		p = read_from_buf(dup_blk_off,dup_blk_len,&n);
		if(p == NULL){
			fprintf(stderr,"some errors happened when read_from_buf\n");
			goto over3;
		}
		/* else p is the pointer of the block 
		 * which is going to be checked 
		 * and the number of bytes is 'n' */
		if(dup_found == DUP_FOUND){
			/* start a new search or
			 * current block is the last block of src_file */
			printf("calculate the rolling_checksum with cal_rollin_cksm \n");
			akl = 0,bkl = 0,skl = 0;
			skl = cal_rollin_cksm(p,&akl,&bkl,n);
		}else if(dup_found == DUP_NOT_FOUND){
			/* the only case that rolling_checksum is calculated with last value */
			printf("calculate the rolling_checksum with cal_rollin_cksm_plus_1 \n");
			oc = *(p - 1);
			nc = (n < dup_blk_len?0:(*(p + n - 1)));
			skl = cal_rollin_cksm_plus_1(oc,nc,&akl,&bkl,dup_blk_len);
		}
		dup_found = DUP_NOT_FOUND;
		rolling_chksm = skl;
		cblk_hash_v = ROLLING_CHECKSUM_HASH(rolling_chksm);
		lst_hd = &(chunk_blk_entry_hash[cblk_hash_v]);
		/* searching */
		if(*lst_hd == NULL){
			/* no match,
			 * right shift one byte and continue */
			goto MODIFY_SOME_VAR_AND_GOTO_NEXT_LOOP;
		}
		while(1){
			cblk_current = containerof(*lst_hd,chunk_block_entry,cbe_hash);
			if(cblk_current->block_len == n && \
					ROLLING_CHKSM_EQUAL(cblk_current->rolling_chksm,rolling_chksm)){
				/* same block_len and rolling_chksm,
				 * need further checking md5 */
				cal_md5(p,n,md5);
				if(MD5_EQUAL(cblk_current->md5,md5)){
					dup_found = DUP_FOUND;
					break;
				}
			}
			if(cblk_current->rolling_chksm > rolling_chksm){
				/* because collided chunk_blk_entry are sorted 
				 * no need to search further here */
				break;
			}
			if(IS_LAST_ENTRY(*lst_hd)){
				/* the last entry */
				break;
			}
			lst_hd = &((*lst_hd)->next);
		}
MODIFY_SOME_VAR_AND_GOTO_NEXT_LOOP:
		if(dup_found == DUP_FOUND){
			/* dup_block found,
			 * 1) make delta_block_entry list,
			 * 2) reset : delta_region_off 
			 *			  delta_region_len
			 *			  dup_blk_off 
			 *	mention that dup_blk_off should be right shifted 'n' bytes */
			update_delta_block_list(delta_region_off,dup_blk_off,n,cblk_current,dup_blk_len);
			dup_blk_off += n;
			delta_region_off = dup_blk_off;
		}else if(dup_found == DUP_NOT_FOUND){
			/* dup_block not found,
			  right shift one byte and continue */
			dup_blk_off++;
		}
	}
	printf("finding dup_block over,delta_block_entry has been in the list!\n");
	/* sending delta_file_header */
send_delta_file_header:
	dfh.block_nr = delta_block_nr;
	if(Write(connfd,&dfh,DELTA_FILE_HEADER_SZ) != DELTA_FILE_HEADER_SZ){
		fprintf(stderr,"write delta_file_header fail!\n");
		goto over3;
	}
	if(send_delta_block(fd,connfd) != 0){
		fprintf(stderr,"some errors happened when sending delta_block!\n");
	}
over3:
	if(chunk_block_nr == 0){
		goto over2;
	}
	free(cblk_array);
over2:
	close(fd);
over1:
	close(connfd);
	return 0;
}
Example #28
0
void client_dispatch_response(Client *client, PendingRequest *pending_request,
                              Packet *response, bool force, bool ignore_authentication) {
    Node *pending_request_client_node = NULL;
    int enqueued = 0;
#ifdef BRICKD_WITH_PROFILING
    uint64_t elapsed;
#endif

    if (!ignore_authentication &&
            client->authentication_state != CLIENT_AUTHENTICATION_STATE_DISABLED &&
            client->authentication_state != CLIENT_AUTHENTICATION_STATE_DONE) {
        log_packet_debug("Ignoring non-authenticated client ("CLIENT_SIGNATURE_FORMAT")",
                         client_expand_signature(client));

        goto cleanup;
    }

    // find matching pending request if not forced and no pending request is
    // already given. do this before the disconnect check to ensure that even
    // for a disconnected client the pending request list is updated correctly
    if (!force && pending_request == NULL) {
        pending_request_client_node = client->pending_request_sentinel.next;

        while (pending_request_client_node != &client->pending_request_sentinel) {
            pending_request = containerof(pending_request_client_node, PendingRequest, client_node);

            if (packet_is_matching_response(response, &pending_request->header)) {
                break;
            }

            pending_request_client_node = pending_request_client_node->next;
        }

        if (pending_request_client_node == &client->pending_request_sentinel) {
            pending_request = NULL;

            goto cleanup;
        }
    }

    if (client->disconnected) {
        log_debug("Ignoring disconnected client ("CLIENT_SIGNATURE_FORMAT")",
                  client_expand_signature(client));

        goto cleanup;
    }

    if (force || pending_request != NULL) {
        enqueued = writer_write(&client->response_writer, response);

        if (enqueued < 0) {
            goto cleanup;
        }

        if (force) {
            log_packet_debug("Forced to %s response to client ("CLIENT_SIGNATURE_FORMAT")",
                             enqueued ? "enqueue" : "send", client_expand_signature(client));
        } else {
#ifdef BRICKD_WITH_PROFILING
            elapsed = microseconds() - pending_request->arrival_time;

            log_packet_debug("%s response to client ("CLIENT_SIGNATURE_FORMAT"), was requested %u.%03u msec ago, %d request(s) still pending",
                             enqueued ? "Enqueued" : "Sent", client_expand_signature(client),
                             (unsigned int)(elapsed / 1000), (unsigned int)(elapsed % 1000),
                             client->pending_request_count - 1);
#else
            log_packet_debug("%s response to client ("CLIENT_SIGNATURE_FORMAT"), %d request(s) still pending",
                             enqueued ? "Enqueued" : "Sent", client_expand_signature(client),
                             client->pending_request_count - 1);
#endif
        }
    }

cleanup:
    if (pending_request != NULL) {
        pending_request_remove_and_free(pending_request);
    }
}
static File *program_scheduler_prepare_stderr(ProgramScheduler *program_scheduler,
                                              struct timeval timestamp, File *stdout) {
	Program *program = containerof(program_scheduler, Program, scheduler);
	File *file;
	APIE error_code;

	switch (program->config.stderr_redirection) {
	case PROGRAM_STDIO_REDIRECTION_DEV_NULL:
		// FIXME: maybe only open /dev/null once and share it between all schedulers
		error_code = file_open(program_scheduler->dev_null_file_name->base.id,
		                       FILE_FLAG_WRITE_ONLY, 0, 1000, 1000,
		                       NULL, OBJECT_CREATE_FLAG_INTERNAL, NULL, &file);

		if (error_code != API_E_SUCCESS) {
			program_scheduler_handle_error(program_scheduler, false,
			                               "Could not open /dev/null for writing: %s (%d)",
			                               api_get_error_code_name(error_code), error_code);

			return NULL;
		}

		return file;

	case PROGRAM_STDIO_REDIRECTION_PIPE: // should never be reachable
		program_scheduler_handle_error(program_scheduler, true,
		                               "Invalid stderr redirection %d",
		                               program->config.stderr_redirection);

		return NULL;

	case PROGRAM_STDIO_REDIRECTION_FILE:
		if (program_scheduler->absolute_stderr_file_name == NULL) { // should never be reachable
			program_scheduler_handle_error(program_scheduler, true,
			                               "Absolute stderr file name not set");

			return NULL;
		}

		error_code = file_open(program_scheduler->absolute_stderr_file_name->base.id,
		                       FILE_FLAG_WRITE_ONLY | FILE_FLAG_CREATE,
		                       0644, 1000, 1000,
		                       NULL, OBJECT_CREATE_FLAG_INTERNAL, NULL, &file);

		if (error_code != API_E_SUCCESS) {
			program_scheduler_handle_error(program_scheduler, false,
			                               "Could not open/create '%s' for writing: %s (%d)",
			                               program_scheduler->absolute_stderr_file_name->buffer,
			                               api_get_error_code_name(error_code), error_code);

			return NULL;
		}

		return file;

	case PROGRAM_STDIO_REDIRECTION_INDIVIDUAL_LOG:
		return program_scheduler_prepare_individual_log(program_scheduler, timestamp, "stderr");

	case PROGRAM_STDIO_REDIRECTION_CONTINUOUS_LOG:
		return program_scheduler_prepare_continuous_log(program_scheduler, timestamp, "stderr");

	case PROGRAM_STDIO_REDIRECTION_STDOUT:
		object_add_internal_reference(&stdout->base);

		return stdout;

	default: // should never be reachable
		program_scheduler_handle_error(program_scheduler, true,
		                               "Invalid stderr redirection %d",
		                               program->config.stderr_redirection);

		return NULL;
	}
}
APIE program_scheduler_create(ProgramScheduler *program_scheduler,
                              ProgramSchedulerProcessSpawnedFunction process_spawned,
                              ProgramSchedulerStateChangedFunction state_changed,
                              void *opaque) {
	int phase = 0;
	Program *program = containerof(program_scheduler, Program, scheduler);
	APIE error_code;
	char bin_directory[1024];
	char *log_directory;
	String *dev_null_file_name;
	int i;
	String *environment;

	// format bin directory name
	if (robust_snprintf(bin_directory, sizeof(bin_directory), "%s/bin",
	                    program->root_directory->buffer) < 0) {
		error_code = api_get_error_code_from_errno();

		log_error("Could not format program bin directory name: %s (%d)",
		          get_errno_name(errno), errno);

		goto cleanup;
	}

	// create bin directory as default user (UID 1000, GID 1000)
	error_code = directory_create(bin_directory, DIRECTORY_FLAG_RECURSIVE,
	                              0755, 1000, 1000);

	if (error_code != API_E_SUCCESS) {
		goto cleanup;
	}

	// format log directory name
	if (asprintf(&log_directory, "%s/log", program->root_directory->buffer) < 0) {
		error_code = api_get_error_code_from_errno();

		log_error("Could not format program log directory name: %s (%d)",
		          get_errno_name(errno), errno);

		goto cleanup;
	}

	phase = 1;

	// create log directory as default user (UID 1000, GID 1000)
	error_code = directory_create(log_directory, DIRECTORY_FLAG_RECURSIVE,
	                              0755, 1000, 1000);

	if (error_code != API_E_SUCCESS) {
		goto cleanup;
	}

	// get '/dev/null' stock string object
	error_code = inventory_get_stock_string("/dev/null", &dev_null_file_name);

	if (error_code != API_E_SUCCESS) {
		goto cleanup;
	}

	phase = 2;

	program_scheduler->process_spawned = process_spawned;
	program_scheduler->state_changed = state_changed;
	program_scheduler->opaque = opaque;
	program_scheduler->absolute_working_directory = NULL;
	program_scheduler->absolute_stdin_file_name = NULL;
	program_scheduler->absolute_stdout_file_name = NULL;
	program_scheduler->absolute_stderr_file_name = NULL;
	program_scheduler->log_directory = log_directory;
	program_scheduler->dev_null_file_name = dev_null_file_name;
	program_scheduler->observer.function = program_scheduler_handle_observer;
	program_scheduler->observer.opaque = program_scheduler;
	program_scheduler->observer_state = PROCESS_OBSERVER_STATE_FINISHED;
	program_scheduler->shutdown = false;
	program_scheduler->waiting_for_brickd = !network_is_brickd_connected();
	program_scheduler->timer_active = false;
	program_scheduler->cron_active = false;
	program_scheduler->last_spawned_process = NULL;
	program_scheduler->last_spawned_timestamp = 0;
	program_scheduler->state = PROGRAM_SCHEDULER_STATE_STOPPED;
	program_scheduler->timestamp = time(NULL);
	program_scheduler->message = NULL;

	// if X11 is enabled...
	if (_x11_enabled) {
		for (i = 0; i < program->config.environment->items.count; ++i) {
			environment = *(String **)array_get(&program->config.environment->items, i);

			// ...and the DISPLAY environment variable is set...
			if (strncmp(environment->buffer, "DISPLAY=", strlen("DISPLAY=")) == 0) {
				// ...then use the process monitor to wait for lxpanel to start
				program_scheduler->observer_state = PROCESS_OBSERVER_STATE_PENDING;

				break;
			}
		}
	}

	// FIXME: only create timer for interval mode, otherwise this wastes a
	//        file descriptor per non-interval scheduler
	if (timer_create_(&program_scheduler->timer, program_scheduler_handle_timer,
	                  program_scheduler) < 0) {
		error_code = api_get_error_code_from_errno();

		log_error("Could not create timer: %s (%d)",
		          get_errno_name(errno), errno);

		goto cleanup;
	}

	phase = 3;

cleanup:
	switch (phase) { // no breaks, all cases fall through intentionally
	case 2:
		string_unlock_and_release(dev_null_file_name);

	case 1:
		free(log_directory);

	default:
		break;
	}

	return phase == 3 ? API_E_SUCCESS : error_code;
}