diff --git a/src/packages/libkypackages.c b/src/packages/libkypackages.c index acf0318..7d3ddc5 100644 --- a/src/packages/libkypackages.c +++ b/src/packages/libkypackages.c @@ -33,6 +33,7 @@ #include #include #include +#include #define KDK_DEKSTOP_FILE_PATH "/usr/share/applications/" #define KDK_LOCALE_DEKSTOP_FILE_PATH "/.local/share/applications/" @@ -73,7 +74,7 @@ static inline char *read_key(char *buffer, const char *key) return NULL; } -static int get_desktop_info(char *dir_path, kdk_startmenu_list *programlist) +static int get_desktop_info(char *dir_path, kdk_app_info *programlist, int start_app) { char canonical_filename[4096] = {"\0"}; if (!realpath(dir_path, canonical_filename) || !verify_file(canonical_filename)) @@ -91,7 +92,7 @@ static int get_desktop_info(char *dir_path, kdk_startmenu_list *programlist) if (DT_DIR == dir_t->d_type) continue; - kdk_startmenu_t *curinfo = NULL; + kdk_app_t *curinfo = NULL; if (strstr(dir_t->d_name, ".desktop")) { char fpath[PROGRAM_SIZE] = {0}; @@ -112,8 +113,6 @@ static int get_desktop_info(char *dir_path, kdk_startmenu_list *programlist) return 0; } - - FILE *fp = fopen(filename, "r"); if (NULL == fp) { @@ -164,7 +163,7 @@ static int get_desktop_info(char *dir_path, kdk_startmenu_list *programlist) // 判断是否是显示在开始菜单的应用程序 if ((val = read_key(buffer, "NoDisplay="))) { - if (0 == strcmp(val, "true")) + if (0 == strcmp(val, "true") && start_app) { is_start_menu_app = 0; } @@ -174,11 +173,11 @@ static int get_desktop_info(char *dir_path, kdk_startmenu_list *programlist) if (is_start_menu_app) { - kdk_startmenu_t **tmp = (kdk_startmenu_t **)realloc(programlist->list, PROGRAM_SIZE * sizeof(kdk_startmenu_t *)); + kdk_app_t **tmp = (kdk_app_t **)realloc(programlist->list, PROGRAM_SIZE * sizeof(kdk_app_t *)); if (!tmp) return 0; - curinfo = (kdk_startmenu_t *)calloc(1, sizeof(kdk_startmenu_t)); + curinfo = (kdk_app_t *)calloc(1, sizeof(kdk_app_t)); if (!curinfo) return 0; @@ -258,7 +257,7 @@ static char *read_default_app(const char *filetype) } fp = fopen(canonical_filename, "r"); - if(NULL == fp) + if (NULL == fp) return NULL; while (fgets(line, 1024, fp)) @@ -343,6 +342,100 @@ kdk_package_list *kdk_package_get_packagelist() } while (feof(fp) == 0); fclose(fp); + + char *kaiming = "kaiming list"; + fp = popen(kaiming, "r"); + if (NULL != fp) + { + char line[1024]; + while (fgets(line, sizeof(line), fp)) + { + char name[256], id[256], branch[64], module[64], version[64], size[128], description[1024]; + int count = sscanf(line, "%s %s %s %s %s %s %s", name, id, branch, module, version, size, description); + if (count != 7) + continue; + if (0 == strcmp(name, "Name") && 0 == strcmp(id, "Id")) // 第一行表头 + continue; + + curpackage = (kdk_package_t *)calloc(1, sizeof(kdk_package_t)); + if (!curpackage) + goto err_out; + if (packagelist->nums == maxpackage) + { + maxpackage += PACKAGE_INCREASE_STEP; + kdk_package_t **tmp = (kdk_package_t **)realloc(packagelist->list, maxpackage * sizeof(kdk_package_t *)); + if (!tmp) + { + free(curpackage); + goto err_out; + } + packagelist->list = tmp; + } + packagelist->list[packagelist->nums] = curpackage; + packagelist->nums++; + + curpackage->name = strdup(name); + curpackage->version = strdup(version); + + char numericStr[20]; + int i = 0, j = 0; + + // 从字符串中提取数字部分到 numericStr + while ('\0' != size[i]) + { + if (isdigit(size[i])) + numericStr[j++] = size[i]; + i++; + } + numericStr[j] = '\0'; + + if (0 == strendwith(size, "B")) + curpackage->size_kb = atol(numericStr) / 1024; + if (0 == strendwith(size, "MB")) + curpackage->size_kb = atol(numericStr) * 1024; + if (0 == strendwith(size, "GB")) + curpackage->size_kb = atol(numericStr) * 1024 * 1024; + } + } + pclose(fp); + + char *kare = "kare -l"; + fp = popen(kare, "r"); + if (NULL != fp) + { + char line[1024]; + while (fgets(line, sizeof(line), fp)) + { + char name[256], version[64]; + int count = sscanf(line, "%s %s", name, version); + if (count != 2) + continue; + if (0 == strcmp(name, "软件包名")) // 第一行表头 + continue; + + curpackage = (kdk_package_t *)calloc(1, sizeof(kdk_package_t)); + if (!curpackage) + goto err_out; + if (packagelist->nums == maxpackage) + { + maxpackage += PACKAGE_INCREASE_STEP; + kdk_package_t **tmp = (kdk_package_t **)realloc(packagelist->list, maxpackage * sizeof(kdk_package_t *)); + if (!tmp) + { + free(curpackage); + goto err_out; + } + packagelist->list = tmp; + } + packagelist->list[packagelist->nums] = curpackage; + packagelist->nums++; + + curpackage->name = strdup(name); + curpackage->version = strdup(version); + } + } + pclose(fp); + return packagelist; err_out: @@ -384,6 +477,73 @@ void kdk_package_free_packagelist(kdk_package_list *pl) free(pl); } +InstallMethod kdk_package_get_installation_method(const char *name, const char *version) +{ + const char *dpkg = "dpkg -l"; + FILE *fp = popen(dpkg, "r"); + if (NULL != fp) + { + char *line[1024]; + while (fgets(line, sizeof(line), fp)) + { + char tmp_name[256], tmp_version[64]; + int count = sscanf(line, "%*s %s %s %*s %*s", tmp_name, tmp_version); + if (count != 2) + continue; + if (0 == strcmp(tmp_name, name) && 0 == strcmp(tmp_version, version)) + { + pclose(fp); + if (strstr(name, "kwre")) + return KWRE_METHOD; + else if (strstr(name, "kmre")) + return KMRE_METHOD; + else + return DPKG_METHOD; + } + } + } + + const char *kaiming = "kaiming list"; + fp = popen(kaiming, "r"); + if (NULL != fp) + { + char *line[1024]; + while (fgets(line, sizeof(line), fp)) + { + char tmp_name[256], tmp_version[64]; + int count = sscanf(line, "%s %*s %*s %*s %s %*s %*s", tmp_name, tmp_version); + if (count != 2) + continue; + if (0 == strcmp(tmp_name, name) && 0 == strcmp(tmp_version, version)) + { + pclose(fp); + return KM_METHOD; + } + } + } + + const char *kare = "kare -l"; + fp = popen(kare, "r"); + if (NULL != fp) + { + char *line[1024]; + while (fgets(line, sizeof(line), fp)) + { + char tmp_name[256], tmp_version[64]; + int count = sscanf(line, "%s %s", tmp_name, tmp_version); + if (count != 2) + continue; + if (0 == strcmp(tmp_name, name) && 0 == strcmp(tmp_version, version)) + { + pclose(fp); + return KARE_METHOD; + } + } + } + + return NONE_METHOD; +} + int kdk_package_install_package(const char *packagePath) { } @@ -412,7 +572,49 @@ char *kdk_package_get_version(const char *name) break; } fclose(fp); - return val ? strdup(val) : NULL; + + if (val) + return strdup(val); + + const char *kaiming = "kaiming list"; + fp = popen(kaiming, "r"); + if (NULL != fp) + { + char *line[1024]; + while (fgets(line, sizeof(line), fp)) + { + char tmp_name[256], tmp_version[64]; + int count = sscanf(line, "%s %*s %*s %*s %s %*s %*s", tmp_name, tmp_version); + if (count != 2) + continue; + if (0 == strcmp(tmp_name, name)) + { + pclose(fp); + return strdup(tmp_version); + } + } + } + + const char *kare = "kare -l"; + fp = popen(kare, "r"); + if (NULL != fp) + { + char *line[1024]; + while (fgets(line, sizeof(line), fp)) + { + char tmp_name[256], tmp_version[64]; + int count = sscanf(line, "%s %s", tmp_name, tmp_version); + if (count != 2) + continue; + if (0 == strcmp(tmp_name, name)) + { + pclose(fp); + return strdup(tmp_version); + } + } + } + + return NULL; } int kdk_package_is_installed(const char *name, const char *version) @@ -436,6 +638,50 @@ int kdk_package_is_installed(const char *name, const char *version) } } fclose(fp); + if (1 == flag) + return flag; + + const char *kaiming = "kaiming list"; + fp = popen(kaiming, "r"); + if (NULL != fp) + { + char *line[1024]; + while (fgets(line, sizeof(line), fp)) + { + char tmp_name[256], tmp_version[64]; + int count = sscanf(line, "%s %*s %*s %*s %s %*s %*s", tmp_name, tmp_version); + if (count != 2) + continue; + if (0 == strcmp(tmp_name, name) && 0 == strcmp(tmp_version, version)) + { + pclose(fp); + flag = 1; + break; + } + } + } + if (1 == flag) + return flag; + + const char *kare = "kare -l"; + fp = popen(kare, "r"); + if (NULL != fp) + { + char *line[1024]; + while (fgets(line, sizeof(line), fp)) + { + char tmp_name[256], tmp_version[64]; + int count = sscanf(line, "%s %s", tmp_name, tmp_version); + if (count != 2) + continue; + if (0 == strcmp(tmp_name, name) && 0 == strcmp(tmp_version, version)) + { + pclose(fp); + flag = 1; + break; + } + } + } return flag; } @@ -472,7 +718,30 @@ char *kdk_package_get_description(const char *name) } } fclose(fp); - return val ? strdup(result) : NULL; + + if (val) + return strdup(val); + + const char *kaiming = "kaiming list"; + fp = popen(kaiming, "r"); + if (NULL != fp) + { + char *line[1024]; + while (fgets(line, sizeof(line), fp)) + { + char tmp_name[256], description[1024]; + int count = sscanf(line, "%s %*s %*s %*s %*s %*s %s", tmp_name, description); + if (count != 2) + continue; + if (0 == strcmp(tmp_name, name)) + { + pclose(fp); + return strdup(description); + } + } + } + + return NULL; } char **kdk_package_get_code_path(const char *name) @@ -648,31 +917,51 @@ char *kdk_package_get_default_ppt_viewer(void) return read_default_app("application/wps-office.ppt"); } -kdk_startmenu_list *kdk_package_get_startmenu_list(void) +kdk_app_info* kdk_package_get_startmenu_list(void) { - kdk_startmenu_list *programlist = (kdk_startmenu_list *)calloc(1, sizeof(kdk_startmenu_list)); + kdk_app_info *programlist = (kdk_app_info *)calloc(1, sizeof(kdk_app_info)); if (!programlist) return NULL; - get_desktop_info(KDK_DEKSTOP_FILE_PATH, programlist); + get_desktop_info(KDK_DEKSTOP_FILE_PATH, programlist, 1); char *homeDir = getenv("HOME"); char *filepath[PROGRAM_SIZE] = {0}; sprintf(filepath, "%s%s", homeDir, KDK_LOCALE_DEKSTOP_FILE_PATH); - get_desktop_info(filepath, programlist); + get_desktop_info(filepath, programlist, 1); - get_desktop_info(KDK_SNAPD_DEKSTOP_FILE_PATH, programlist); + get_desktop_info(KDK_SNAPD_DEKSTOP_FILE_PATH, programlist, 1); - get_desktop_info(KDK_FLATPAK_DEKSTOP_FILE_PATH, programlist); + get_desktop_info(KDK_FLATPAK_DEKSTOP_FILE_PATH, programlist, 1); return programlist; } -void kdk_package_free_startmenu_list(kdk_startmenu_list *list) +void kdk_package_free_startmenu_list(kdk_app_info *list) { - if(NULL == list) + if (NULL == list) return; - for(int i = 0; i < list->nums; i++) + for (int i = 0; i < list->nums; i++) + free(list->list[i]); + free(list); +} + +kdk_app_info *kdk_package_get_application_list(void) +{ + kdk_app_info *programlist = (kdk_app_info *)calloc(1, sizeof(kdk_app_info)); + if (!programlist) + return NULL; + + get_desktop_info(KDK_DEKSTOP_FILE_PATH, programlist, 0); + + return programlist; +} + +void kdk_package_free_app_info(kdk_app_info *list) +{ + if (NULL == list) + return; + for (int i = 0; i < list->nums; i++) free(list->list[i]); free(list); } diff --git a/src/packages/libkypackages.h b/src/packages/libkypackages.h index 41f00bb..549f08e 100644 --- a/src/packages/libkypackages.h +++ b/src/packages/libkypackages.h @@ -46,6 +46,16 @@ extern "C" { #endif +typedef enum _InstallMethod +{ + NONE_METHOD, + DPKG_METHOD, + KM_METHOD, + KARE_METHOD, + KMRE_METHOD, + KWRE_METHOD +} InstallMethod; + typedef struct _kdk_package_t{ char *name; // 包名 char *version; // 版本号 @@ -60,7 +70,7 @@ typedef struct { kdk_package_t **list; }kdk_package_list; -typedef struct _kdk_startmenu_t +typedef struct _kdk_app_t { char *name; // 程序名称 char *version; // 版本号 @@ -68,13 +78,13 @@ typedef struct _kdk_startmenu_t char *cmd; // 可执行文件路径 char *param; // 启动参数 char *icon; // 图标信息 -} kdk_startmenu_t; +} kdk_app_t; -typedef struct _kdk_startmenu_list +typedef struct _kdk_app_info { unsigned int nums; //list成员个数 - kdk_startmenu_t **list; //开始菜单应用信息数组 -} kdk_startmenu_list; + kdk_app_t **list; //开始菜单应用信息数组 +} kdk_app_info; /** * @brief 获取系统中所有包列表 @@ -90,6 +100,15 @@ extern kdk_package_list* kdk_package_get_packagelist(); */ extern void kdk_package_free_packagelist(kdk_package_list *list); +/** + * @brief 判断指定包的安装方式,返回值为枚举类型 + * + * @param name 包名 + * @param version 版本 + * @return InstallMethod 安装模式枚举值 + */ +InstallMethod kdk_package_get_installation_method(const char *name, const char *version); + /** * @brief [未启用]安装指定的软件包 * @@ -223,16 +242,30 @@ extern char* kdk_package_get_default_ppt_viewer(void); /** * @brief 获取开始菜单中的所有应用信息 * - * @return kdk_startmenu_list* 开始菜单中的所有应用信息 + * @return kdk_app_info* 开始菜单中的所有应用信息 */ -extern kdk_startmenu_list* kdk_package_get_startmenu_list(void); +extern kdk_app_info* kdk_package_get_startmenu_list(void); /** - * @brief 释放kdk_package_get_startmenu_list的返回 + * @brief 释放kdk_app_info链表 * - * @param list kdk_package_get_startmenu_list返回的指针 + * @param list kdk_app_info链表 */ -extern void kdk_package_free_startmenu_list(kdk_startmenu_list *list); +extern void kdk_package_free_startmenu_list(kdk_app_info *list); + +/** + * @brief 获取所有应用信息 + * + * @return kdk_app_info* 所有应用信息 + */ +extern kdk_app_info* kdk_package_get_application_list(void); + +/** + * @brief 释放kdk_app_info链表 + * + * @param list kdk_app_info链表 + */ +extern void kdk_package_free_app_info(kdk_app_info *list); @@ -249,4 +282,4 @@ extern void kdk_package_free_startmenu_list(kdk_startmenu_list *list); /** * @} - */ + */ \ No newline at end of file diff --git a/src/packages/test/kypackage-test.c b/src/packages/test/kypackage-test.c index 203b178..43f433f 100644 --- a/src/packages/test/kypackage-test.c +++ b/src/packages/test/kypackage-test.c @@ -44,6 +44,29 @@ int main() } kdk_package_free_packagelist(list); + InstallMethod ret = kdk_package_get_installation_method("scram-gui", "0.16.2-1build2"); + switch (ret) + { + case DPKG_METHOD: + printf("Install method: %s", "dpkg"); + break; + case KM_METHOD: + printf("Install method: %s", "km"); + break; + case KARE_METHOD: + printf("Install method: %s", "kare"); + break; + case KMRE_METHOD: + printf("Install method: %s", "kmre"); + break; + case KWRE_METHOD: + printf("Install method: %s", "kwre"); + break; + default: + printf("Install method: %s", "None"); + break; + } + printf("Evolution是否安装:%s\n", kdk_package_is_installed("evolution", NULL) == 1 ? "是" : "否"); char *version = kdk_package_get_version("evolution"); printf("Evolution版本号:%s\n", version); @@ -85,12 +108,12 @@ int main() printf("%s\n", kdk_package_get_default_excel_viewer() ? kdk_package_get_default_excel_viewer() : "get execl failed"); printf("%s\n", kdk_package_get_default_ppt_viewer() ? kdk_package_get_default_ppt_viewer() : "get ppt failed"); - kdk_startmenu_list *start_menu_list = kdk_package_get_startmenu_list(); + kdk_app_info *start_menu_list = kdk_package_get_startmenu_list(); if (NULL != start_menu_list) { for (int i = 0; i < start_menu_list->nums; i++) { - kdk_startmenu_t *tmp = start_menu_list->list[i]; + kdk_app_t *tmp = start_menu_list->list[i]; printf("%s\n", tmp->cmd); printf("%s\n", tmp->company); printf("%s\n", tmp->icon); @@ -99,7 +122,24 @@ int main() printf("%s\n", tmp->version); printf("\n"); } - kdk_package_free_startmenu_list(start_menu_list); + kdk_package_free_app_info(start_menu_list); + } + + kdk_app_info *app_list = kdk_package_get_application_list(); + if (NULL != app_list) + { + for (int i = 0; i < app_list->nums; i++) + { + kdk_app_t *tmp = app_list->list[i]; + printf("%s\n", tmp->cmd); + printf("%s\n", tmp->company); + printf("%s\n", tmp->icon); + printf("%s\n", tmp->name); + printf("%s\n", tmp->param); + printf("%s\n", tmp->version); + printf("\n"); + } + kdk_package_free_app_info(app_list); } return 0;