Add a third default.
[oweals/gnunet.git] / src / util / disk.c
index 69473a13de77c06057c2d4cb24c1091586a3fc8d..e3743430e192c507d92fc0c21ca4fe0e548dc977 100644 (file)
@@ -140,28 +140,26 @@ translate_unix_perms (enum GNUNET_DISK_AccessPermissions perm)
  * Iterate over all files in the given directory and
  * accumulate their size.
  *
- * @param cls closure of type "struct GetFileSizeData"
+ * @param cls closure of type `struct GetFileSizeData`
  * @param fn current filename we are looking at
- * @return GNUNET_SYSERR on serious errors, otherwise GNUNET_OK
+ * @return #GNUNET_SYSERR on serious errors, otherwise #GNUNET_OK
  */
 static int
 getSizeRec (void *cls, const char *fn)
 {
   struct GetFileSizeData *gfsd = cls;
 
-#ifdef HAVE_STAT64
-  struct stat64 buf;
-#else
-  struct stat buf;
-#endif
+#if defined (HAVE_STAT64) && !(defined (_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS == 64)
+  STRUCT_STAT64 buf;
 
-#ifdef HAVE_STAT64
   if (0 != STAT64 (fn, &buf))
   {
     LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_DEBUG, "stat64", fn);
     return GNUNET_SYSERR;
   }
 #else
+  struct stat buf;
+
   if (0 != STAT (fn, &buf))
   {
     LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_DEBUG, "stat", fn);
@@ -189,7 +187,7 @@ getSizeRec (void *cls, const char *fn)
  * Checks whether a handle is invalid
  *
  * @param h handle to check
- * @return GNUNET_YES if invalid, GNUNET_NO if valid
+ * @return #GNUNET_YES if invalid, #GNUNET_NO if valid
  */
 int
 GNUNET_DISK_handle_invalid (const struct GNUNET_DISK_FileHandle *h)
@@ -206,11 +204,11 @@ GNUNET_DISK_handle_invalid (const struct GNUNET_DISK_FileHandle *h)
  *
  * @param fh open file handle
  * @param size where to write size of the file
