#include "conf-update.h" char **get_listing(char *cmd, char *delim) { FILE *pipe; char *buf = NULL; size_t bufsize = 0; ssize_t read; char **listing; int count = 1, i = 0; unsigned int j; char c; pipe = popen(cmd, "r"); if (pipe) { read = getdelim(&buf, &bufsize, '\0', pipe); char *buf_backup = buf; if (read != -1) { // determine number of tokens while ((c = buf[i]) != '\0') { for (j=0;jname = strdup("/"); root->children = malloc(sizeof(struct node *)); root->ct_children = 0; root->parent = NULL; root->dir = TRUE; root->link = NULL; for (i=0;!is_last_entry(list[i]);i++) { if (is_valid_entry(list[i])) { endtok = list[i]+1; run = 1; while (run) { if (run == 2) { // 2 means we're on the last run run = 0; endtok = list[i] + strlen(list[i]) + 1; } else { if ((endtok = strchr(endtok+1, '/')) == NULL) { run = 2; } } curtok = strndup(list[i], endtok - list[i]); mynode = find_node(root, curtok); if (mynode == (struct node *)FALSE) { mynode = root; } if (mynode != (struct node *)TRUE) { // mynode is the parent of the new to be inserted node newnode = malloc(sizeof(struct node)); newnode->name = strdup(curtok); if (!strcmp(curtok,list[i])) { // it's the file newnode->dir = FALSE; newnode->link = &list[i]; } else { newnode->dir = TRUE; newnode->link = NULL; } newnode->children = malloc(sizeof(struct node *)); newnode->ct_children = 0; newnode->parent = mynode; mynode->ct_children++; mynode->children = realloc(mynode->children, sizeof(struct node *) * mynode->ct_children); mynode->children[mynode->ct_children-1] = newnode; } free(curtok); } } } return root; } struct node *find_node(struct node *root, char *path) { int i; struct node *mynode; if (!strcmp(root->name, path)) { // already exists return (struct node *)TRUE; } else if (!strncmp(root->name, path, strlen(root->name)) && root->dir == TRUE) { // at least it's in the same direction, go through the list of children for (i=0;ict_children;i++) { mynode = find_node(root->children[i], path); if (mynode == (struct node *)TRUE) { return (struct node *)TRUE; } else if (mynode != (struct node *)FALSE) { return mynode; } } // if we hit this point, nothing was found, meaning that it has to be a child of the current node return root; } else { // completely wrong return (struct node *)FALSE; } } void sanity_checks() { extern struct configuration config; unsigned int i; FILE *pipe; char *cmd = NULL; char *tools[] = { "diff", "portageq", strndup(config.pager, strchrnul(config.pager, ' ') - config.pager), strndup(config.diff_tool, strchrnul(config.diff_tool, ' ') - config.diff_tool), strndup(config.merge_tool, strchrnul(config.merge_tool, ' ') - config.merge_tool), strndup(config.edit_tool, strchrnul(config.edit_tool, ' ') - config.edit_tool) }; gchar *program_in_path; if (getuid() != 0) { fprintf(stderr, "!!! Oops, you're not root!\n"); exit(EXIT_FAILURE); } for (i=0;iparent)) { ct_indents++; } indent_name = calloc(width + 1, sizeof(char)); if ((start = strstr(update->name, "._cfg"))) { name = start+strlen("._cfg????_"); while (ct_indents > 0) { strcat(indent_name, INDENT_STR); ct_indents--; } strcat(indent_name, name); strcat(indent_name, " ("); strncpy(number, start+strlen("._cfg"), 4); num = atoi(number) + 1; snprintf(indent_name + strlen(indent_name), 4, "%d", num); strcat(indent_name, ")"); if (*(name - 1) == '-') { strcat(indent_name, "(merged)"); } } else { start = strrchr(update->name, '/') + 1; while (ct_indents > 0) { strcat(indent_name, INDENT_STR); ct_indents--; } strcat(indent_name, start); strcat(indent_name, "/"); } remainder = width - strlen(indent_name); for(i=0;ict_children;i++) { count += count_array_items(root->children[i]); } return 1 + count; } void build_item_array(ITEM **item_array, struct node *root, int menu_width) { int i = 0; // fast-forward to the next NULL entry while (item_array[i]) { i++; } item_array[i] = new_item(get_indent_name(root, menu_width), ""); set_item_userptr(item_array[i], root->link); for (i=0;ict_children;i++) { build_item_array(item_array, root->children[i], menu_width); } } void free_folded(struct node *root) { int i; for (i=0;ict_children;i++) { free_folded(root->children[i]); } // if (root->dir) { // it seems name is assigned unconditionally since $sometime free(root->name); // } free(root->children); free(root); } bool get_confirmation(WINDOW *win, char *action) { bool result; echo(); nocbreak(); char ret[2] = " "; wattron(win, COLOR_PAIR(4)); wattroff(win, A_BOLD); // TODO: replace COLS - 4/LINES - 7 with a function to determine size of inner mvwprintw(win, LINES - 6, 2, "Do you really want to "); wprintw(win, action); wprintw(win, " all selected updates? [y/n] "); refresh(); wgetnstr(win, ret, 1); if (!strcmp(ret,"y")) { result = true; } else { result = false; } mvwhline(win, LINES - 6, 1, ' ', COLS - 4 -2); noecho(); cbreak(); return result; } void exit_error(bool expr, char *hint) { if (!expr) { endwin(); char *mystring = calloc(sizeof(char), strlen("!!! ERROR: ") + strlen(hint) + 1); sprintf(mystring, "!!! ERROR: %s", hint); perror(mystring); exit(EXIT_FAILURE); } } char **get_files_list(char *searchpath, char **index, int *max) { struct stat mystat, tmpstat; int i = 0, j; DIR *dirfd; struct dirent *file = (struct dirent *)TRUE; char *absfile; char *myfile; bool ignore; if(-1 == lstat(searchpath, &mystat)) { return index; } if (S_ISDIR(mystat.st_mode)) { dirfd = opendir(searchpath); if (dirfd) { while (file) { file = readdir(dirfd); if (file && strcmp(file->d_name, ".") && strcmp(file->d_name, "..") && \ strcmp(file->d_name, ".svn") && strcmp(file->d_name, "CVS")) { absfile = (char *)calloc((strlen(searchpath) + strlen("/") + strlen(file->d_name) + 1), sizeof(char *)); strcpy(absfile, searchpath); strcat(absfile, "/"); strcat(absfile, file->d_name); index = get_files_list(absfile, index, max); free(absfile); } } } else if (errno == ENOENT) { return index; } else { exit_error(0, searchpath); } closedir(dirfd); } else if (S_ISREG(mystat.st_mode)) { if (!strncmp(strrchr(searchpath, '/')+1, "._cfg", strlen("._cfg"))) { if (*(searchpath+strlen(searchpath)-1) != '~' && \ strcmp(searchpath+strlen(searchpath)-4,".bak")) { myfile = get_real_filename(searchpath); if (access(myfile, F_OK) != 0) { // we don't want phantom updates unlink(searchpath); } else { // we don't want duplicates either ignore = FALSE; for (j=0;j<(*max) && index[j] != LAST_ENTRY;j++) { lstat(index[j], &tmpstat); if (tmpstat.st_dev == mystat.st_dev && \ tmpstat.st_ino == mystat.st_ino) { ignore = TRUE; } } if (!ignore) { while (i < (*max) && !is_last_entry(index[i])) { i++; } if (i + 1 >= (*max)) { (*max)++; index = (char **)realloc(index, (*max) * sizeof(char *)); } index[i] = strdup(searchpath); index[i+1] = LAST_ENTRY; } } free(myfile); } } } return index; }