rnd-19981202-1
[rocksndiamonds.git] / src / files.c
index b3a37e6100dec8d9a7c15248834fbdab4551a5f2..2b089217ae9daba79e3c6d345ec153f5f8d9787e 100644 (file)
@@ -60,6 +60,7 @@
 #define LEVELFILE_EXTENSION    "lvl"
 #define TAPEFILE_EXTENSION     "rec"
 #define SCOREFILE_EXTENSION    "sco"
+#define ERROR_FILENAME         "error.out"
 #endif
 
 /* file permissions for newly written files */
@@ -80,7 +81,7 @@ static char *getGlobalDataDir()
   return GAME_DIR;
 }
 
-static char *getUserDataDir()
+char *getUserDataDir()
 {
   static char *userdata_dir = NULL;
 
@@ -89,8 +90,7 @@ static char *getUserDataDir()
     char *home_dir = getHomeDir();
     char *data_dir = USERDATA_DIRECTORY;
 
-    userdata_dir = checked_malloc(strlen(home_dir) + strlen(data_dir) + 2);
-    sprintf(userdata_dir, "%s/%s", home_dir, data_dir);
+    userdata_dir = getPath2(home_dir, data_dir);
   }
 
   return userdata_dir;
@@ -110,10 +110,10 @@ static char *getUserLevelDir(char *level_subdir)
   if (userlevel_dir)
     free(userlevel_dir);
 
-  userlevel_dir = checked_malloc(strlen(data_dir) + strlen(userlevel_subdir) +
-                                strlen(level_subdir) + 3);
-  sprintf(userlevel_dir, "%s/%s%s%s", data_dir, userlevel_subdir,
-         (strlen(level_subdir) > 0 ? "/" : ""), level_subdir);
+  if (strlen(level_subdir) > 0)
+    userlevel_dir = getPath3(data_dir, userlevel_subdir, level_subdir);
+  else
+    userlevel_dir = getPath2(data_dir, userlevel_subdir);
 
   return userlevel_dir;
 }
@@ -127,10 +127,10 @@ static char *getTapeDir(char *level_subdir)
   if (tape_dir)
     free(tape_dir);
 
-  tape_dir = checked_malloc(strlen(data_dir) + strlen(tape_subdir) +
-                           strlen(level_subdir) + 3);
-  sprintf(tape_dir, "%s/%s%s%s", data_dir, tape_subdir,
-         (strlen(level_subdir) > 0 ? "/" : ""), level_subdir);
+  if (strlen(level_subdir) > 0)
+    tape_dir = getPath3(data_dir, tape_subdir, level_subdir);
+  else
+    tape_dir = getPath2(data_dir, tape_subdir);
 
   return tape_dir;
 }
@@ -144,10 +144,10 @@ static char *getScoreDir(char *level_subdir)
   if (score_dir)
     free(score_dir);
 
-  score_dir = checked_malloc(strlen(data_dir) + strlen(score_subdir) +
-                            strlen(level_subdir) + 3);
-  sprintf(score_dir, "%s/%s%s%s", data_dir, score_subdir,
-         (strlen(level_subdir) > 0 ? "/" : ""), level_subdir);
+  if (strlen(level_subdir) > 0)
+    score_dir = getPath3(data_dir, score_subdir, level_subdir);
+  else
+    score_dir = getPath2(data_dir, score_subdir);
 
   return score_dir;
 }
@@ -212,6 +212,7 @@ static void InitUserDataDirectory()
 
 static void InitTapeDirectory(char *level_subdir)
 {
+  createDirectory(getUserDataDir(), "user data");
   createDirectory(getTapeDir(""), "main tape");
   createDirectory(getTapeDir(level_subdir), "level tape");
 }
