/* Return a new string which is the result of tilde expanding STRING. */ char * tilde_expand (char *string) { char *result; int result_size, result_index; result_size = result_index = 0; result = (char *)NULL; /* Scan through STRING expanding tildes as we come to them. */ while (1) { register int start, end; char *tilde_word, *expansion; int len; /* Make START point to the tilde which starts the expansion. */ start = tilde_find_prefix (string, &len); /* Copy the skipped text into the result. */ if ((result_index + start + 1) > result_size) result = (char *)xrealloc (result, 1 + (result_size += (start + 20))); strncpy (result + result_index, string, start); result_index += start; /* Advance STRING to the starting tilde. */ string += start; /* Make END be the index of one after the last character of the username. */ end = tilde_find_suffix (string); /* If both START and END are zero, we are all done. */ if (!start && !end) break; /* Expand the entire tilde word, and copy it into RESULT. */ tilde_word = (char *)xmalloc (1 + end); strncpy (tilde_word, string, end); tilde_word[end] = '\0'; string += end; expansion = tilde_expand_word (tilde_word); free (tilde_word); len = strlen (expansion); if ((result_index + len + 1) > result_size) result = (char *)xrealloc (result, 1 + (result_size += (len + 20))); strcpy (result + result_index, expansion); result_index += len; free (expansion); } result[result_index] = '\0'; return (result); }
void maybe_build_dir_node (char *dirname) { int path_index, update_tags; char *this_dir; FILE_BUFFER *dir_buffer = info_find_file (dirname); /* If there is no "dir" in the current info path, we cannot build one from nothing. */ if (!dir_buffer) return; /* If this directory has already been built, return now. */ if (dir_buffer->flags & N_CannotGC) return; /* Initialize the list we use to avoid reading the same dir file twice with the dir file just found. */ new_dir_file_p (&dir_buffer->finfo); update_tags = 0; /* Using each element of the path, check for one of the files in DIRS_TO_ADD. Do not check for "localdir.info.Z" or anything else. Only files explictly named are eligible. This is a design decision. There can be an info file name "localdir.info" which contains information on the setting up of "localdir" files. */ for (this_dir = infopath_first (&path_index); this_dir; this_dir = infopath_next (&path_index)) { register int da_index; char *from_file; /* Expand a leading tilde if one is present. */ if (*this_dir == '~') { char *tilde_expanded_dirname; tilde_expanded_dirname = tilde_expand_word (this_dir); if (tilde_expanded_dirname != this_dir) { free (this_dir); this_dir = tilde_expanded_dirname; } } /* For every different file named in DIRS_TO_ADD found in the search path, add that file's menu to our "dir" node. */ for (da_index = 0; (from_file = dirs_to_add[da_index]); da_index++) { struct stat finfo; int statable; int namelen = strlen (from_file); char *fullpath = xmalloc (3 + strlen (this_dir) + namelen); strcpy (fullpath, this_dir); if (!IS_SLASH (fullpath[strlen (fullpath) - 1])) strcat (fullpath, "/"); strcat (fullpath, from_file); statable = (stat (fullpath, &finfo) == 0); /* Only add this file if we have not seen it before. */ if (statable && S_ISREG (finfo.st_mode) && new_dir_file_p (&finfo)) { size_t filesize; int compressed; char *contents = filesys_read_info_file (fullpath, &filesize, &finfo, &compressed); if (contents) { update_tags++; add_menu_to_file_buffer (contents, filesize, dir_buffer); free (contents); } } free (fullpath); } free (this_dir); } if (update_tags) build_tags_and_nodes (dir_buffer); /* Flag that the dir buffer has been built. */ dir_buffer->flags |= N_CannotGC; }
char * info_find_fullpath (char *partial) { int initial_character; char *temp; filesys_error_number = 0; maybe_initialize_infopath (); if (partial && (initial_character = *partial)) { char *expansion; expansion = lookup_info_filename (partial); if (expansion) return expansion; /* If we have the full path to this file, we still may have to add various extensions to it. I guess we have to stat this file after all. */ if (IS_ABSOLUTE (partial)) temp = info_absolute_file (partial); else if (initial_character == '~') { expansion = tilde_expand_word (partial); if (IS_ABSOLUTE (expansion)) { temp = info_absolute_file (expansion); free (expansion); } else temp = expansion; } else if (initial_character == '.' && (IS_SLASH (partial[1]) || (partial[1] == '.' && IS_SLASH (partial[2])))) { if (local_temp_filename_size < 1024) local_temp_filename = xrealloc (local_temp_filename, (local_temp_filename_size = 1024)); #if defined (HAVE_GETCWD) if (!getcwd (local_temp_filename, local_temp_filename_size)) #else /* !HAVE_GETCWD */ if (!getwd (local_temp_filename)) #endif /* !HAVE_GETCWD */ { filesys_error_number = errno; return partial; } strcat (local_temp_filename, "/"); strcat (local_temp_filename, partial); temp = info_absolute_file (local_temp_filename); /* try extensions */ if (!temp) partial = local_temp_filename; } else temp = info_file_in_path (partial, infopath); if (temp) { remember_info_filename (partial, temp); if (strlen (temp) > (unsigned int) local_temp_filename_size) local_temp_filename = xrealloc (local_temp_filename, (local_temp_filename_size = (50 + strlen (temp)))); strcpy (local_temp_filename, temp); free (temp); return local_temp_filename; } } return partial; }
/* Scan the list of directories in PATH looking for FILENAME. If we find one that is a regular file, return it as a new string. Otherwise, return a NULL pointer. */ static char * info_file_in_path (char *filename, char *path) { struct stat finfo; char *temp_dirname; int statable, dirname_index; /* Reject ridiculous cases up front, to prevent infinite recursion later on. E.g., someone might say "info '(.)foo'"... */ if (!*filename || STREQ (filename, ".") || STREQ (filename, "..")) return NULL; dirname_index = 0; while ((temp_dirname = extract_colon_unit (path, &dirname_index))) { register int i, pre_suffix_length; char *temp; /* Expand a leading tilde if one is present. */ if (*temp_dirname == '~') { char *expanded_dirname; expanded_dirname = tilde_expand_word (temp_dirname); free (temp_dirname); temp_dirname = expanded_dirname; } temp = xmalloc (30 + strlen (temp_dirname) + strlen (filename)); strcpy (temp, temp_dirname); if (!IS_SLASH (temp[(strlen (temp)) - 1])) strcat (temp, "/"); strcat (temp, filename); pre_suffix_length = strlen (temp); free (temp_dirname); for (i = 0; info_suffixes[i]; i++) { strcpy (temp + pre_suffix_length, info_suffixes[i]); statable = (stat (temp, &finfo) == 0); /* If we have found a regular file, then use that. Else, if we have found a directory, look in that directory for this file. */ if (statable) { if (S_ISREG (finfo.st_mode)) { return temp; } else if (S_ISDIR (finfo.st_mode)) { char *newpath, *filename_only, *newtemp; newpath = xstrdup (temp); filename_only = filename_non_directory (filename); newtemp = info_file_in_path (filename_only, newpath); free (newpath); if (newtemp) { free (temp); return newtemp; } } } else { /* Add various compression suffixes to the name to see if the file is present in compressed format. */ register int j, pre_compress_suffix_length; pre_compress_suffix_length = strlen (temp); for (j = 0; compress_suffixes[j].suffix; j++) { strcpy (temp + pre_compress_suffix_length, compress_suffixes[j].suffix); statable = (stat (temp, &finfo) == 0); if (statable && (S_ISREG (finfo.st_mode))) return temp; } } } free (temp); } return NULL; }