Exemplo n.º 1
1
int main(int argc, char **argv)
{
	/* Se prezinta etapele cronologice ale simularii unei retele de rutere prin
	implementarea unui program care va fi capabil sa ruleze un algoritm de rutare SPF
	(shortest path first) minimalist si sa se adapteze la schimbarile din retea in cadrul
	aceluiasi algoritm si sa ruteze o serie de mesaje date ca input. Se pot adauga sau
	sterge legaturi in retea */
	
	int noRouters;
	ifstream infile(argv[1]);
	infile >> noRouters;
	

	init_api(argc, argv);
	init_sim(argc, argv);

	loop {
		trigger_events();
		process_messages(noRouters);
		update_routing_table(noRouters);
		api_update_state();
		if (api_simulation_ended())
			break;
	}

	clean_sim();
	clean_api();
	
	return 0;
}
Exemplo n.º 2
0
/* 删除 */
int command_remove(int argc, char **argv) {
//{{{
    int ret = 0;
    const char *error   = NULL;
    const char *path    = NULL;

    if (argc < 2) {
        color_log(COLOR_LOG_ERROR, "rm 缺少参数\n");
        ret = 1;
        goto free;
    }

    path = argv[1];

    if (!init_api()) {
        ret = 1;
        goto free;
    }

    BaiduPCS_Remove(api, path);

    error = BaiduPCS_GetError(api);
    if (error != NULL) {
        color_log(COLOR_LOG_ERROR, "rm %s 失败:%s\n", path, error);
        ret = 1;
        goto free;
    }

free:
    return ret;
}
Exemplo n.º 3
0
// General Functions
uint8_t xboot_get_version(uint16_t *ver)
{
        uint8_t ret = init_api();
        uint16_t ptr;
        
        #ifdef NEED_EIND
        uint8_t saved_eind;
        #endif // NEED_EIND
        
        if (ret != XB_SUCCESS)
                return ret;
        
        if (api_version == 1)
        {
                ptr = PGM_READ_WORD(JUMP_TABLE_INDEX(0));
                if (ptr == 0 || ptr == 0xffff)
                        return XB_ERR_NOT_FOUND;
                
                #ifdef NEED_EIND
                saved_eind = EIND;
                EIND = PROGMEM_SIZE >> 17;
                #endif // NEED_EIND
                
                ret = ( (uint8_t(*)(uint16_t *)) ptr )(ver);
                
                #ifdef NEED_EIND
                EIND = saved_eind;
                #endif // NEED_EIND
                
                return ret;
        }
Exemplo n.º 4
0
Arquivo: main.c Projeto: jdp/psionrl
int main(int argc, char *argv[]) {
	/* Open up the Lua environment */
	if (!init_scripting()) {
		fprintf(stderr, "Error starting Lua environment\n");
		return 1;
	}
	
	/* Initialize the API */
	init_api();
	
	/* Configure the game */
	if (!config()) {
		fprintf(stderr, "Configuration error\n");
		return 1;
	}
	
	TCOD_console_set_custom_font(font_file, font_glyph_width,
								 font_glyph_height,
								 TCOD_FONT_LAYOUT_ASCII_INCOL);
	
	/* Open up the console window */
	TCOD_console_init_root(ui_width, ui_height, ui_caption, false);
	
	/* Why is this necessary? */
	/*
	splash();
	getkey();
	menu();
	getkey();
	*/
	
	/*
	run_script("test");
	lua_getglobal(L, "monsters");
	lua_pushnil(L);
	while (lua_next(L, -2) != 0) {
		printf("%s - %s\n",
			lua_typename(L, lua_type(L, -2)),
			lua_tostring(L, -1));
		lua_pop(L, 1);
	}
	lua_pop(L, 1);
	printf("TOS: %d\n", lua_gettop(L));
	*/
	
	/* Enter the main game loop */
	play();
	
	/* Clean & successful exit */
	return 0;
}
Exemplo n.º 5
0
/* 列出远程文件 */
int command_ls(int argc, char **argv) {
//{{{
    int option_show_detail = 0; //是否显示详情
    int option_recursion   = 0; //是否递归
    int ret = 0;
    char c;
    char *remote_path;

    opterr = 0;
    while ((c = getopt (argc, argv, "lr")) != -1) {
        switch (c) {
            case 'l':
                option_show_detail = 1;
                break;
            case 'r':
                option_recursion = 1;
                break;
        }
    }
 
    if (optind < argc - 1) {
        color_log(COLOR_LOG_ERROR, "请指定路径\n");
        usage();
        ret = 1;
        goto free;
    }
    
    remote_path = argv[argc - 1];
#ifdef DEBUG
    fprintf(stderr, "ls %s\n", remote_path);
#endif
    
    if (!init_api()) {
        ret = 1;
        goto free;
    }
    
    if (option_recursion) {
        ret = do_recursion_ls(remote_path, option_show_detail);
    } else {
        ret = do_normal_ls(remote_path, option_show_detail);
    }

free:
    return ret;
}
Exemplo n.º 6
0
int main(int argc, char **argv)
{
	Network network; // pastreaza informatii despre intreaga retea

	init_api(argc, argv);
	init_sim(&network, argv);

	loop {
		trigger_events(&network);
		process_messages(&network);
		update_routing_table(&network);
		api_update_state();
		if (api_simulation_ended())
			break;
	}

	clean_sim(&network);
	clean_api();

	return 0;
}
Exemplo n.º 7
0
/* 移动,复制 */
int command_move_or_copy(int argc, char **argv, const char *type) {
//{{{
    int ret = 0;
    const char *error   = NULL;
    const char *from    = NULL;
    const char *to      = NULL;

    if (argc < 3) {
        color_log(COLOR_LOG_ERROR, "%s 缺少参数\n", type);
        ret = 1;
        goto free;
    }

    from = argv[1];
    to   = argv[2];

    if (!init_api()) {
        ret = 1;
        goto free;
    }

    if (strcmp(type, "cp") == 0) {
        BaiduPCS_Copy(api, from, to);
    } else {
        BaiduPCS_Move(api, from, to);
    }

    error = BaiduPCS_GetError(api);
    if (error != NULL) {
        color_log(COLOR_LOG_ERROR, "%s %s -> %s %s\n", type, from, to, error);
        ret = 1;
        goto free;
    }

free:
    return ret;

}
Exemplo n.º 8
0
/* 显示云盘信息 */
int command_info(int argc, char **argv) {
//{{{
    if (!init_api()) return 1;
    int ret = 0;
    const char *error   = NULL;
    char buf[1024];
    BaiduPCSInfo info;

    BaiduPCS_Info(api, &info);
    error = BaiduPCS_GetError(api);
    if (error != NULL) {
        color_log(COLOR_LOG_ERROR, "获取信息失败%s\n", error);
        ret = 1;
        goto free;
    }

    readable_size(info.quota, buf);
    printf("总容量:%s\n", buf);
    readable_size(info.used, buf);
    printf("已使用:%s\n", buf);
free:
    return ret;
}
Exemplo n.º 9
0
void *Loader::load_driver(const char* kind, const char *tag,
        egl_connection_t* cnx, uint32_t mask)
{
    char driver_absolute_path[PATH_MAX];
    const char* const search1 = "/vendor/lib/egl/lib%s_%s.so";
    const char* const search2 = "/system/lib/egl/lib%s_%s.so";

    snprintf(driver_absolute_path, PATH_MAX, search1, kind, tag);
    if (access(driver_absolute_path, R_OK)) {
        snprintf(driver_absolute_path, PATH_MAX, search2, kind, tag);
        if (access(driver_absolute_path, R_OK)) {
            // this happens often, we don't want to log an error
            return 0;
        }
    }

    void* dso = dlopen(driver_absolute_path, RTLD_NOW | RTLD_LOCAL);
    if (dso == 0) {
        const char* err = dlerror();
        LOGE("load_driver(%s): %s", driver_absolute_path, err?err:"unknown");
        return 0;
    }

    LOGD("loaded %s", driver_absolute_path);

    if (mask & EGL) {
        getProcAddress = (getProcAddressType)dlsym(dso, "eglGetProcAddress");

        LOGE_IF(!getProcAddress, 
                "can't find eglGetProcAddress() in %s", driver_absolute_path);

        egl_t* egl = &cnx->egl;
        __eglMustCastToProperFunctionPointerType* curr =
            (__eglMustCastToProperFunctionPointerType*)egl;
        char const * const * api = egl_names;
        while (*api) {
            char const * name = *api;
            __eglMustCastToProperFunctionPointerType f = 
                (__eglMustCastToProperFunctionPointerType)dlsym(dso, name);
            if (f == NULL) {
                // couldn't find the entry-point, use eglGetProcAddress()
                f = getProcAddress(name);
                if (f == NULL) {
                    f = (__eglMustCastToProperFunctionPointerType)0;
                }
            }
            *curr++ = f;
            api++;
        }
    }
    
    if (mask & GLESv1_CM) {
        void *gl=&cnx->hooks[GLESv1_INDEX]->gl;
        init_api(dso, gl_names,
            (__eglMustCastToProperFunctionPointerType*)
                gl,
            getProcAddress);
    }

    if (mask & GLESv2) {
      void *gl=&cnx->hooks[GLESv2_INDEX]->gl;
      init_api(dso, gl_names,
            (__eglMustCastToProperFunctionPointerType*)
                gl,
            getProcAddress);
    }
    
    return dso;
}
Exemplo n.º 10
0
/* 上传文件或目录 */
int command_upload(int argc, char **argv) {
//{{{
    int option_overwrite        = 0; /* 覆盖同名文件        */
    int option_new              = 0; /* 创建新文件          */
    int option_follow_link      = 0; /* 复制链接源文件      */
    size_t option_split_size    = 0; /* 分片大小            */

    int ret = 0;
    int i   = 0;
    char c;

    char *split_size    = NULL;
    char *remote_path   = NULL;
    char *local_path    = NULL;

    /* 最大分片 2G  */
    size_t max_split_size = 2 * 1024 * 1024 * (size_t)1024;
    /* 最小分片 10M */
    size_t min_split_size = 10 * 1024 * 1024;


    opterr = 0;
    while ((c = getopt(argc, argv, "onlp:")) != -1) {
        switch (c) {
            case 'o':
                option_overwrite = 1;
                break;
            case 'n':
                option_new = 1;
                break;
            case 'l':
                option_follow_link = 1;
                break;
            case 'p':
                split_size = optarg;
                break;
            case '?':
                if (optopt == 'p') {
                    color_log(COLOR_LOG_ERROR, "-p 请指定分片大小\n");
                    ret = 1;
                    goto free;
                }
                break;
        }
    }
 
    if (option_overwrite && option_new) {
        color_log(COLOR_LOG_ERROR, "请不要同时指定-n -o\n");
        ret = 1;
        goto free;
    }

    if (optind < argc - 2) {
        color_log(COLOR_LOG_ERROR, "请指定路径\n");
        usage();
        ret = 1;
        goto free;
    }

    local_path = argv[argc - 2];
    if (local_path[strlen(local_path) - 1] == '/') {
        local_path[strlen(local_path) - 1] = '\0';
    }

    remote_path = argv[argc - 1];
    if (remote_path[strlen(remote_path) - 1] == '/') {
        remote_path[strlen(remote_path) - 1] = '\0';
    }

    /* 默认50M分片大小 */
    if (split_size == NULL) {
        option_split_size = 50 * 1024 * 1024;
    } else {
        i = strlen(split_size) - 1;
        if (i > 0) {
            if (split_size[i] == 'M' || split_size[i] == 'm') {
                split_size[i] = '\0';
                option_split_size = atof(split_size) * 1024 * 1024;
            } else if (split_size[i] == 'G' || split_size[i] == 'g') {
                split_size[i] = '\0';
                option_split_size = atof(split_size) * 1024 * 1024 * 1024;
            }
        } else {
            option_split_size = atol(split_size);
        }

        if (option_split_size < min_split_size) {
            ret = 1;
            color_log(COLOR_LOG_ERROR, "分片尺寸不能小于10M\n");
            goto free;
        } else if (option_split_size > max_split_size) {
            ret = 1;
            color_log(COLOR_LOG_ERROR, "分片尺寸不能大于2G\n");
            goto free;
        }
    }

    if (!init_api()) {
        ret = 1;
        goto free;
    }

#ifdef DEBUG
    fprintf(stderr, "Upload %s to %s\n", local_path, remote_path);
    readable_size(option_split_size, api->util_buffer0);
    fprintf(stderr, "分片尺寸:%s\n", api->util_buffer0);
#endif

   
    if (stat(local_path, &(api->file_st)) == -1) {
        color_log(COLOR_LOG_ERROR, "%s 不存在\n", local_path);
        ret = 1;
        goto free;
    }

    ret = do_upload(local_path,
                    remote_path,
                    option_overwrite, 
                    option_new, 
                    option_follow_link,
                    option_split_size);
free:

    return ret;
} 
Exemplo n.º 11
0
/* 下载文件或目录 */
int command_download(int argc, char **argv) {
//{{{
    int option_overwrite    = 0; /* 覆盖同名文件        */
    int option_new          = 0; /* 创建新文件          */

    int ret = 0;
    char c;

    char *remote_path;
    char *local_path;
    
    opterr = 0;
    while ((c = getopt(argc, argv, "on")) != -1) {
        switch (c) {
            case 'o':
                option_overwrite = 1;
                break;
            case 'n':
                option_new = 1;
                break;
        }
    }
 
    if (option_overwrite && option_new) {
        color_log(COLOR_LOG_ERROR, "请不要同时指定-n -o\n");
        ret = 1;
        goto free;
    }

    if (optind < argc - 2) {
        color_log(COLOR_LOG_ERROR, "请指定路径\n");
        usage();
        ret = 1;
        goto free;
    }

    local_path = argv[argc - 1];
    if (local_path[strlen(local_path) - 1] == '/') {
        local_path[strlen(local_path) - 1] = '\0';
    }

    remote_path = argv[argc - 2];
    if (remote_path[strlen(remote_path) - 1] == '/') {
        remote_path[strlen(remote_path) - 1] = '\0';
    }

#ifdef DEBUG
    fprintf(stderr, "Download %s to %s\n", local_path, remote_path);
#endif

    if (!init_api()) {
        ret = 1;
        goto free;
    }
    
    ret = do_download(remote_path,
                    local_path,
                    option_overwrite, 
                    option_new);
free:
    return ret;
} 
Exemplo n.º 12
0
void *Loader::load_driver(const char* kind,
        egl_connection_t* cnx, uint32_t mask)
{
    class MatchFile {
    public:
        static String8 find(const char* kind) {
            String8 result;
            String8 pattern;
            pattern.appendFormat("lib%s", kind);
            const char* const searchPaths[] = {
#if defined(__LP64__)
                    "/vendor/lib64/egl",
                    "/system/lib64/egl"
#else
                    "/vendor/lib/egl",
                    "/system/lib/egl"
#endif
            };

            // first, we search for the exact name of the GLES userspace
            // driver in both locations.
            // i.e.:
            //      libGLES.so, or:
            //      libEGL.so, libGLESv1_CM.so, libGLESv2.so

            for (size_t i=0 ; i<NELEM(searchPaths) ; i++) {
                if (find(result, pattern, searchPaths[i], true)) {
                    return result;
                }
            }

            // for compatibility with the old "egl.cfg" naming convention
            // we look for files that match:
            //      libGLES_*.so, or:
            //      libEGL_*.so, libGLESv1_CM_*.so, libGLESv2_*.so

            pattern.append("_");
            for (size_t i=0 ; i<NELEM(searchPaths) ; i++) {
                if (find(result, pattern, searchPaths[i], false)) {
                    return result;
                }
            }

            // we didn't find the driver. gah.
            result.clear();
            return result;
        }

    private:
        static bool find(String8& result,
                const String8& pattern, const char* const search, bool exact) {

            // in the emulator case, we just return the hardcoded name
            // of the software renderer.
            if (checkGlesEmulationStatus() == 0) {
                ALOGD("Emulator without GPU support detected. "
                      "Fallback to software renderer.");
#if defined(__LP64__)
                result.setTo("/system/lib64/egl/libGLES_android.so");
#else
                result.setTo("/system/lib/egl/libGLES_android.so");
#endif
                return true;
            }

            if (exact) {
                String8 absolutePath;
                absolutePath.appendFormat("%s/%s.so", search, pattern.string());
                if (!access(absolutePath.string(), R_OK)) {
                    result = absolutePath;
                    return true;
                }
                return false;
            }

            DIR* d = opendir(search);
            if (d != NULL) {
                struct dirent cur;
                struct dirent* e;
                while (readdir_r(d, &cur, &e) == 0 && e) {
                    if (e->d_type == DT_DIR) {
                        continue;
                    }
                    if (!strcmp(e->d_name, "libGLES_android.so")) {
                        // always skip the software renderer
                        continue;
                    }
                    if (strstr(e->d_name, pattern.string()) == e->d_name) {
                        if (!strcmp(e->d_name + strlen(e->d_name) - 3, ".so")) {
                            result.clear();
                            result.appendFormat("%s/%s", search, e->d_name);
                            closedir(d);
                            return true;
                        }
                    }
                }
                closedir(d);
            }
            return false;
        }
    };


    String8 absolutePath = MatchFile::find(kind);
    if (absolutePath.isEmpty()) {
        // this happens often, we don't want to log an error
        return 0;
    }
    const char* const driver_absolute_path = absolutePath.string();

    void* dso = dlopen(driver_absolute_path, RTLD_NOW | RTLD_LOCAL);
    if (dso == 0) {
        const char* err = dlerror();
        ALOGE("load_driver(%s): %s", driver_absolute_path, err?err:"unknown");
        return 0;
    }

    ALOGD("loaded %s", driver_absolute_path);

    if (mask & EGL) {
        getProcAddress = (getProcAddressType)dlsym(dso, "eglGetProcAddress");

        ALOGE_IF(!getProcAddress,
                "can't find eglGetProcAddress() in %s", driver_absolute_path);

        egl_t* egl = &cnx->egl;
        __eglMustCastToProperFunctionPointerType* curr =
            (__eglMustCastToProperFunctionPointerType*)egl;
        char const * const * api = egl_names;
        while (*api) {
            char const * name = *api;
            __eglMustCastToProperFunctionPointerType f =
                (__eglMustCastToProperFunctionPointerType)dlsym(dso, name);
            if (f == NULL) {
                // couldn't find the entry-point, use eglGetProcAddress()
                f = getProcAddress(name);
                if (f == NULL) {
                    f = (__eglMustCastToProperFunctionPointerType)0;
                }
            }
            *curr++ = f;
            api++;
        }
    }

    if (mask & GLESv1_CM) {
        init_api(dso, gl_names,
            (__eglMustCastToProperFunctionPointerType*)
                &cnx->hooks[egl_connection_t::GLESv1_INDEX]->gl,
            getProcAddress);
    }

    if (mask & GLESv2) {
      init_api(dso, gl_names,
            (__eglMustCastToProperFunctionPointerType*)
                &cnx->hooks[egl_connection_t::GLESv2_INDEX]->gl,
            getProcAddress);
    }

    return dso;
}
Exemplo n.º 13
0
void *Loader::load_driver(const char* kind, const char *tag,
        egl_connection_t* cnx, uint32_t mask)
{
    char driver_absolute_path[PATH_MAX];
    const char* const search1 = "/vendor/lib/egl/lib%s_%s.so";
    const char* const search2 = "/system/lib/egl/lib%s_%s.so";

    snprintf(driver_absolute_path, PATH_MAX, search1, kind, tag);
    if (access(driver_absolute_path, R_OK)) {
        snprintf(driver_absolute_path, PATH_MAX, search2, kind, tag);
        if (access(driver_absolute_path, R_OK)) {
            // this happens often, we don't want to log an error
            return 0;
        }
    }

    void* dso = dlopen(driver_absolute_path, RTLD_NOW | RTLD_LOCAL);
    if (dso == 0) {
        const char* err = dlerror();
        ALOGE("load_driver(%s): %s", driver_absolute_path, err?err:"unknown");
        return 0;
    }

    ALOGD("loaded %s", driver_absolute_path);

    if (mask & EGL) {
        getProcAddress = (getProcAddressType)dlsym(dso, "eglGetProcAddress");

        ALOGE_IF(!getProcAddress, 
                "can't find eglGetProcAddress() in %s", driver_absolute_path);

#ifdef SYSTEMUI_PBSIZE_HACK
#warning "SYSTEMUI_PBSIZE_HACK enabled"
        /*
         * TODO: replace SYSTEMUI_PBSIZE_HACK by something less hackish
         *
         * Here we adjust the PB size from its default value to 512KB which
         * is the minimum acceptable for the systemui process.
         * We do this on low-end devices only because it allows us to enable
         * h/w acceleration in the systemui process while keeping the
         * memory usage down.
         *
         * Obviously, this is the wrong place and wrong way to make this
         * adjustment, but at the time of this writing this was the safest
         * solution.
         */
        const char *cmdline = getProcessCmdline();
        if (strstr(cmdline, "systemui")) {
            void *imgegl = dlopen("/vendor/lib/libIMGegl.so", RTLD_LAZY);
            if (imgegl) {
                unsigned int *PVRDefaultPBS =
                        (unsigned int *)dlsym(imgegl, "PVRDefaultPBS");
                if (PVRDefaultPBS) {
                    ALOGD("setting default PBS to 512KB, was %d KB", *PVRDefaultPBS / 1024);
                    *PVRDefaultPBS = 512*1024;
                }
            }
        }
#endif

        egl_t* egl = &cnx->egl;
        __eglMustCastToProperFunctionPointerType* curr =
            (__eglMustCastToProperFunctionPointerType*)egl;
        char const * const * api = egl_names;
        while (*api) {
            char const * name = *api;
            __eglMustCastToProperFunctionPointerType f = 
                (__eglMustCastToProperFunctionPointerType)dlsym(dso, name);
            if (f == NULL) {
                // couldn't find the entry-point, use eglGetProcAddress()
                f = getProcAddress(name);
                if (f == NULL) {
                    f = (__eglMustCastToProperFunctionPointerType)0;
                }
            }
            *curr++ = f;
            api++;
        }
    }
    
    if (mask & GLESv1_CM) {
        init_api(dso, gl_names,
            (__eglMustCastToProperFunctionPointerType*)
                &cnx->hooks[egl_connection_t::GLESv1_INDEX]->gl,
            getProcAddress);
    }

    if (mask & GLESv2) {
      init_api(dso, gl_names,
            (__eglMustCastToProperFunctionPointerType*)
                &cnx->hooks[egl_connection_t::GLESv2_INDEX]->gl,
            getProcAddress);
    }
    
    return dso;
}
Exemplo n.º 14
0
int main() {
	int res, try, retries;
	char *query_string, *abf_api_url, *api_token;

	char *log_level = getenv("LOG_LEVEL");
	if (init_logger(log_level == NULL ? "INFO" : log_level) < 0) {
		return 2;
	}
	register_thread("Main");

	log_printf(LOG_INFO, "Starting DNS check...\n");
	res = check_dns();
	if (res < 0) {
		log_printf(LOG_FATAL, "Check DNS failed, can't resolve github.com. Exiting...\n");
		return 6;
	} else {
		log_printf(LOG_INFO, "Successfuly resolved github. Continuing.\n");
	}

	usergroup omv_mock = get_omv_uid_mock_gid();
	if(omv_mock.omv_uid == 0) {
		log_printf(LOG_FATAL, "User omv doesn't exist. Exiting...\n");
		return 7;
	}
	if(omv_mock.mock_gid == 0) {
		log_printf(LOG_FATAL, "Group mock doesn't exist. Exiting...\n");
		return 8;
	}

	res = process_config(&abf_api_url, &api_token, &query_string);
	if (res < 0) {
		log_printf(LOG_FATAL, "Failed to process config, exiting.\n");
		return 1;
	}

	init_strings(api_token);

	init_api(abf_api_url, api_token);

	if(start_statistics_thread(query_string)) {
		log_printf(LOG_FATAL, "Failed to initialize statistics thread. Exiting...\n");
		return 5;
	}

	while(1) {
		char *job;
		if(api_jobs_shift(&job, query_string)) {
			sleep(10);
			continue;
		}

		char *build_id, *distrib_type;
		char **env;
		int ttl;

		res = parse_job_description(job, &build_id, &ttl, &distrib_type, &env);
		free(job);
		if(res < 0) {
			sleep(10);
			continue;
		}

		log_printf(LOG_INFO, "Starting build with build_id %s.\n", build_id);
		log_printf(LOG_INFO, "Sending build start notification to ABF.\n");
		retries = 5;
		try = 0;
		set_busy_status(1, build_id);
		int build_start_success = 0;
		while(retries) {
			log_printf(LOG_INFO, "Try #%d: Sending data to ABF.\n", try + 1);
			if(!api_jobs_feedback(build_id, BUILD_STARTED, hostname_payload)) {
				log_printf(LOG_INFO, "Try #%d: Data sent.\n", try + 1);
				build_start_success = 1;
				break;
			} else {
				log_printf(LOG_ERROR, "Try #%d: Failed to send data to ABF. Sleeping for %d seconds and retrying...\n", try + 1, 1 << try);
			}
			retries--;
			sleep(1 << try);
			try++;
		}

		if (!build_start_success) {
			log_printf(LOG_ERROR, "Failed to send build start to ABF, aborting build.\n");
			free(build_id);
			free(distrib_type);
			for(int i = 0; i < res; i++) {
				free(env[i]);
			}
			free(env);
			set_busy_status(0, NULL);
			continue;
		}

		child script = exec_build(distrib_type, (char * const *)env, omv_mock);

		int live_inspector_started = 1;
		log_printf(LOG_INFO, "Starting live inspector, build's time to live is %d seconds.\n", ttl);
		if(start_live_inspector(ttl, script.pid, build_id) < 0) {
			live_inspector_started = 0;
			log_printf(LOG_WARN, "Live inspector failed to start. Job canceling and timeout will be unavailable.\n");
		}

		int live_logger_started = 1;
		log_printf(LOG_INFO, "Starting live logger.\n");
		if(start_live_logger(build_id, script.read_fd) < 0) {
			live_logger_started = 0;
			log_printf(LOG_WARN, "Live logger failed to start. Live log will be unavailable.\n");
		}

		int status, build_status = BUILD_COMPLETED;
		waitpid(script.pid, &status, 0);
		int canceled = 0;
		if (live_inspector_started) {
			canceled = stop_live_inspector();
		}
		if (live_logger_started) {
			stop_live_logger();
		}

		int exit_code = 0;
		if (canceled) {
			build_status = BUILD_CANCELED;
		}
		else if(WIFEXITED(status)) {
			exit_code = WEXITSTATUS(status);
			switch(exit_code) {
				case 0:
					build_status = BUILD_COMPLETED;
					break;
				case 5:
					build_status = TESTS_FAILED;
					break;
				default:
					build_status = BUILD_FAILED;
			}
		}
		else if(WIFSIGNALED(status)) {
			exit_code = 255;
			build_status = BUILD_FAILED;
		}

		for(int i = 0; i < res; i++) {
			free(env[i]);
		}
		free(env);
		free(distrib_type);

		log_printf(LOG_INFO, "Build is over with status %s.\n", build_statuses_str[build_status]);

		mkdir(home_output, 0666);
		system(move_output_cmd);


		system(upload_cmd);

		char *container_data = read_file(container_data_path);
		char *results = read_file("/tmp/results.json");
		char *commit_hash = read_file(commit_hash_path);
		if(commit_hash != NULL) {
			commit_hash[40] = '\0';
		}

		char *fail_reason = NULL;
		if (build_status == BUILD_FAILED) {
			fail_reason = read_file(fail_reason_path);
			if (fail_reason != NULL) {
				for (unsigned int i = 0; i < strlen(fail_reason); i++) {
					if (!isprint(fail_reason[i]) || fail_reason[i] == '"') {
						fail_reason[i] = ' ';
					}
				}
			}
		}

		char *args = xmalloc((container_data ? strlen(container_data) : 0) + (results ? strlen(results) : 0) + 2048);
		sprintf(args, build_completed_args_fmt, (results ? results : "[]"), \
				(container_data ? container_data : "{}"), exit_code, (commit_hash ? commit_hash : ""),
				(fail_reason ? fail_reason : ""));

		retries = 5;
		try = 0;
		while(retries) {
			log_printf(LOG_INFO, "Try #%d: Sending data to ABF\n", try + 1);
			if(!api_jobs_feedback(build_id, build_status, args)) {
				log_printf(LOG_INFO, "Data sent.\n");
				break;
			} else {
				log_printf(LOG_ERROR, "Failed to send data to ABF. Sleeping for %d seconds and retrying...\n", 1 << try);
			}
			retries--;
			sleep(1 << try);
			try++;
		}

		set_busy_status(0, NULL);
		free(args);
		free(build_id);

		if(commit_hash) {
			free(commit_hash);
		}
		if(results) {
			free(results);
		}
		if(container_data) {
			free(container_data);
		}
		if(fail_reason) {
			free(fail_reason);
		}
	}

	return 0;
}