@@ -226,6 +227,7 @@ static void InitUserLevelDirectory(char *level_subdir)
 {
   if (access(getUserLevelDir(level_subdir), F_OK) != 0)
   {
+    createDirectory(getUserDataDir(), "user data");
     createDirectory(getUserLevelDir(""), "main user level");
     createDirectory(getUserLevelDir(level_subdir), "user level");
 
@@ -599,11 +601,9 @@ void SaveTape(int level_nr)
   InitTapeDirectory(leveldir[leveldir_nr].filename);
 
   /* if a tape still exists, ask to overwrite it */
-  if ((file = fopen(filename, "r")))
+  if (access(filename, F_OK) == 0)
   {
     new_tape = FALSE;
-    fclose(file);
-
     if (!Request("Replace old tape ?", REQ_ASK))
       return;
   }
@@ -699,7 +699,7 @@ void LoadScore(int level_nr)
   /* always start with reliable default values */
   for(i=0; i<MAX_SCORE_ENTRIES; i++)
   {
-    strcpy(highscore[i].Name, EMPTY_ALIAS);
+    strcpy(highscore[i].Name, EMPTY_PLAYER_NAME);
     highscore[i].Score = 0;
   }
 
@@ -1029,7 +1029,7 @@ static struct SetupFileList *loadSetupFileList(char *filename)
 
   if (!(file = fopen(filename, "r")))
   {
-    Error(ERR_WARN, "cannot open setup/info file '%s'", filename);
+    Error(ERR_WARN, "cannot open configuration file '%s'", filename);
     return NULL;
   }
 
@@ -1098,7 +1098,7 @@ static struct SetupFileList *loadSetupFileList(char *filename)
   freeSetupFileList(setup_file_list);
 
   if (first_valid_list_entry == NULL)
-    Error(ERR_WARN, "setup/info file '%s' is empty", filename);
+    Error(ERR_WARN, "configuration file '%s' is empty", filename);
 
   return first_valid_list_entry;
 }
@@ -1113,7 +1113,7 @@ static void checkSetupFileListIdentifier(struct SetupFileList *setup_file_list,
   {
     if (strcmp(setup_file_list->value, identifier) != 0)
     {
-      Error(ERR_WARN, "setup/info file has wrong version");
+      Error(ERR_WARN, "configuration file has wrong version");
       return;
     }
     else
@@ -1124,7 +1124,7 @@ static void checkSetupFileListIdentifier(struct SetupFileList *setup_file_list,
     checkSetupFileListIdentifier(setup_file_list->next, identifier);
   else
   {
-    Error(ERR_WARN, "setup/info file has no version information");
+    Error(ERR_WARN, "configuration file has no version information");
     return;
   }
 }
@@ -1317,7 +1317,10 @@ static int LoadLevelInfoFromLevelDir(char *level_directory, int start_entry)
   int i, current_entry = start_entry;
 
   if ((dir = opendir(level_directory)) == NULL)
-    Error(ERR_EXIT, "cannot read level directory '%s'", level_directory);
+  {
+    Error(ERR_WARN, "cannot read level directory '%s'", level_directory);
+    return current_entry;
+  }
 
   while (current_entry < MAX_LEVDIR_ENTRIES)
   {
@@ -1371,8 +1374,8 @@ static int LoadLevelInfoFromLevelDir(char *level_directory, int start_entry)
 
   closedir(dir);
 
-  if (current_entry == start_entry && start_entry != -1)
-    Error(ERR_EXIT, "cannot find any valid level series in directory '%s'",
+  if (current_entry == start_entry)
+    Error(ERR_WARN, "cannot find any valid level series in directory '%s'",
          level_directory);
 
   return current_entry;
@@ -1389,6 +1392,10 @@ void LoadLevelInfo()
                                            num_leveldirs);
   num_leveldirs = LoadLevelInfoFromLevelDir(getUserLevelDir(""),
                                            num_leveldirs);
+
+  if (num_leveldirs == 0)
+    Error(ERR_EXIT, "cannot find any valid level series in any directory");
+
   if (num_leveldirs > 1)
     qsort(leveldir, num_leveldirs, sizeof(struct LevelDirInfo),
          compareLevelDirInfoEntries);
@@ -1396,16 +1403,16 @@ void LoadLevelInfo()
 
 static void SaveUserLevelInfo()
 {
-  char filename[MAX_FILENAME_LEN];
+  char *filename;
   FILE *file;
   int i;
 
-  sprintf(filename, "%s/%s",
-         getUserLevelDir(getLoginName()), LEVELINFO_FILENAME);
+  filename = getPath2(getUserLevelDir(getLoginName()), LEVELINFO_FILENAME);
 
   if (!(file = fopen(filename, "w")))
   {
     Error(ERR_WARN, "cannot write level info file '%s'", filename);
+    free(filename);
     return;
   }
 
@@ -1421,19 +1428,20 @@ static void SaveUserLevelInfo()
     fprintf(file, "%s\n", getSetupLine("", i));
 
   fclose(file);
+  free(filename);
 
   chmod(filename, SETUP_PERMS);
 }
 
 void LoadSetup()
 {
-  char filename[MAX_FILENAME_LEN];
+  char *filename;
   struct SetupFileList *setup_file_list = NULL;
 
   /* always start with reliable default values */
   setSetupInfoToDefaults(&setup);
 
-  sprintf(filename, "%s/%s", getSetupDir(), SETUP_FILENAME);
+  filename = getPath2(getSetupDir(), SETUP_FILENAME);
 
   setup_file_list = loadSetupFileList(filename);
 
@@ -1460,6 +1468,8 @@ void LoadSetup()
   }
   else
     Error(ERR_WARN, "using default setup values");
+
+  free(filename);
 }
 
 static char *getSetupLine(char *prefix, int token_nr)
@@ -1528,16 +1538,17 @@ static char *getSetupLine(char *prefix, int token_nr)
 void SaveSetup()
 {
   int i, pnr;
-  char filename[MAX_FILENAME_LEN];
+  char *filename;
   FILE *file;
 
   InitUserDataDirectory();
 
-  sprintf(filename, "%s/%s", getSetupDir(), SETUP_FILENAME);
+  filename = getPath2(getSetupDir(), SETUP_FILENAME);
 
   if (!(file = fopen(filename, "w")))
   {
     Error(ERR_WARN, "cannot write setup file '%s'", filename);
+    free(filename);
     return;
   }
 
@@ -1570,19 +1581,20 @@ void SaveSetup()
   }
 
   fclose(file);
+  free(filename);
 
   chmod(filename, SETUP_PERMS);
 }
 
 void LoadLevelSetup()
 {
-  char filename[MAX_FILENAME_LEN];
+  char *filename;
 
   /* always start with reliable default values */
   leveldir_nr = 0;
   level_nr = 0;
 
-  sprintf(filename, "%s/%s", getSetupDir(), LEVELSETUP_FILENAME);
+  filename = getPath2(getSetupDir(), LEVELSETUP_FILENAME);
 
   if (level_setup_list)
     freeSetupFileList(level_setup_list);
@@ -1605,11 +1617,13 @@ void LoadLevelSetup()
                                        LEVELSETUP_COOKIE);
     Error(ERR_WARN, "using default setup values");
   }
+
+  free(filename);
 }
 
 void SaveLevelSetup()
 {
-  char filename[MAX_FILENAME_LEN];
+  char *filename;
   struct SetupFileList *list_entry = level_setup_list;
   FILE *file;
 
@@ -1621,11 +1635,12 @@ void SaveLevelSetup()
   setTokenValue(level_setup_list,
                leveldir[leveldir_nr].filename, int2str(level_nr, 0));
 
-  sprintf(filename, "%s/%s", getSetupDir(), LEVELSETUP_FILENAME);
+  filename = getPath2(getSetupDir(), LEVELSETUP_FILENAME);
 
   if (!(file = fopen(filename, "w")))
   {
     Error(ERR_WARN, "cannot write setup file '%s'", filename);
+    free(filename);
     return;
   }
 
@@ -1645,6 +1660,67 @@ void SaveLevelSetup()
   }
 
   fclose(file);
