static int max_backup_version(char *file, char *dir) { DIR *dirp; struct dirent *dp; int highest_version; int this_version; int file_name_length; dirp = opendir (dir); if (!dirp) return 0; highest_version = 0; file_name_length = strlen (file); while ((dp = readdir (dirp)) != 0) { if (!REAL_DIR_ENTRY (dp) || NLENGTH (dp) <= file_name_length) continue; this_version = version_number (file, dp->d_name, file_name_length); if (this_version > highest_version) highest_version = this_version; } closedir (dirp); return highest_version; }
TaskButton::TaskButton(IPane *parent, IPainter *backgroundPainter, IPainter *textPainter, IEventHandler *eventHandler, HWND window, TaskData &taskData) : mEventHandler(eventHandler) , mIconPainter(nullptr) , mMenu(nullptr) , mMenuWindow(nullptr) , mOverlayIconPainter(nullptr) , mTaskData(taskData) , mFlashInterval(0) , mWindow(window) { mIconPosition = NRECT(NLENGTH(0, 0, 0), NLENGTH(0, 0, 0), NLENGTH(0, 0, 32), NLENGTH(0, 0, 32)); mIconPainter = nCore::CreateImagePainter(); mIconPainter->SetPosition(mIconPosition, nullptr); mIconPainter->SetImage(nCore::GetWindowIcon(window, 32)); mOverlayIconPosition = NRECT(NLENGTH(0, 0, 16), NLENGTH(0, 0, 16), NLENGTH(0, 0, 32), NLENGTH(0, 0, 32)); mOverlayIconPainter = nCore::CreateImagePainter(); mOverlayIconPainter->SetPosition(mOverlayIconPosition, nullptr); PaneInitData initData; ZeroMemory(&initData, sizeof(PaneInitData)); initData.cbSize = sizeof(PaneInitData); initData.messageHandler = this; IPainter *painters[] = { backgroundPainter, textPainter, mIconPainter, mOverlayIconPainter }; initData.painters = painters; initData.numPainters = _countof(painters); initData.states = gButtonStates; initData.numStates = gNumButtonStates; mPane = parent->CreateChild(&initData); if (IsIconic(window)) { ActivateState(State::Minimized); } if (window == gActiveWindow) { ActivateState(State::Active); } wchar_t windowText[256]; GetWindowText(window, windowText, 256); mPane->SetText(windowText); // Reset the system menu for the window mMenu = GetSystemMenu(mWindow, FALSE); if (!IsMenu(mMenu)) { GetSystemMenu(mWindow, TRUE); mMenu = GetSystemMenu(mWindow, FALSE); } }
static int handle_dirent (dir_list * list, const char *fltr, struct dirent *dp, struct stat *buf1, int next_free, int *link_to_dir, int *stale_link) { vfs_path_t *vpath; if (dp->d_name[0] == '.' && dp->d_name[1] == 0) return 0; if (dp->d_name[0] == '.' && dp->d_name[1] == '.' && dp->d_name[2] == 0) return 0; if (!panels_options.show_dot_files && (dp->d_name[0] == '.')) return 0; if (!panels_options.show_backups && dp->d_name[NLENGTH (dp) - 1] == '~') return 0; vpath = vfs_path_from_str (dp->d_name); if (mc_lstat (vpath, buf1) == -1) { /* * lstat() fails - such entries should be identified by * buf1->st_mode being 0. * It happens on QNX Neutrino for /fs/cd0 if no CD is inserted. */ memset (buf1, 0, sizeof (*buf1)); } if (S_ISDIR (buf1->st_mode)) tree_store_mark_checked (dp->d_name); /* A link to a file or a directory? */ *link_to_dir = 0; *stale_link = 0; if (S_ISLNK (buf1->st_mode)) { struct stat buf2; if (mc_stat (vpath, &buf2) == 0) *link_to_dir = S_ISDIR (buf2.st_mode) != 0; else *stale_link = 1; } vfs_path_free (vpath); if (!(S_ISDIR (buf1->st_mode) || *link_to_dir) && (fltr != NULL) && !mc_search (fltr, dp->d_name, MC_SEARCH_T_GLOB)) return 0; /* Need to grow the *list? */ if (next_free == list->size && !grow_list (list)) return -1; return 1; }
// Taken from tsid uint32_t recurse(FILE *fmatched, char *dir) { uint32_t matches = 0; dirent *dp; struct stat st; DIR *dirp; char nbuf[MAX_PATH_LEN]; size_t len; SDEBUG("Recurse into directory " << dir << endl); dirp=opendir(dir); if (dirp==NULL) { SDEBUG(dir << " unreadable\n"); return 0; } while ((dp=readdir(dirp)) != NULL) { if (!strcmp(dp->d_name,".") || !strcmp(dp->d_name,"..")) continue; len=strlen(dir); if (len+NLENGTH(dp)+1 < MAX_PATH_LEN-1) { strcpy(nbuf,dir); if (len != 0) // dir = "" means current dir on Amiga nbuf[len++]='/'; strcpy(nbuf+len, dp->d_name); stat(nbuf, &st); if (S_ISDIR(st.st_mode)) matches += recurse(fmatched, nbuf); // recurse into directory if (S_ISREG(st.st_mode)) matches += analyse(fmatched, nbuf); // add the file } else { SDEBUG(dir << "/" << dp->d_name << ": pathname too long\n"); } } closedir(dirp); return matches; }
/* Sends the complete directory listing, as well as the stat information */ static void do_readdir (void) { struct dirent *dirent; struct stat st; int handle, n; rpc_get (msock, RPC_INT, &handle, RPC_END); if (!handle) { rpc_send (msock, RPC_INT, 0, RPC_END); return; } /* We incremented it in opendir */ handle--; while ((dirent = readdir (mcfs_DIR.dirs[handle]))) { int fname_len; char *fname; int length = NLENGTH (dirent); rpc_send (msock, RPC_INT, length, RPC_END); rpc_send (msock, RPC_BLOCK, length, dirent->d_name, RPC_END); fname_len = strlen (mcfs_DIR.names[handle]) + strlen (dirent->d_name) + 2; fname = malloc (fname_len); snprintf (fname, fname_len, "%s/%s", mcfs_DIR.names[handle], dirent->d_name); n = lstat (fname, &st); g_free (fname); send_status (n, errno); if (n >= 0) send_stat_info (&st); } rpc_send (msock, RPC_INT, 0, RPC_END); }
static char * filename_completion_function (const char *text, int state, input_complete_t flags) { static DIR *directory = NULL; static char *filename = NULL; static char *dirname = NULL; static char *users_dirname = NULL; static size_t filename_len; int isdir = 1, isexec = 0; static vfs_path_t *dirname_vpath = NULL; struct dirent *entry = NULL; SHOW_C_CTX ("filename_completion_function"); if (text && (flags & INPUT_COMPLETE_SHELL_ESC)) { char *u_text; char *result; char *e_result; u_text = strutils_shell_unescape (text); result = filename_completion_function (u_text, state, flags & (~INPUT_COMPLETE_SHELL_ESC)); g_free (u_text); e_result = strutils_shell_escape (result); g_free (result); return e_result; } /* If we're starting the match process, initialize us a bit. */ if (state == 0) { const char *temp; g_free (dirname); g_free (filename); g_free (users_dirname); vfs_path_free (dirname_vpath); if ((*text != '\0') && (temp = strrchr (text, PATH_SEP)) != NULL) { filename = g_strdup (++temp); dirname = g_strndup (text, temp - text); } else { dirname = g_strdup ("."); filename = g_strdup (text); } /* We aren't done yet. We also support the "~user" syntax. */ /* Save the version of the directory that the user typed. */ users_dirname = dirname; dirname = tilde_expand (dirname); canonicalize_pathname (dirname); dirname_vpath = vfs_path_from_str (dirname); /* Here we should do something with variable expansion and `command`. Maybe a dream - UNIMPLEMENTED yet. */ directory = mc_opendir (dirname_vpath); filename_len = strlen (filename); } /* Now that we have some state, we can read the directory. */ while (directory && (entry = mc_readdir (directory))) { if (!str_is_valid_string (entry->d_name)) continue; /* Special case for no filename. All entries except "." and ".." match. */ if (filename_len == 0) { if (DIR_IS_DOT (entry->d_name) || DIR_IS_DOTDOT (entry->d_name)) continue; } else { /* Otherwise, if these match up to the length of filename, then it may be a match. */ if ((entry->d_name[0] != filename[0]) || ((NLENGTH (entry)) < filename_len) || strncmp (filename, entry->d_name, filename_len)) continue; } isdir = 1; isexec = 0; { struct stat tempstat; vfs_path_t *tmp_vpath; tmp_vpath = vfs_path_build_filename (dirname, entry->d_name, (char *) NULL); /* Unix version */ if (mc_stat (tmp_vpath, &tempstat) == 0) { uid_t my_uid = getuid (); gid_t my_gid = getgid (); if (!S_ISDIR (tempstat.st_mode)) { isdir = 0; if ((!my_uid && (tempstat.st_mode & 0111)) || (my_uid == tempstat.st_uid && (tempstat.st_mode & 0100)) || (my_gid == tempstat.st_gid && (tempstat.st_mode & 0010)) || (tempstat.st_mode & 0001)) isexec = 1; } } else { /* stat failed, strange. not a dir in any case */ isdir = 0; } vfs_path_free (tmp_vpath); } if ((flags & INPUT_COMPLETE_COMMANDS) && (isexec || isdir)) break; if ((flags & INPUT_COMPLETE_CD) && isdir) break; if (flags & (INPUT_COMPLETE_FILENAMES)) break; } if (entry == NULL) { if (directory) { mc_closedir (directory); directory = NULL; } g_free (dirname); dirname = NULL; vfs_path_free (dirname_vpath); dirname_vpath = NULL; g_free (filename); filename = NULL; g_free (users_dirname); users_dirname = NULL; return NULL; } { GString *temp; temp = g_string_sized_new (16); if (users_dirname != NULL && (users_dirname[0] != '.' || users_dirname[1] != '\0')) { g_string_append (temp, users_dirname); /* We need a '/' at the end. */ if (temp->str[temp->len - 1] != PATH_SEP) g_string_append_c (temp, PATH_SEP); } g_string_append (temp, entry->d_name); if (isdir) g_string_append_c (temp, PATH_SEP); return g_string_free (temp, FALSE); } }
static enum numbered_backup_result numbered_backup (char **buffer, size_t buffer_size, size_t filelen) { enum numbered_backup_result result = BACKUP_IS_NEW; DIR *dirp; struct dirent *dp; char *buf = *buffer; size_t versionlenmax = 1; char *base = base_name (buf); size_t base_offset = base - buf; size_t baselen = base_len (base); /* Temporarily modify the buffer into its parent directory name, open the directory, and then restore the buffer. */ char tmp[sizeof "."]; memcpy (tmp, base, sizeof "."); strcpy (base, "."); dirp = opendir (buf); memcpy (base, tmp, sizeof "."); strcpy (base + baselen, ".~1~"); if (!dirp) return result; while ((dp = readdir (dirp)) != NULL) { char const *p; char *q; bool all_9s; size_t versionlen; size_t new_buflen; if (! REAL_DIR_ENTRY (dp) || NLENGTH (dp) < baselen + 4) continue; if (memcmp (buf + base_offset, dp->d_name, baselen + 2) != 0) continue; p = dp->d_name + baselen + 2; /* Check whether this file has a version number and if so, whether it is larger. Use string operations rather than integer arithmetic, to avoid problems with integer overflow. */ if (! ('1' <= *p && *p <= '9')) continue; all_9s = (*p == '9'); for (versionlen = 1; ISDIGIT (p[versionlen]); versionlen++) all_9s &= (p[versionlen] == '9'); if (! (p[versionlen] == '~' && !p[versionlen + 1] && (versionlenmax < versionlen || (versionlenmax == versionlen && memcmp (buf + filelen + 2, p, versionlen) <= 0)))) continue; /* This directory has the largest version number seen so far. Append this highest numbered extension to the file name, prepending '0' to the number if it is all 9s. */ versionlenmax = all_9s + versionlen; result = (all_9s ? BACKUP_IS_LONGER : BACKUP_IS_SAME_LENGTH); new_buflen = filelen + 2 + versionlenmax + 1; if (buffer_size <= new_buflen) { buf = xnrealloc (buf, 2, new_buflen); buffer_size = new_buflen * 2; } q = buf + filelen; *q++ = '.'; *q++ = '~'; *q = '0'; q += all_9s; memcpy (q, p, versionlen + 2); /* Add 1 to the version number. */ q += versionlen; while (*--q == '9') *q = '0'; ++*q; } closedir (dirp); *buffer = buf; return result; }
static char * filename_completion_function (char *text, int state) { static DIR *directory; static char *filename = NULL; static char *dirname = NULL; static char *users_dirname = NULL; static size_t filename_len; int isdir = 1, isexec = 0; struct dirent *entry = NULL; /* If we're starting the match process, initialize us a bit. */ if (!state){ const char *temp; g_free (dirname); g_free (filename); g_free (users_dirname); if ((*text) && (temp = strrchr (text, PATH_SEP))){ filename = g_strdup (++temp); dirname = g_strndup (text, temp - text); } else { dirname = g_strdup ("."); filename = g_strdup (text); } /* We aren't done yet. We also support the "~user" syntax. */ /* Save the version of the directory that the user typed. */ users_dirname = dirname; { dirname = tilde_expand (dirname); canonicalize_pathname (dirname); /* Here we should do something with variable expansion and `command`. Maybe a dream - UNIMPLEMENTED yet. */ } directory = mc_opendir (dirname); filename_len = strlen (filename); } /* Now that we have some state, we can read the directory. */ while (directory && (entry = mc_readdir (directory))){ /* Special case for no filename. All entries except "." and ".." match. */ if (!filename_len){ if (!strcmp (entry->d_name, ".") || !strcmp (entry->d_name, "..")) continue; } else { /* Otherwise, if these match up to the length of filename, then it may be a match. */ if ((entry->d_name[0] != filename[0]) || ((NLENGTH (entry)) < filename_len) || strncmp (filename, entry->d_name, filename_len)) continue; } isdir = 1; isexec = 0; { char *tmp = g_malloc (3 + strlen (dirname) + NLENGTH (entry)); struct stat tempstat; strcpy (tmp, dirname); strcat (tmp, PATH_SEP_STR); strcat (tmp, entry->d_name); canonicalize_pathname (tmp); /* Unix version */ if (!mc_stat (tmp, &tempstat)){ uid_t my_uid = getuid (); gid_t my_gid = getgid (); if (!S_ISDIR (tempstat.st_mode)){ isdir = 0; if ((!my_uid && (tempstat.st_mode & 0111)) || (my_uid == tempstat.st_uid && (tempstat.st_mode & 0100)) || (my_gid == tempstat.st_gid && (tempstat.st_mode & 0010)) || (tempstat.st_mode & 0001)) isexec = 1; } } g_free (tmp); } switch (look_for_executables) { case 2: if (!isexec) continue; break; case 1: if (!isexec && !isdir) continue; break; } if (ignore_filenames && !isdir) continue; break; } if (!entry){ if (directory){ mc_closedir (directory); directory = NULL; } g_free (dirname); dirname = NULL; g_free (filename); filename = NULL; g_free (users_dirname); users_dirname = NULL; return NULL; } else { char *temp; if (users_dirname && (users_dirname[0] != '.' || users_dirname[1])){ int dirlen = strlen (users_dirname); temp = g_malloc (3 + dirlen + NLENGTH (entry)); strcpy (temp, users_dirname); /* We need a `/' at the end. */ if (users_dirname[dirlen - 1] != PATH_SEP){ temp[dirlen] = PATH_SEP; temp[dirlen + 1] = 0; } strcat (temp, entry->d_name); } else { temp = g_malloc (2 + NLENGTH (entry)); strcpy (temp, entry->d_name); } if (isdir) strcat (temp, PATH_SEP_STR); return temp; } }
int do_reload_dir (const vfs_path_t * vpath, dir_list * list, sortfn * sort, int count, gboolean lc_reverse, gboolean lc_case_sensitive, gboolean exec_ff, const char *fltr) { DIR *dirp; struct dirent *dp; int next_free = 0; int i, status, link_to_dir, stale_link; struct stat st; int marked_cnt; GHashTable *marked_files; const char *tmp_path; dirp = mc_opendir (vpath); if (dirp == NULL) { message (D_ERROR, MSG_ERROR, _("Cannot read directory contents")); clean_dir (list, count); return set_zero_dir (list) ? 1 : 0; } tree_store_start_check (vpath); marked_files = g_hash_table_new (g_str_hash, g_str_equal); alloc_dir_copy (list->size); for (marked_cnt = i = 0; i < count; i++) { dir_copy.list[i].fnamelen = list->list[i].fnamelen; dir_copy.list[i].fname = list->list[i].fname; dir_copy.list[i].f.marked = list->list[i].f.marked; dir_copy.list[i].f.dir_size_computed = list->list[i].f.dir_size_computed; dir_copy.list[i].f.link_to_dir = list->list[i].f.link_to_dir; dir_copy.list[i].f.stale_link = list->list[i].f.stale_link; dir_copy.list[i].sort_key = NULL; dir_copy.list[i].second_sort_key = NULL; if (list->list[i].f.marked) { g_hash_table_insert (marked_files, dir_copy.list[i].fname, &dir_copy.list[i]); marked_cnt++; } } /* Add ".." except to the root directory. The ".." entry (if any) must be the first in the list. */ tmp_path = vfs_path_get_by_index (vpath, 0)->path; if (! (vfs_path_elements_count (vpath) == 1 && (tmp_path[0] == PATH_SEP) && (tmp_path[1] == '\0'))) { if (!set_zero_dir (list)) { clean_dir (list, count); clean_dir (&dir_copy, count); return next_free; } if (get_dotdot_dir_stat (vpath, &st)) list->list[next_free].st = st; next_free++; } while ((dp = mc_readdir (dirp))) { status = handle_dirent (list, fltr, dp, &st, next_free, &link_to_dir, &stale_link); if (status == 0) continue; if (status == -1) { mc_closedir (dirp); /* Norbert (Feb 12, 1997): Just in case someone finds this memory leak: -1 means big trouble (at the moment no memory left), I don't bother with further cleanup because if one gets to this point he will have more problems than a few memory leaks and because one 'clean_dir' would not be enough (and because I don't want to spent the time to make it working, IMHO it's not worthwhile). clean_dir (&dir_copy, count); */ tree_store_end_check (); g_hash_table_destroy (marked_files); return next_free; } list->list[next_free].f.marked = 0; /* * If we have marked files in the copy, scan through the copy * to find matching file. Decrease number of remaining marks if * we copied one. */ if (marked_cnt > 0) { if ((g_hash_table_lookup (marked_files, dp->d_name))) { list->list[next_free].f.marked = 1; marked_cnt--; } } list->list[next_free].fnamelen = NLENGTH (dp); list->list[next_free].fname = g_strndup (dp->d_name, list->list[next_free].fnamelen); list->list[next_free].f.link_to_dir = link_to_dir; list->list[next_free].f.stale_link = stale_link; list->list[next_free].f.dir_size_computed = 0; list->list[next_free].st = st; list->list[next_free].sort_key = NULL; list->list[next_free].second_sort_key = NULL; next_free++; if (!(next_free % 16)) rotate_dash (); } mc_closedir (dirp); tree_store_end_check (); g_hash_table_destroy (marked_files); if (next_free) { do_sort (list, sort, next_free - 1, lc_reverse, lc_case_sensitive, exec_ff); } clean_dir (&dir_copy, count); return next_free; }
int do_load_dir (const vfs_path_t * vpath, dir_list * list, sortfn * sort, gboolean lc_reverse, gboolean lc_case_sensitive, gboolean exec_ff, const char *fltr) { DIR *dirp; struct dirent *dp; int status, link_to_dir, stale_link; int next_free = 0; struct stat st; char *path; /* ".." (if any) must be the first entry in the list */ if (!set_zero_dir (list)) return next_free; if (get_dotdot_dir_stat (vpath, &st)) list->list[next_free].st = st; next_free++; dirp = mc_opendir (vpath); if (dirp == NULL) { message (D_ERROR, MSG_ERROR, _("Cannot read directory contents")); return next_free; } tree_store_start_check (vpath); /* Do not add a ".." entry to the root directory */ path = vfs_path_to_str (vpath); if ((path[0] == PATH_SEP) && (path[1] == '\0')) next_free--; g_free (path); while ((dp = mc_readdir (dirp)) != NULL) { status = handle_dirent (list, fltr, dp, &st, next_free, &link_to_dir, &stale_link); if (status == 0) continue; if (status == -1) goto ret; list->list[next_free].fnamelen = NLENGTH (dp); list->list[next_free].fname = g_strndup (dp->d_name, list->list[next_free].fnamelen); list->list[next_free].f.marked = 0; list->list[next_free].f.link_to_dir = link_to_dir; list->list[next_free].f.stale_link = stale_link; list->list[next_free].f.dir_size_computed = 0; list->list[next_free].st = st; list->list[next_free].sort_key = NULL; list->list[next_free].second_sort_key = NULL; next_free++; if ((next_free & 31) == 0) rotate_dash (); } if (next_free != 0) do_sort (list, sort, next_free - 1, lc_reverse, lc_case_sensitive, exec_ff); ret: mc_closedir (dirp); tree_store_end_check (); return next_free; }