- * @return GNUNET_OK on success, GNUNET_SYSERR on error
+ * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
  */
 int
 GNUNET_DISK_file_handle_size (struct GNUNET_DISK_FileHandle *fh,
-                             OFF_T *size)
+                             off_t *size)
 {
 #if WINDOWS
   BOOL b;
@@ -221,7 +219,7 @@ GNUNET_DISK_file_handle_size (struct GNUNET_DISK_FileHandle *fh,
     SetErrnoFromWinError (GetLastError ());
     return GNUNET_SYSERR;
   }
-  *size = (OFF_T) li.QuadPart;
+  *size = (off_t) li.QuadPart;
 #else
   struct stat sbuf;
 
@@ -239,10 +237,10 @@ GNUNET_DISK_file_handle_size (struct GNUNET_DISK_FileHandle *fh,
  * @param h handle of an open file
  * @param offset position to move to
  * @param whence specification to which position the offset parameter relates to
- * @return the new position on success, GNUNET_SYSERR otherwise
+ * @return the new position on success, #GNUNET_SYSERR otherwise
  */
-OFF_T
-GNUNET_DISK_file_seek (const struct GNUNET_DISK_FileHandle * h, OFF_T offset,
+off_t
+GNUNET_DISK_file_seek (const struct GNUNET_DISK_FileHandle * h, off_t offset,
                        enum GNUNET_DISK_Seek whence)
 {
   if (h == NULL)
@@ -265,7 +263,7 @@ GNUNET_DISK_file_seek (const struct GNUNET_DISK_FileHandle * h, OFF_T offset,
     SetErrnoFromWinError (GetLastError ());
     return GNUNET_SYSERR;
   }
-  return (OFF_T) new_pos.QuadPart;
+  return (off_t) new_pos.QuadPart;
 #else
   static int t[] = { SEEK_SET, SEEK_CUR, SEEK_END };
 
@@ -284,13 +282,15 @@ GNUNET_DISK_file_seek (const struct GNUNET_DISK_FileHandle * h, OFF_T offset,
  *             of all sizes of files in the directory)
  * @param include_symbolic_links should symbolic links be
  *        included?
- * @param single_file_mode GNUNET_YES to only get size of one file
- *        and return GNUNET_SYSERR for directories.
- * @return GNUNET_SYSERR on error, GNUNET_OK on success
+ * @param single_file_mode #GNUNET_YES to only get size of one file
+ *        and return #GNUNET_SYSERR for directories.
+ * @return #GNUNET_SYSERR on error, #GNUNET_OK on success
  */
 int
-GNUNET_DISK_file_size (const char *filename, uint64_t * size,
-                       int include_symbolic_links, int single_file_mode)
+GNUNET_DISK_file_size (const char *filename,
+                      uint64_t * size,
+                       int include_symbolic_links,
+                      int single_file_mode)
 {
   struct GetFileSizeData gfsd;
   int ret;
@@ -465,6 +465,35 @@ mkdtemp (char *fn)
   strcpy (fn, tfn);
   return fn;
 }
+#else
+
+/**
+ * Update POSIX permissions mask of a file on disk.  If both argumets
+ * are #GNUNET_NO, the file is made world-read-write-executable (777).
+ *
+ * @param fn name of the file to update
+ * @param require_uid_match #GNUNET_YES means 700
+ * @param require_gid_match #GNUNET_YES means 770 unless @a require_uid_match is set
+ */
+void
+GNUNET_DISK_fix_permissions (const char *fn,
+                             int require_uid_match,
+                             int require_gid_match)
+{
+  mode_t mode;
+
+  if (GNUNET_YES == require_uid_match)
+    mode = S_IRUSR | S_IWUSR | S_IXUSR;
+  else if (GNUNET_YES == require_gid_match)
+    mode = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP;
+  else
+    mode = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IWOTH | S_IXOTH;
+  if (0 != chmod (fn, mode))
+    GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
+                              "chmod",
+                              fn);
+}
+
 #endif
 
 /**
@@ -605,7 +634,7 @@ GNUNET_DISK_directory_test (const char *fil, int is_readable)
  * (of a file that exists and that is not a directory).
  *
  * @param fil filename to check
- * @return #GNUNET_YES if yes, GNUNET_NO if not a file, #GNUNET_SYSERR if something
+ * @return #GNUNET_YES if yes, #GNUNET_NO if not a file, #GNUNET_SYSERR if something
  * else (will print an error message in that case, too).
  */
 int
@@ -1356,7 +1385,7 @@ GNUNET_DISK_directory_iterator_start (enum GNUNET_SCHEDULER_Priority prio,
  *
  * @param unused not used
  * @param fn directory to remove
- * @return GNUNET_OK
+ * @return #GNUNET_OK
  */
 static int
 remove_helper (void *unused, const char *fn)
@@ -1370,15 +1399,19 @@ remove_helper (void *unused, const char *fn)
  * Remove all files in a directory (rm -rf). Call with
  * caution.
  *
- *
  * @param filename the file to remove
- * @return GNUNET_OK on success, GNUNET_SYSERR on error
+ * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
  */
 int
 GNUNET_DISK_directory_remove (const char *filename)
 {
   struct stat istat;
 
+  if (NULL == filename)
+  {
+    GNUNET_break (0);
+    return GNUNET_SYSERR;
+  }
   if (0 != LSTAT (filename, &istat))
     return GNUNET_NO;           /* file may not exist... */
   (void) CHMOD (filename, S_IWUSR | S_IRUSR | S_IXUSR);
@@ -1531,8 +1564,8 @@ GNUNET_DISK_file_change_owner (const char *filename, const char *user)
  * @return GNUNET_OK on success, GNUNET_SYSERR on error
  */
 int
-GNUNET_DISK_file_lock (struct GNUNET_DISK_FileHandle *fh, OFF_T lock_start,
-                       OFF_T lock_end, int excl)
+GNUNET_DISK_file_lock (struct GNUNET_DISK_FileHandle *fh, off_t lock_start,
+                       off_t lock_end, int excl)
 {
   if (fh == NULL)
   {
@@ -1552,7 +1585,7 @@ GNUNET_DISK_file_lock (struct GNUNET_DISK_FileHandle *fh, OFF_T lock_start,
   return fcntl (fh->fd, F_SETLK, &fl) != 0 ? GNUNET_SYSERR : GNUNET_OK;
 #else
   OVERLAPPED o;
-  OFF_T diff = lock_end - lock_start;
+  off_t diff = lock_end - lock_start;
   DWORD diff_low, diff_high;
   diff_low = (DWORD) (diff & 0xFFFFFFFF);
   diff_high = (DWORD) ((diff >> (sizeof (DWORD) * 8)) & 0xFFFFFFFF);
@@ -1582,8 +1615,8 @@ GNUNET_DISK_file_lock (struct GNUNET_DISK_FileHandle *fh, OFF_T lock_start,
  * @return GNUNET_OK on success, GNUNET_SYSERR on error
  */
 int
-GNUNET_DISK_file_unlock (struct GNUNET_DISK_FileHandle *fh, OFF_T unlock_start,
-                         OFF_T unlock_end)
+GNUNET_DISK_file_unlock (struct GNUNET_DISK_FileHandle *fh, off_t unlock_start,
+                         off_t unlock_end)
 {
   if (fh == NULL)
   {
@@ -1603,7 +1636,7 @@ GNUNET_DISK_file_unlock (struct GNUNET_DISK_FileHandle *fh, OFF_T unlock_start,
   return fcntl (fh->fd, F_SETLK, &fl) != 0 ? GNUNET_SYSERR : GNUNET_OK;
 #else
   OVERLAPPED o;
-  OFF_T diff = unlock_end - unlock_start;
+  off_t diff = unlock_end - unlock_start;
   DWORD diff_low, diff_high;
   diff_low = (DWORD) (diff & 0xFFFFFFFF);
   diff_high = (DWORD) ((diff >> (sizeof (DWORD) * 8)) & 0xFFFFFFFF);
@@ -1631,7 +1664,7 @@ GNUNET_DISK_file_unlock (struct GNUNET_DISK_FileHandle *fh, OFF_T unlock_start,
  * @param fn file name to be opened
  * @param flags opening flags, a combination of GNUNET_DISK_OPEN_xxx bit flags
  * @param perm permissions for the newly created file, use
- *             #GNUNET_DISK_PERM_USER_NONE if a file could not be created by this
+ *             #GNUNET_DISK_PERM_NONE if a file could not be created by this
  *             call (because of flags)
  * @return IO handle on success, NULL on error
  */
@@ -1929,78 +1962,6 @@ GNUNET_DISK_get_handle_from_native (FILE *fd)
 }
 
 
-/**
- * Construct full path to a file inside of the private
- * directory used by GNUnet.  Also creates the corresponding
- * directory.  If the resulting name is supposed to be
- * a directory, end the last argument in '/' (or pass
- * DIR_SEPARATOR_STR as the last argument before NULL).
- *
- * @param cfg configuration to use (determines HOME)
- * @param service_name name of the service
- * @param ... is NULL-terminated list of
- *                path components to append to the
- *                private directory name.
- * @return the constructed filename
- */
-char *
-GNUNET_DISK_get_home_filename (const struct GNUNET_CONFIGURATION_Handle *cfg,
-                               const char *service_name, ...)
-{
-  const char *c;
-  char *pfx;
-  char *ret;
-  va_list ap;
-  unsigned int needed;
-
-  if (GNUNET_OK !=
-      GNUNET_CONFIGURATION_get_value_filename (cfg, service_name, "HOME", &pfx))
-    return NULL;
-  if (pfx == NULL)
-  {
-    LOG (GNUNET_ERROR_TYPE_WARNING,
-         _("No `%s' specified for service `%s' in configuration.\n"), "HOME",
-         service_name);
-    return NULL;
-  }
-  needed = strlen (pfx) + 2;
-  if ((pfx[strlen (pfx) - 1] != '/') && (pfx[strlen (pfx) - 1] != '\\'))
-    needed++;
-  va_start (ap, service_name);
-  while (1)
-  {
-    c = va_arg (ap, const char *);
-
-    if (c == NULL)
-      break;
-    needed += strlen (c);
-    if ((c[strlen (c) - 1] != '/') && (c[strlen (c) - 1] != '\\'))
-      needed++;
-  }
-  va_end (ap);
-  ret = GNUNET_malloc (needed);
-  strcpy (ret, pfx);
-  GNUNET_free (pfx);
-  va_start (ap, service_name);
-  while (1)
-  {
-    c = va_arg (ap, const char *);
-
-    if (c == NULL)
-      break;
-    if ((c[strlen (c) - 1] != '/') && (c[strlen (c) - 1] != '\\'))
-      strcat (ret, DIR_SEPARATOR_STR);
-    strcat (ret, c);
-  }
-  va_end (ap);
-  if ((ret[strlen (ret) - 1] != '/') && (ret[strlen (ret) - 1] != '\\'))
-    (void) GNUNET_DISK_directory_create_for_file (ret);
-  else
-    (void) GNUNET_DISK_directory_create (ret);
-  return ret;
-}
-
-
 /**
  * Handle for a memory-mapping operation.
  */