int our_truncate(char *path, off_t size) { int ret = -1; #if defined(_WINDOWS) || !defined(HAVE_TRUNCATE) int fdes; #endif #ifdef _WINDOWS if((fdes = our_open(path, O_RDWR | O_CREAT | S_IREAD | S_IWRITE | _O_U8TEXT, 0600)) != -1){ if(chsize(fdes, size) == 0) ret = 0; close(fdes); } #else /* UNIX */ #ifdef HAVE_TRUNCATE ret = truncate(fname_to_locale(path), size); #else /* !HAVE_TRUNCATE */ if((fdes = our_open(path, O_RDWR, 0600)) != -1){ ret = chsize(fdes, size) ; if(close(fdes)) ret = -1; } #endif /* !HAVE_TRUNCATE */ #endif /* UNIX */ return ret; }
/* * Check if we can access a file in a given way * * Args: file -- The file to check * mode -- The mode ala the access() system call, see ACCESS_EXISTS * and friends in alpine.h. * * Result: returns 0 if the user can access the file according to the mode, * -1 if he can't (and errno is set). * * */ int can_access(char *file, int mode) { #ifdef _WINDOWS struct stat buf; /* * NOTE: The WinNT access call returns that every directory is readable and * writable. We actually want to know if the write is going to fail, so we * try it. We don't read directories in Windows so we skip implementing that. */ if(mode & WRITE_ACCESS && file && !our_stat(file, &buf) && (buf.st_mode & S_IFMT) == S_IFDIR){ char *testname; int fd; size_t l = 0; /* * We'd like to just call temp_nam here, since it creates a file * and does what we want. However, temp_nam calls us! */ if((testname = malloc(MAXPATH * sizeof(char)))){ strncpy(testname, file, MAXPATH-1); testname[MAXPATH-1] = '\0'; if(testname[0] && testname[(l=strlen(testname))-1] != '\\' && l+1 < MAXPATH){ l++; strncat(testname, "\\", MAXPATH-strlen(testname)-1); testname[MAXPATH-1] = '\0'; } if(l+8 < MAXPATH && strncat(testname, "caXXXXXX", MAXPATH-strlen(testname)-1) && mktemp(testname)){ if((fd = our_open(testname, O_CREAT|O_EXCL|O_WRONLY|O_BINARY, 0600)) >= 0){ (void)close(fd); our_unlink(testname); free(testname); /* success, drop through to access call */ } else{ free(testname); /* can't write in the directory */ return(-1); } } else{ free(testname); return(-1); } } } if(mode & EXECUTE_ACCESS) /* Windows access has no execute mode */ mode &= ~EXECUTE_ACCESS; /* and crashes because of it */ #endif /* WINDOWS */ return(our_access(file, mode)); }
char * rd_metadata_name(void) { char *p, *q, *metafile; char path[MAXPATH], pinerc_dir[MAXPATH]; struct variable *vars = ps_global->vars; dprint((9, "rd_metadata_name\n")); pinerc_dir[0] = '\0'; if(ps_global->pinerc){ char *prcn = ps_global->pinerc; char *lc; if((lc = last_cmpnt(prcn)) != NULL){ int to_copy; to_copy = (lc - prcn > 1) ? (lc - prcn - 1) : 1; strncpy(pinerc_dir, prcn, MIN(to_copy, sizeof(pinerc_dir)-1)); pinerc_dir[MIN(to_copy, sizeof(pinerc_dir)-1)] = '\0'; } else{ pinerc_dir[0] = '.'; pinerc_dir[1] = '\0'; } } /* * If there is no metadata file specified in the pinerc, create a filename. */ if(!(VAR_REMOTE_ABOOK_METADATA && VAR_REMOTE_ABOOK_METADATA[0])){ if(pinerc_dir[0] && (p = tempfile_in_same_dir(ps_global->pinerc, meta_prefix, NULL))){ /* fill in the pinerc variable */ q = p + strlen(pinerc_dir) + 1; set_variable(V_REMOTE_ABOOK_METADATA, q, 1, 0, Main); dprint((2, "creating name for metadata file: %s\n", q ? q : "?")); /* something's broken, return NULL rab */ if(!VAR_REMOTE_ABOOK_METADATA || !VAR_REMOTE_ABOOK_METADATA[0]){ our_unlink(p); fs_give((void **)&p); return(NULL); } fs_give((void **)&p); } else{ q_status_message(SM_ORDER, 3, 5, "can't create metadata file in pinerc directory, continuing"); return(NULL); } } build_path(path, pinerc_dir ? pinerc_dir : NULL, VAR_REMOTE_ABOOK_METADATA, sizeof(path)); metafile = path; /* * If the metadata file doesn't exist, create it. */ if(can_access(metafile, ACCESS_EXISTS) != 0){ int fd; if((fd = our_open(metafile, O_CREAT|O_EXCL|O_WRONLY|O_BINARY, 0600)) < 0){ set_variable(V_REMOTE_ABOOK_METADATA, NULL, 1, 0, Main); q_status_message2(SM_ORDER, 3, 5, "can't create cache file %.200s, continuing (%.200s)", metafile, error_description(errno)); dprint((2, "can't create metafile %s: %s\n", metafile ? metafile : "?", error_description(errno))); return(NULL); } dprint((2, "created metadata file: %s\n", metafile ? metafile : "?")); (void)close(fd); } return(cpystr(metafile));; }