+  free(filename);
 
   chmod(filename, SETUP_PERMS);
 }
+
+#ifdef MSDOS
+static boolean initErrorFile()
+{
+  char *filename;
+  FILE *error_file;
+
+  InitUserDataDirectory();
+
+  filename = getPath2(getUserDataDir(), ERROR_FILENAME);
+  error_file = fopen(filename, "w");
+  free(filename);
+
+  if (error_file == NULL)
+    return FALSE;
+
+  fclose(error_file);
+
+  return TRUE;
+}
+
+FILE *openErrorFile()
+{
+  static boolean first_access = TRUE;
+  char *filename;
+  FILE *error_file;
+
+  if (first_access)
+  {
+    if (!initErrorFile())
+      return NULL;
+
+    first_access = FALSE;
+  }
+
+  filename = getPath2(getUserDataDir(), ERROR_FILENAME);
+  error_file = fopen(filename, "a");
+  free(filename);
+
+  return error_file;
+}
+
+void dumpErrorFile()
+{
+  char *filename;
+  FILE *error_file;
+
+  filename = getPath2(getUserDataDir(), ERROR_FILENAME);
+  error_file = fopen(filename, "r");
+  free(filename);
+
+  if (error_file != NULL)
+  {
+    while (!feof(error_file))
+      fputc(fgetc(error_file), stderr);
+
+    fclose(error_file);
+  }
+}
+#endif