📄 searchlink.c
字号:
#ifndef lintstatic char sccsid[] = "@(#)searchlink.c 1.1 92/07/30 Copyr 1988 Sun Micro";#endif/* * Copyright (c) 1987 Sun Microsystems, Inc. *//* * Library routines to read/write .tfs_info files, which contain * searchlinks, backlinks, and whiteout information. These routines * are called by the tfsd and by preserve, which creates rev-trees * behind the tfsd's back, and so needs to look at .tfs_info files * directly. */#include <nse/stdio.h>#include <strings.h>#include <errno.h>#include <sys/stat.h>#include <nse/param.h>#include <nse/util.h>#include <nse/searchlink.h>#include <nse/file_err.h>#define STRIP_EOLN(string) string[strlen(string) - 1] = '\0';static Nse_err tfs_file_move();static Nse_err tfs_file_read();static Nse_err do_file_read();static Nse_err tfs_file_write();static Nse_err write_tfs_file_contents();static Nse_err tfs_fgets();/* * Returns the searchlink of 'directory' in the string 'name' (which should * be MAXPATHLEN chars long.) If there is no searchlink for the directory, * ENOENT is returned as the error code. */Nse_errnse_get_searchlink(directory, name) char *directory; char *name;{ Nse_err result; result = tfs_file_read(directory, name, (int *) NULL, (Nse_whiteout *) NULL, (Nse_whiteout *) NULL, (FILE **) NULL); if ((result == NULL) && (name[0] == '\0')) { errno = ENOENT; result = nse_err_format_errno("Tfs read of searchlink in directory \"%s\"", directory); } return (result);}/* * Set searchlink of 'directory' to 'name', regardless of whether or not a * searchlink already exists for 'directory'. */Nse_errnse_set_searchlink(directory, name) char *directory; char *name;{ FILE *file; char old_link[MAXPATHLEN]; int blct; Nse_whiteout bl; Nse_whiteout wo; Nse_err result; if (result = tfs_file_read(directory, old_link, &blct, &bl, &wo, &file)) { return (result); } result = tfs_file_write(directory, name, blct, bl, wo, file); nse_dispose_whiteout(bl); nse_dispose_whiteout(wo); return (result);}/* * Set the searchlink of 'directory' to 'name' only if 'directory' does not * already have a searchlink. An error code is returned in two cases: * either the directory already has a searchlink which has a value * different from 'name', in which case NSE_SL_ALREADY_SET_DIFF is * returned and 'old_name' contains the old searchlink; or an error * occurred, in which case the intro(2) error code is returned. * * The boolean pointed at by `changedp' is set to indicate if the * searchlink changed. */Nse_errnse_set_cond_searchlink(directory, name, old_name, changedp) char *directory; char *name; char *old_name; bool_t *changedp;{ FILE *file; Nse_whiteout wo; int blct; Nse_whiteout bl; Nse_err result; *changedp = FALSE; if (result = tfs_file_read(directory, old_name, &blct, &bl, &wo, &file)) { return (result); } if (old_name[0] != '\0') { fclose(file); if (!NSE_STREQ(name, old_name)) { result = nse_err_format(NSE_SL_ALREADY_SET_DIFF, directory); } } else { *changedp = TRUE; result = tfs_file_write(directory, name, blct, bl, wo, file); } nse_dispose_whiteout(bl); nse_dispose_whiteout(wo); return (result);}/* * Returns list of white-out entries in directory. */Nse_errnse_get_whiteout(directory, wop) char *directory; Nse_whiteout *wop;{ char searchlink[MAXPATHLEN]; return tfs_file_read(directory, searchlink, (int *) NULL, (Nse_whiteout *) NULL, wop, (FILE **) NULL);}/* * Set a new whiteout entry 'name' in 'directory'. This function is a * no-op if whiteout entry 'name' is already set for the directory. */Nse_errnse_set_whiteout(directory, name) char *directory; char *name;{ FILE *file; char searchlink[MAXPATHLEN]; int blct; Nse_whiteout bl; Nse_whiteout wo_first; Nse_whiteout wo; int found = 0; Nse_err result; if (result = tfs_file_read(directory, searchlink, &blct, &bl, &wo_first, &file)) { return (result); } wo = wo_first; while (wo != NULL) { if (NSE_STREQ(name, wo->name)) { found = 1; break; } wo = wo->next; } if (found) { fclose(file); } else { wo = NSE_NEW(Nse_whiteout); wo->name = NSE_STRDUP(name); wo->next = wo_first; wo_first = wo; result = tfs_file_write(directory, searchlink, blct, bl, wo_first, file); } nse_dispose_whiteout(bl); nse_dispose_whiteout(wo_first); return (result);}/* * Clear whiteout entry 'name' from the whiteout list of 'directory'. If * 'name' is not in the whiteout list of 'directory', 0 is returned. */Nse_errnse_clear_whiteout(directory, name) char *directory; char *name;{ FILE *file; char searchlink[MAXPATHLEN]; int blct; Nse_whiteout bl; Nse_whiteout wo_first; Nse_whiteout wo; Nse_whiteout wo_prev = NULL; int found = 0; Nse_err result; if (result = tfs_file_read(directory, searchlink, &blct, &bl, &wo_first, &file)) { return (result); } wo = wo_first; while (wo != NULL) { if (NSE_STREQ(name, wo->name)) { found = 1; break; } wo_prev = wo; wo = wo->next; } if (found) { if (wo_prev == NULL) { wo_first = wo->next; } else { wo_prev->next = wo->next; } free(wo->name); free((char *) wo); result = tfs_file_write(directory, searchlink, blct, bl, wo_first, file); } else { fclose(file); } nse_dispose_whiteout(bl); nse_dispose_whiteout(wo_first); return (result);}/* * Purge all whiteout info from a tfs file and replace search link. * */Nse_errnse_purge_whiteout(directory, newlink) char *directory; char *newlink;{ FILE *file; char searchlink[MAXPATHLEN]; int blct; Nse_whiteout bl; Nse_whiteout wo; Nse_err result; if (result = tfs_file_read(directory, searchlink, &blct, &bl, &wo, &file)) { return result; } nse_dispose_whiteout(wo); result = tfs_file_write(directory, newlink, blct, bl, (Nse_whiteout) NULL, file); nse_dispose_whiteout(bl); return result;}/* * Release the list allocated by nse_get_whiteout. */voidnse_dispose_whiteout(wo) Nse_whiteout wo;{ Nse_whiteout wo_next; while (wo != NULL) { wo_next = wo->next; free(wo->name); free((char *) wo); wo = wo_next; }}/* * Returns list of backlink entries in directory. */Nse_errnse_get_backlink(directory, blp) char *directory; Nse_whiteout *blp;{ char searchlink[MAXPATHLEN]; int blct; return tfs_file_read(directory, searchlink, &blct, blp, (Nse_whiteout *) NULL, (FILE **) NULL);}/* * Set a new backlink entry 'name' in 'directory'. This function is a * no-op if backlink entry 'name' is already set for the directory. */Nse_errnse_set_backlink(directory, name) char *directory; char *name;{ FILE *file; char searchlink[MAXPATHLEN]; int blct; Nse_whiteout bl; Nse_whiteout bl_first; Nse_whiteout wo; int found = 0; Nse_err result; if (result = tfs_file_read(directory, searchlink, &blct, &bl_first, &wo, &file)) { return (result); } bl = bl_first; while (bl != NULL) { if (NSE_STREQ(name, bl->name)) { found = 1; break; } bl = bl->next; } if (found) { fclose(file); } else { bl = NSE_NEW(Nse_whiteout); bl->name = NSE_STRDUP(name); bl->next = bl_first; bl_first = bl; blct++; result = tfs_file_write(directory, searchlink, blct, bl_first, wo, file); } nse_dispose_whiteout(bl_first); nse_dispose_whiteout(wo); return (result);}/* * Clear backlink entry 'name' from the backlink list of 'directory'. If * 'name' is not in the backlink list of 'directory', 0 is returned. */Nse_errnse_clear_backlink(directory, name) char *directory; char *name;{ FILE *file; char searchlink[MAXPATHLEN]; int blct; Nse_whiteout bl; Nse_whiteout bl_first; Nse_whiteout wo; Nse_whiteout bl_prev = NULL; int found = 0; Nse_err result; if (result = tfs_file_read(directory, searchlink, &blct, &bl_first, &wo, &file)) { return (result); } bl = bl_first; while (bl != NULL) { if (NSE_STREQ(name, bl->name)) { found = 1; break; } bl_prev = bl; bl = bl->next; } if (found) { if (bl_prev == NULL) { bl_first = bl->next; } else { bl_prev->next = bl->next; } free(bl->name); free((char *) bl); blct--; result = tfs_file_write(directory, searchlink, blct, bl_first, wo, file); } else { fclose(file); } nse_dispose_whiteout(bl_first); nse_dispose_whiteout(wo); return (result);}static FILE *tfs_info_file;/* * Return both the searchlink, backlink, and the white-out entries in * 'directory'. */Nse_errnse_get_tfs_info(directory, name, blp, wop, will_write_later) char *directory; char *name; Nse_whiteout *blp; Nse_whiteout *wop; bool_t will_write_later;{ FILE **filep; int blct; if (will_write_later) { filep = &tfs_info_file; } else { filep = NULL; } return tfs_file_read(directory, name, &blct, blp, wop, filep);}/* * Set all tfs info for 'directory'. */Nse_errnse_set_tfs_info(directory, name, bl_first, wo) char *directory; char *name; Nse_whiteout bl_first; Nse_whiteout wo;{ int blct = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -