char *realpath(const char *file_name, char *resolved_name, size_t resolv_buffer_length) { long lRet; wchar_t szFile[_MAX_PATH + 1]; wchar_t szRet[_MAX_PATH + 1]; wchar_t *wresult; char *result = NULL; if (_plibc_utf8_mode == 1) { lRet = plibc_conv_to_win_pathwconv(file_name, szFile, _MAX_PATH ); if (lRet != ERROR_SUCCESS) { SetErrnoFromWinError(lRet); return NULL; } wresult = _wfullpath(szRet, szFile, MAX_PATH); SetErrnoFromWinError(GetLastError()); if (wresult) wchartostr (szRet, &result, CP_UTF8); return result; } else { lRet = plibc_conv_to_win_path(file_name, (char *) szFile, _MAX_PATH ); if (lRet != ERROR_SUCCESS) { SetErrnoFromWinError(lRet); return NULL; } result = _fullpath(resolved_name, (char *) szFile, resolv_buffer_length); SetErrnoFromWinError(GetLastError()); return result; } }
/** * @brief Get status information on a file */ int __win_stat(const char *path, struct stat *buffer, int iDeref) { char szFile[_MAX_PATH + 1]; long lRet; if ((lRet = plibc_conv_to_win_path(path, szFile)) != ERROR_SUCCESS) { SetErrnoFromWinError(lRet); return -1; } /* Remove trailing slash */ lRet = strlen(szFile) - 1; if (szFile[lRet] == '\\') { szFile[lRet] = 0; } /* Dereference symlinks */ if (iDeref) { if (__win_deref(szFile) == -1 && errno != EINVAL) return -1; } /* stat sets errno */ return stat(szFile, buffer); }
/** * Obtain the location of ".my.cnf". * * @param cfg our configuration * @param section the section * @return NULL on error */ static char * get_my_cnf_path (const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section) { char *cnffile; char *home_dir; struct stat st; #ifndef WINDOWS struct passwd *pw; #endif int configured; #ifndef WINDOWS pw = getpwuid (getuid ()); if (!pw) { GNUNET_log_from_strerror (GNUNET_ERROR_TYPE_ERROR, "mysql", "getpwuid"); return NULL; } if (GNUNET_YES == GNUNET_CONFIGURATION_have_value (cfg, section, "CONFIG")) { GNUNET_assert (GNUNET_OK == GNUNET_CONFIGURATION_get_value_filename (cfg, section, "CONFIG", &cnffile)); configured = GNUNET_YES; } else { home_dir = GNUNET_strdup (pw->pw_dir); GNUNET_asprintf (&cnffile, "%s/.my.cnf", home_dir); GNUNET_free (home_dir); configured = GNUNET_NO; } #else home_dir = (char *) GNUNET_malloc (_MAX_PATH + 1); plibc_conv_to_win_path ("~/", home_dir); GNUNET_asprintf (&cnffile, "%s/.my.cnf", home_dir); GNUNET_free (home_dir); configured = GNUNET_NO; #endif GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, "mysql", _("Trying to use file `%s' for MySQL configuration.\n"), cnffile); if ((0 != STAT (cnffile, &st)) || (0 != ACCESS (cnffile, R_OK)) || (!S_ISREG (st.st_mode))) { if (configured == GNUNET_YES) GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "mysql", _("Could not access file `%s': %s\n"), cnffile, STRERROR (errno)); GNUNET_free (cnffile); return NULL; } return cnffile; }
/** * @brief Get status information on a file */ int __win_stat64(const char *path, struct stat64 *buffer, int iDeref) { char szFile[_MAX_PATH + 1]; long lRet; if ((lRet = plibc_conv_to_win_path(path, szFile)) != ERROR_SUCCESS) { SetErrnoFromWinError(lRet); return -1; } /* Remove trailing slash */ lRet = strlen(szFile) - 1; if (szFile[lRet] == '\\') { szFile[lRet] = 0; } /* Dereference symlinks */ if (iDeref) { if (__win_deref(szFile) == -1 && errno != EINVAL) return -1; } if (!_plibc_stat64) { /* not supported under Windows 9x */ struct stat theStat; int iRet; iRet = __win_stat(path, &theStat, iDeref); buffer->st_dev = theStat.st_dev; buffer->st_ino = theStat.st_ino; buffer->st_mode = theStat.st_mode; buffer->st_nlink = theStat.st_nlink; buffer->st_uid = theStat.st_uid; buffer->st_gid = theStat.st_gid; buffer->st_rdev = theStat.st_rdev; buffer->st_size = (theStat.st_size > LONG_MAX) ? LONG_MAX : theStat.st_size; buffer->st_atime = (theStat.st_atime > LONG_MAX) ? LONG_MAX : theStat.st_atime; buffer->st_mtime = (theStat.st_mtime > LONG_MAX) ? LONG_MAX : theStat.st_mtime; buffer->st_ctime = (theStat.st_ctime > LONG_MAX) ? LONG_MAX : theStat.st_ctime; return iRet; } else /* stat sets errno */ return _plibc_stat64(szFile, buffer); }
/** * @brief Determine file-access permission. */ int _win_access( const char *path, int mode ) { char szFile[_MAX_PATH + 1]; long lRet; mode &= 6; if ((lRet = plibc_conv_to_win_path(path, szFile)) != ERROR_SUCCESS) { SetErrnoFromWinError(lRet); return -1; } /* access sets errno */ return access(szFile, mode); }
char *_win_bindtextdomain(const char *domainname, const char *dirname) { #ifdef HAVE_LIBINTL char szDirname[_MAX_PATH + 1]; int i; if ((i = plibc_conv_to_win_path(dirname, szDirname)) != ERROR_SUCCESS) { SetErrnoFromWinError(i); return NULL; } return bindtextdomain(domainname, szDirname); #else errno = ENOSYS; return NULL; #endif }
/** * @brief Open a file */ int _win_open(const char *filename, int oflag, ...) { int mode, iFD; char szFile[_MAX_PATH + 1]; long lRet; if ((lRet = plibc_conv_to_win_path(filename, szFile)) != ERROR_SUCCESS) { errno = ENOENT; SetLastError(lRet); return -1; } if (oflag & O_CREAT) { va_list arg; va_start(arg, oflag); mode = va_arg(arg, int); va_end(arg); }
char *_win_bindtextdomain(const char *domainname, const char *dirname) { #ifdef HAVE_LIBINTL char szDirname[_MAX_PATH + 1]; int i; if ((i = plibc_conv_to_win_path(dirname, szDirname, _MAX_PATH)) != ERROR_SUCCESS) { SetErrnoFromWinError(i); return NULL; } /* There is nothing we could do: libintl will internally call CRT with * szDirname, so we can't convert it to UTF-8, and can't convince * libintl to use wide-character functions either. * So only call BINDTEXTDOMAIN() with ASCII/CP*-encoded dirnames. */ return bindtextdomain(domainname, szDirname); #else errno = ENOSYS; return NULL; #endif }
/** * Change the file-permission settings. */ int _win_chmod(const char *filename, int pmode) { wchar_t szFile[_MAX_PATH + 1]; long lRet; pmode &= (_S_IREAD | _S_IWRITE); if (_plibc_utf8_mode == 1) lRet = plibc_conv_to_win_pathwconv(filename, szFile, _MAX_PATH); else lRet = plibc_conv_to_win_path(filename, (char *) szFile, _MAX_PATH); if (lRet != ERROR_SUCCESS) { SetErrnoFromWinError(lRet); return -1; } /* chmod sets errno */ if (_plibc_utf8_mode == 1) return _wchmod(szFile, pmode); else return chmod((char *) szFile, pmode); }
/** * @brief Open a file */ int _win_open(const char *filename, int oflag, ...) { int mode, iFD; wchar_t szFile[_MAX_PATH + 1]; long lRet; if (_plibc_utf8_mode == 1) lRet = plibc_conv_to_win_pathwconv(filename, szFile, _MAX_PATH); else lRet = plibc_conv_to_win_path(filename, (char *) szFile, _MAX_PATH); if (lRet != ERROR_SUCCESS) { errno = ENOENT; SetLastError(lRet); return -1; } if (oflag & O_CREAT) { va_list arg; va_start(arg, oflag); mode = va_arg(arg, int); va_end(arg); }
/** * Complete filename (a la shell) from abbrevition. * @param fil the name of the file, may contain ~/ or * be relative to the current directory * @returns the full file name, * NULL is returned on error */ char * GNUNET_STRINGS_filename_expand (const char *fil) { char *buffer; #ifndef MINGW size_t len; size_t n; char *fm; const char *fil_ptr; #else char *fn; long lRet; #endif if (fil == NULL) return NULL; #ifndef MINGW if (fil[0] == DIR_SEPARATOR) /* absolute path, just copy */ return GNUNET_strdup (fil); if (fil[0] == '~') { fm = getenv ("HOME"); if (fm == NULL) { LOG (GNUNET_ERROR_TYPE_WARNING, _("Failed to expand `$HOME': environment variable `HOME' not set")); return NULL; } fm = GNUNET_strdup (fm); /* do not copy '~' */ fil_ptr = fil + 1; /* skip over dir seperator to be consistent */ if (fil_ptr[0] == DIR_SEPARATOR) fil_ptr++; } else { /* relative path */ fil_ptr = fil; len = 512; fm = NULL; while (1) { buffer = GNUNET_malloc (len); if (getcwd (buffer, len) != NULL) { fm = buffer; break; } if ((errno == ERANGE) && (len < 1024 * 1024 * 4)) { len *= 2; GNUNET_free (buffer); continue; } GNUNET_free (buffer); break; } if (fm == NULL) { LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "getcwd"); buffer = getenv ("PWD"); /* alternative */ if (buffer != NULL) fm = GNUNET_strdup (buffer); } if (fm == NULL) fm = GNUNET_strdup ("./"); /* give up */ } n = strlen (fm) + 1 + strlen (fil_ptr) + 1; buffer = GNUNET_malloc (n); GNUNET_snprintf (buffer, n, "%s%s%s", fm, (fm[strlen (fm) - 1] == DIR_SEPARATOR) ? "" : DIR_SEPARATOR_STR, fil_ptr); GNUNET_free (fm); return buffer; #else fn = GNUNET_malloc (MAX_PATH + 1); if ((lRet = plibc_conv_to_win_path (fil, fn)) != ERROR_SUCCESS) { SetErrnoFromWinError (lRet); LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "plibc_conv_to_win_path"); return NULL; } /* is the path relative? */ if ((strncmp (fn + 1, ":\\", 2) != 0) && (strncmp (fn, "\\\\", 2) != 0)) { char szCurDir[MAX_PATH + 1]; lRet = GetCurrentDirectory (MAX_PATH + 1, szCurDir); if (lRet + strlen (fn) + 1 > (MAX_PATH + 1)) { SetErrnoFromWinError (ERROR_BUFFER_OVERFLOW); LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "GetCurrentDirectory"); return NULL; } buffer = GNUNET_malloc (MAX_PATH + 1); GNUNET_snprintf (buffer, MAX_PATH + 1, "%s\\%s", szCurDir, fn); GNUNET_free (fn); fn = buffer; } return fn; #endif }
/** * Create an entry for a file in a publish-structure. * * @param h handle to the file sharing subsystem * @param client_info initial value for the client-info value for this entry * @param filename name of the file or directory to publish * @param keywords under which keywords should this file be available * directly; can be NULL * @param meta metadata for the file * @param do_index GNUNET_YES for index, GNUNET_NO for insertion, * GNUNET_SYSERR for simulation * @param bo block options * @return publish structure entry for the file */ struct GNUNET_FS_FileInformation * GNUNET_FS_file_information_create_from_file (struct GNUNET_FS_Handle *h, void *client_info, const char *filename, const struct GNUNET_FS_Uri *keywords, const struct GNUNET_CONTAINER_MetaData *meta, int do_index, const struct GNUNET_FS_BlockOptions *bo) { struct FileInfo *fi; uint64_t fsize; struct GNUNET_FS_FileInformation *ret; const char *fn; const char *ss; #if WINDOWS char fn_conv[MAX_PATH]; #endif /* FIXME: should includeSymLinks be GNUNET_NO or GNUNET_YES here? */ if (GNUNET_OK != GNUNET_DISK_file_size (filename, &fsize, GNUNET_NO, GNUNET_YES)) { GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "stat", filename); return NULL; } fi = GNUNET_FS_make_file_reader_context_ (filename); if (fi == NULL) { GNUNET_break (0); return NULL; } ret = GNUNET_FS_file_information_create_from_reader (h, client_info, fsize, &GNUNET_FS_data_reader_file_, fi, keywords, meta, do_index, bo); if (ret == NULL) return NULL; ret->h = h; ret->filename = GNUNET_strdup (filename); #if !WINDOWS fn = filename; #else plibc_conv_to_win_path (filename, fn_conv); fn = fn_conv; #endif while (NULL != (ss = strstr (fn, DIR_SEPARATOR_STR))) fn = ss + 1; /* FIXME: If we assume that on other platforms CRT is UTF-8-aware, then * this should be changed to EXTRACTOR_METAFORMAT_UTF8 */ #if !WINDOWS GNUNET_CONTAINER_meta_data_insert (ret->meta, "<gnunet>", EXTRACTOR_METATYPE_GNUNET_ORIGINAL_FILENAME, EXTRACTOR_METAFORMAT_C_STRING, "text/plain", fn, strlen (fn) + 1); #else GNUNET_CONTAINER_meta_data_insert (ret->meta, "<gnunet>", EXTRACTOR_METATYPE_GNUNET_ORIGINAL_FILENAME, EXTRACTOR_METAFORMAT_UTF8, "text/plain", fn, strlen (fn) + 1); #endif return ret; }