rnd-20020318-3-src
authorHolger Schemel <info@artsoft.org>
Mon, 18 Mar 2002 03:05:40 +0000 (04:05 +0100)
committerHolger Schemel <info@artsoft.org>
Sat, 30 Aug 2014 08:36:17 +0000 (10:36 +0200)
src/files.c
src/libgame/misc.c
src/libgame/misc.h
src/main.h

index 2080cd615a3c4142249c0cd20bf1fb190207afcf..9b5b73f5b302b002695091b382af99f7ea8f33da 100644 (file)
@@ -22,8 +22,6 @@
 #include "tape.h"
 #include "joystick.h"
 
-#define MAX_FILENAME_LEN       256     /* maximal filename length    */
-#define MAX_LINE_LEN           1000    /* maximal input line length  */
 #define CHUNK_ID_LEN           4       /* IFF style chunk id length  */
 #define CHUNK_SIZE_UNDEFINED   0       /* undefined chunk size == 0  */
 #define CHUNK_SIZE_NONE                -1      /* do not write chunk size    */
@@ -172,11 +170,6 @@ char *getLevelClassDescription(struct LevelDirInfo *ldi)
 static void SaveUserLevelInfo();               /* for 'InitUserLevelDir()' */
 static char *getSetupLine(char *, int);                /* for 'SaveUserLevelInfo()' */
 
-static char *getSetupDir()
-{
-  return getUserDataDir();
-}
-
 static char *getUserLevelDir(char *level_subdir)
 {
   static char *userlevel_dir = NULL;
@@ -293,24 +286,24 @@ static char *getScoreFilename(int nr)
 
 static void InitTapeDirectory(char *level_subdir)
 {
-  createDirectory(getUserDataDir(), "user data");
-  createDirectory(getTapeDir(""), "main tape");
-  createDirectory(getTapeDir(level_subdir), "level tape");
+  createDirectory(getUserDataDir(), "user data", PERMS_PRIVATE);
+  createDirectory(getTapeDir(""), "main tape", PERMS_PRIVATE);
+  createDirectory(getTapeDir(level_subdir), "level tape", PERMS_PRIVATE);
 }
 
 static void InitScoreDirectory(char *level_subdir)
 {
-  createDirectory(getScoreDir(""), "main score");
-  createDirectory(getScoreDir(level_subdir), "level score");
+  createDirectory(getScoreDir(""), "main score", PERMS_PUBLIC);
+  createDirectory(getScoreDir(level_subdir), "level score", PERMS_PUBLIC);
 }
 
 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");
+    createDirectory(getUserDataDir(), "user data", PERMS_PRIVATE);
+    createDirectory(getUserLevelDir(""), "main user level", PERMS_PRIVATE);
+    createDirectory(getUserLevelDir(level_subdir), "user level",PERMS_PRIVATE);
 
     SaveUserLevelInfo();
   }
@@ -318,21 +311,9 @@ static void InitUserLevelDirectory(char *level_subdir)
 
 static void InitLevelSetupDirectory(char *level_subdir)
 {
-  createDirectory(getUserDataDir(), "user data");
-  createDirectory(getLevelSetupDir(""), "main level setup");
-  createDirectory(getLevelSetupDir(level_subdir), "level setup");
-}
-
-static void ReadUnusedBytesFromFile(FILE *file, unsigned long bytes)
-{
-  while (bytes--)
-    fgetc(file);
-}
-
-static void WriteUnusedBytesToFile(FILE *file, unsigned long bytes)
-{
-  while (bytes--)
-    fputc(0, file);
+  createDirectory(getUserDataDir(), "user data", PERMS_PRIVATE);
+  createDirectory(getLevelSetupDir(""), "main level setup", PERMS_PRIVATE);
+  createDirectory(getLevelSetupDir(level_subdir), "level setup",PERMS_PRIVATE);
 }
 
 static void ReadChunk_VERS(FILE *file, int *file_version, int *game_version)
@@ -379,53 +360,6 @@ static void WriteChunk_VERS(FILE *file, int file_version, int game_version)
   fputc(0, file);      /* not used */
 }
 
-static int getFileVersionFromCookieString(const char *cookie)
-{
-  const char *ptr_cookie1, *ptr_cookie2;
-  const char *pattern1 = "_FILE_VERSION_";
-  const char *pattern2 = "?.?";
-  const int len_cookie = strlen(cookie);
-  const int len_pattern1 = strlen(pattern1);
-  const int len_pattern2 = strlen(pattern2);
-  const int len_pattern = len_pattern1 + len_pattern2;
-  int version_major, version_minor;
-
-  if (len_cookie <= len_pattern)
-    return -1;
-
-  ptr_cookie1 = &cookie[len_cookie - len_pattern];
-  ptr_cookie2 = &cookie[len_cookie - len_pattern2];
-
-  if (strncmp(ptr_cookie1, pattern1, len_pattern1) != 0)
-    return -1;
-
-  if (ptr_cookie2[0] < '0' || ptr_cookie2[0] > '9' ||
-      ptr_cookie2[1] != '.' ||
-      ptr_cookie2[2] < '0' || ptr_cookie2[2] > '9')
-    return -1;
-
-  version_major = ptr_cookie2[0] - '0';
-  version_minor = ptr_cookie2[2] - '0';
-
-  return VERSION_IDENT(version_major, version_minor, 0);
-}
-
-boolean checkCookieString(const char *cookie, const char *template)
-{
-  const char *pattern = "_FILE_VERSION_?.?";
-  const int len_cookie = strlen(cookie);
-  const int len_template = strlen(template);
-  const int len_pattern = strlen(pattern);
-
-  if (len_cookie != len_template)
-    return FALSE;
-
-  if (strncmp(cookie, template, len_cookie - len_pattern) != 0)
-    return FALSE;
-
-  return TRUE;
-}
-
 static void setLevelInfoToDefaults()
 {
   int i, x, y;
@@ -901,8 +835,8 @@ static void SaveLevel_BODY(FILE *file, struct LevelInfo *level)
 {
   int x, y;
 
-  for(y=0; y<lev_fieldy; y++) 
-    for(x=0; x<lev_fieldx; x++) 
+  for(y=0; y<level->fieldy; y++) 
+    for(x=0; x<level->fieldx; x++) 
       if (level->encoding_16bit_field)
        putFile16BitInteger(file, Ur[x][y], BYTE_ORDER_BIG_ENDIAN);
       else
@@ -974,13 +908,16 @@ void SaveLevel(int level_nr)
     return;
   }
 
+
   /* check level field for 16-bit elements */
+  level.encoding_16bit_field = FALSE;
   for(y=0; y<level.fieldy; y++) 
     for(x=0; x<level.fieldx; x++) 
       if (Ur[x][y] > 255)
        level.encoding_16bit_field = TRUE;
 
   /* check yamyam content for 16-bit elements */
+  level.encoding_16bit_yamyam = FALSE;
   for(i=0; i<level.num_yam_contents; i++)
     for(y=0; y<3; y++)
       for(x=0; x<3; x++)
@@ -988,6 +925,7 @@ void SaveLevel(int level_nr)
          level.encoding_16bit_yamyam = TRUE;
 
   /* check amoeba content for 16-bit elements */
+  level.encoding_16bit_amoeba = FALSE;
   if (level.amoeba_content > 255)
     level.encoding_16bit_amoeba = TRUE;
 
@@ -1024,7 +962,7 @@ void SaveLevel(int level_nr)
 
   fclose(file);
 
-  SetFilePermissions_Level(filename);
+  SetFilePermissions(filename, PERMS_PRIVATE);
 }
 
 static void setTapeInfoToDefaults()
@@ -1370,7 +1308,7 @@ void SaveTape(int level_nr)
 
   fclose(file);
 
-  SetFilePermissions_Tape(filename);
+  SetFilePermissions(filename, PERMS_PRIVATE);
 
   tape.changed = FALSE;
 
@@ -1496,17 +1434,18 @@ void SaveScore(int level_nr)
 
   fclose(file);
 
-  SetFilePermissions_Score(filename);
+  SetFilePermissions(filename, PERMS_PUBLIC);
 }
 
-#define TOKEN_STR_FILE_IDENTIFIER      "file_identifier"
+/* ------------------------------------------------------------------------- */
+/* setup file stuff                                                          */
+/* ------------------------------------------------------------------------- */
+
 #define TOKEN_STR_LAST_LEVEL_SERIES    "last_level_series"
 #define TOKEN_STR_LAST_PLAYED_LEVEL    "last_played_level"
 #define TOKEN_STR_HANDICAP_LEVEL       "handicap_level"
 #define TOKEN_STR_PLAYER_PREFIX                "player_"
 
-#define TOKEN_VALUE_POSITION           30
-
 /* global setup */
 #define SETUP_TOKEN_PLAYER_NAME                0
 #define SETUP_TOKEN_SOUND              1
@@ -1562,12 +1501,6 @@ void SaveScore(int level_nr)
 #define FIRST_LEVELINFO_TOKEN          LEVELINFO_TOKEN_NAME
 #define LAST_LEVELINFO_TOKEN           LEVELINFO_TOKEN_READONLY
 
-#define TYPE_BOOLEAN                   1
-#define TYPE_SWITCH                    2
-#define TYPE_KEY                       3
-#define TYPE_INTEGER                   4
-#define TYPE_STRING                    5
-
 static struct SetupInfo si;
 static struct SetupInputInfo sii;
 static struct LevelDirInfo ldi;
@@ -1625,261 +1558,6 @@ static struct
   { TYPE_BOOLEAN, &ldi.readonly,       "readonly"                      }
 };
 
-static char *string_tolower(char *s)
-{
-  static char s_lower[100];
-  int i;
-
-  if (strlen(s) >= 100)
-    return s;
-
-  strcpy(s_lower, s);
-
-  for (i=0; i<strlen(s_lower); i++)
-    s_lower[i] = tolower(s_lower[i]);
-
-  return s_lower;
-}
-
-static int get_string_integer_value(char *s)
-{
-  static char *number_text[][3] =
-  {
-    { "0", "zero", "null", },
-    { "1", "one", "first" },
-    { "2", "two", "second" },
-    { "3", "three", "third" },
-    { "4", "four", "fourth" },
-    { "5", "five", "fifth" },
-    { "6", "six", "sixth" },
-    { "7", "seven", "seventh" },
-    { "8", "eight", "eighth" },
-    { "9", "nine", "ninth" },
-    { "10", "ten", "tenth" },
-    { "11", "eleven", "eleventh" },
-    { "12", "twelve", "twelfth" },
-  };
-
-  int i, j;
-
-  for (i=0; i<13; i++)
-    for (j=0; j<3; j++)
-      if (strcmp(string_tolower(s), number_text[i][j]) == 0)
-       return i;
-
-  return atoi(s);
-}
-
-static boolean get_string_boolean_value(char *s)
-{
-  if (strcmp(string_tolower(s), "true") == 0 ||
-      strcmp(string_tolower(s), "yes") == 0 ||
-      strcmp(string_tolower(s), "on") == 0 ||
-      get_string_integer_value(s) == 1)
-    return TRUE;
-  else
-    return FALSE;
-}
-
-static char *getFormattedSetupEntry(char *token, char *value)
-{
-  int i;
-  static char entry[MAX_LINE_LEN];
-
-  sprintf(entry, "%s:", token);
-  for (i=strlen(entry); i<TOKEN_VALUE_POSITION; i++)
-    entry[i] = ' ';
-  entry[i] = '\0';
-
-  strcat(entry, value);
-
-  return entry;
-}
-
-static void freeSetupFileList(struct SetupFileList *setup_file_list)
-{
-  if (!setup_file_list)
-    return;
-
-  if (setup_file_list->token)
-    free(setup_file_list->token);
-  if (setup_file_list->value)
-    free(setup_file_list->value);
-  if (setup_file_list->next)
-    freeSetupFileList(setup_file_list->next);
-  free(setup_file_list);
-}
-
-static struct SetupFileList *newSetupFileList(char *token, char *value)
-{
-  struct SetupFileList *new = checked_malloc(sizeof(struct SetupFileList));
-
-  new->token = checked_malloc(strlen(token) + 1);
-  strcpy(new->token, token);
-
-  new->value = checked_malloc(strlen(value) + 1);
-  strcpy(new->value, value);
-
-  new->next = NULL;
-
-  return new;
-}
-
-static char *getTokenValue(struct SetupFileList *setup_file_list,
-                          char *token)
-{
-  if (!setup_file_list)
-    return NULL;
-
-  if (strcmp(setup_file_list->token, token) == 0)
-    return setup_file_list->value;
-  else
-    return getTokenValue(setup_file_list->next, token);
-}
-
-static void setTokenValue(struct SetupFileList *setup_file_list,
-                         char *token, char *value)
-{
-  if (!setup_file_list)
-    return;
-
-  if (strcmp(setup_file_list->token, token) == 0)
-  {
-    free(setup_file_list->value);
-    setup_file_list->value = checked_malloc(strlen(value) + 1);
-    strcpy(setup_file_list->value, value);
-  }
-  else if (setup_file_list->next == NULL)
-    setup_file_list->next = newSetupFileList(token, value);
-  else
-    setTokenValue(setup_file_list->next, token, value);
-}
-
-#ifdef DEBUG
-static void printSetupFileList(struct SetupFileList *setup_file_list)
-{
-  if (!setup_file_list)
-    return;
-
-  printf("token: '%s'\n", setup_file_list->token);
-  printf("value: '%s'\n", setup_file_list->value);
-
-  printSetupFileList(setup_file_list->next);
-}
-#endif
-
-static struct SetupFileList *loadSetupFileList(char *filename)
-{
-  int line_len;
-  char line[MAX_LINE_LEN];
-  char *token, *value, *line_ptr;
-  struct SetupFileList *setup_file_list = newSetupFileList("", "");
-  struct SetupFileList *first_valid_list_entry;
-
-  FILE *file;
-
-  if (!(file = fopen(filename, MODE_READ)))
-  {
-    Error(ERR_WARN, "cannot open configuration file '%s'", filename);
-    return NULL;
-  }
-
-  while(!feof(file))
-  {
-    /* read next line of input file */
-    if (!fgets(line, MAX_LINE_LEN, file))
-      break;
-
-    /* cut trailing comment or whitespace from input line */
-    for (line_ptr = line; *line_ptr; line_ptr++)
-    {
-      if (*line_ptr == '#' || *line_ptr == '\n' || *line_ptr == '\r')
-      {
-       *line_ptr = '\0';
-       break;
-      }
-    }
-
-    /* cut trailing whitespaces from input line */
-    for (line_ptr = &line[strlen(line)]; line_ptr > line; line_ptr--)
-      if ((*line_ptr == ' ' || *line_ptr == '\t') && line_ptr[1] == '\0')
-       *line_ptr = '\0';
-
-    /* ignore empty lines */
-    if (*line == '\0')
-      continue;
-
-    line_len = strlen(line);
-
-    /* cut leading whitespaces from token */
-    for (token = line; *token; token++)
-      if (*token != ' ' && *token != '\t')
-       break;
-
-    /* find end of token */
-    for (line_ptr = token; *line_ptr; line_ptr++)
-    {
-      if (*line_ptr == ' ' || *line_ptr == '\t' || *line_ptr == ':')
-      {
-       *line_ptr = '\0';
-       break;
-      }
-    }
-
-    if (line_ptr < line + line_len)
-      value = line_ptr + 1;
-    else
-      value = "\0";
-
-    /* cut leading whitespaces from value */
-    for (; *value; value++)
-      if (*value != ' ' && *value != '\t')
-       break;
-
-    if (*token && *value)
-      setTokenValue(setup_file_list, token, value);
-  }
-
-  fclose(file);
-
-  first_valid_list_entry = setup_file_list->next;
-
-  /* free empty list header */
-  setup_file_list->next = NULL;
-  freeSetupFileList(setup_file_list);
-
-  if (first_valid_list_entry == NULL)
-    Error(ERR_WARN, "configuration file '%s' is empty", filename);
-
-  return first_valid_list_entry;
-}
-
-static void checkSetupFileListIdentifier(struct SetupFileList *setup_file_list,
-                                        char *identifier)
-{
-  if (!setup_file_list)
-    return;
-
-  if (strcmp(setup_file_list->token, TOKEN_STR_FILE_IDENTIFIER) == 0)
-  {
-    if (strcmp(setup_file_list->value, identifier) != 0)
-    {
-      Error(ERR_WARN, "configuration file has wrong version");
-      return;
-    }
-    else
-      return;
-  }
-
-  if (setup_file_list->next)
-    checkSetupFileListIdentifier(setup_file_list->next, identifier);
-  else
-  {
-    Error(ERR_WARN, "configuration file has no version information");
-    return;
-  }
-}
-
 static void setLevelDirInfoToDefaults(struct LevelDirInfo *ldi)
 {
   ldi->filename = NULL;
@@ -2285,7 +1963,7 @@ static void SaveUserLevelInfo()
   fclose(file);
   free(filename);
 
-  SetFilePermissions_Setup(filename);
+  SetFilePermissions(filename, PERMS_PRIVATE);
 }
 
 void LoadSetup()
@@ -2438,7 +2116,7 @@ void SaveSetup()
   fclose(file);
   free(filename);
 
-  SetFilePermissions_Setup(filename);
+  SetFilePermissions(filename, PERMS_PRIVATE);
 }
 
 void LoadLevelSetup_LastSeries()
@@ -2503,7 +2181,7 @@ void SaveLevelSetup_LastSeries()
   fclose(file);
   free(filename);
 
-  SetFilePermissions_Setup(filename);
+  SetFilePermissions(filename, PERMS_PRIVATE);
 }
 
 static void checkSeriesInfo()
@@ -2650,5 +2328,5 @@ void SaveLevelSetup_SeriesInfo()
   fclose(file);
   free(filename);
 
-  SetFilePermissions_Setup(filename);
+  SetFilePermissions(filename, PERMS_PRIVATE);
 }
index 190901ced6e6166f8d8851ddb161ddfd98b05273..b3edef75f1bbf367d8a8d244ad6ef3b67a3ac8c8 100644 (file)
@@ -731,6 +731,18 @@ void putFileChunk(FILE *file, char *chunk_name, int chunk_size,
   }
 }
 
+void ReadUnusedBytesFromFile(FILE *file, unsigned long bytes)
+{
+  while (bytes--)
+    fgetc(file);
+}
+
+void WriteUnusedBytesToFile(FILE *file, unsigned long bytes)
+{
+  while (bytes--)
+    fputc(0, file);
+}
+
 #define TRANSLATE_KEYSYM_TO_KEYNAME    0
 #define TRANSLATE_KEYSYM_TO_X11KEYNAME 1
 #define TRANSLATE_X11KEYNAME_TO_KEYSYM 2
@@ -1300,17 +1312,16 @@ inline void swap_number_pairs(int *x1, int *y1, int *x2, int *y2)
 #define MODE_R_ALL             (S_IRUSR | S_IRGRP | S_IROTH)
 #define MODE_W_ALL             (S_IWUSR | S_IWGRP | S_IWOTH)
 #define MODE_X_ALL             (S_IXUSR | S_IXGRP | S_IXOTH)
-#define MODE_W_ALL             (S_IWUSR | S_IWGRP | S_IWOTH)
 
-#define MODE_W_USR_GRP         (S_IWUSR | S_IWGRP)
-#define MODE_W_NEW_DIR         (S_ISGID | MODE_W_USR_GRP)
+#define MODE_W_PRIVATE         (S_IWUSR)
+#define MODE_W_PUBLIC          (S_IWUSR | S_IWGRP)
+#define MODE_W_PUBLIC_DIR      (S_IWUSR | S_IWGRP | S_ISGID)
 
-#define USERDATA_DIR_MODE      (MODE_R_ALL | MODE_X_ALL | MODE_W_NEW_DIR)
+#define DIR_PERMS_PRIVATE      (MODE_R_ALL | MODE_X_ALL | MODE_W_PRIVATE)
+#define DIR_PERMS_PUBLIC       (MODE_R_ALL | MODE_X_ALL | MODE_W_PUBLIC_DIR)
 
-#define LEVEL_PERMS            (MODE_R_ALL | MODE_W_USR_GRP)
-#define SCORE_PERMS            LEVEL_PERMS
-#define TAPE_PERMS             LEVEL_PERMS
-#define SETUP_PERMS            LEVEL_PERMS
+#define FILE_PERMS_PRIVATE     (MODE_R_ALL | MODE_W_PRIVATE)
+#define FILE_PERMS_PUBLIC      (MODE_R_ALL | MODE_W_PUBLIC)
 
 char *getUserDataDir(void)
 {
@@ -1327,13 +1338,20 @@ char *getUserDataDir(void)
   return userdata_dir;
 }
 
-void createDirectory(char *dir, char *text)
+char *getSetupDir()
+{
+  return getUserDataDir();
+}
+
+void createDirectory(char *dir, char *text, int permission_class)
 {
 #if defined(PLATFORM_UNIX)
   /* leave "other" permissions in umask untouched, but ensure group parts
      of USERDATA_DIR_MODE are not masked */
+  mode_t dir_mode = (permission_class == PERMS_PRIVATE ?
+                    DIR_PERMS_PRIVATE : DIR_PERMS_PUBLIC);
   mode_t normal_umask = umask(0);
-  mode_t group_umask = ~(USERDATA_DIR_MODE & S_IRWXG);
+  mode_t group_umask = ~(dir_mode & S_IRWXG);
   umask(normal_umask & group_umask);
 #endif
 
@@ -1341,7 +1359,7 @@ void createDirectory(char *dir, char *text)
 #if defined(PLATFORM_WIN32)
     if (mkdir(dir) != 0)
 #else
-    if (mkdir(dir, USERDATA_DIR_MODE) != 0)
+    if (mkdir(dir, dir_mode) != 0)
 #endif
       Error(ERR_WARN, "cannot create %s directory '%s'", text, dir);
 
@@ -1352,27 +1370,318 @@ void createDirectory(char *dir, char *text)
 
 void InitUserDataDirectory()
 {
-  createDirectory(getUserDataDir(), "user data");
+  createDirectory(getUserDataDir(), "user data", PERMS_PRIVATE);
+}
+
+void SetFilePermissions(char *filename, int permission_class)
+{
+  chmod(filename, (permission_class == PERMS_PRIVATE ?
+                  FILE_PERMS_PRIVATE : FILE_PERMS_PUBLIC));
+}
+
+int getFileVersionFromCookieString(const char *cookie)
+{
+  const char *ptr_cookie1, *ptr_cookie2;
+  const char *pattern1 = "_FILE_VERSION_";
+  const char *pattern2 = "?.?";
+  const int len_cookie = strlen(cookie);
+  const int len_pattern1 = strlen(pattern1);
+  const int len_pattern2 = strlen(pattern2);
+  const int len_pattern = len_pattern1 + len_pattern2;
+  int version_major, version_minor;
+
+  if (len_cookie <= len_pattern)
+    return -1;
+
+  ptr_cookie1 = &cookie[len_cookie - len_pattern];
+  ptr_cookie2 = &cookie[len_cookie - len_pattern2];
+
+  if (strncmp(ptr_cookie1, pattern1, len_pattern1) != 0)
+    return -1;
+
+  if (ptr_cookie2[0] < '0' || ptr_cookie2[0] > '9' ||
+      ptr_cookie2[1] != '.' ||
+      ptr_cookie2[2] < '0' || ptr_cookie2[2] > '9')
+    return -1;
+
+  version_major = ptr_cookie2[0] - '0';
+  version_minor = ptr_cookie2[2] - '0';
+
+  return VERSION_IDENT(version_major, version_minor, 0);
+}
+
+boolean checkCookieString(const char *cookie, const char *template)
+{
+  const char *pattern = "_FILE_VERSION_?.?";
+  const int len_cookie = strlen(cookie);
+  const int len_template = strlen(template);
+  const int len_pattern = strlen(pattern);
+
+  if (len_cookie != len_template)
+    return FALSE;
+
+  if (strncmp(cookie, template, len_cookie - len_pattern) != 0)
+    return FALSE;
+
+  return TRUE;
+}
+
+/* ------------------------------------------------------------------------- */
+/* setup file stuff                                                          */
+/* ------------------------------------------------------------------------- */
+
+static char *string_tolower(char *s)
+{
+  static char s_lower[100];
+  int i;
+
+  if (strlen(s) >= 100)
+    return s;
+
+  strcpy(s_lower, s);
+
+  for (i=0; i<strlen(s_lower); i++)
+    s_lower[i] = tolower(s_lower[i]);
+
+  return s_lower;
 }
 
-void SetFilePermissions_Level(char *filename)
+int get_string_integer_value(char *s)
 {
-  chmod(filename, LEVEL_PERMS);
+  static char *number_text[][3] =
+  {
+    { "0", "zero", "null", },
+    { "1", "one", "first" },
+    { "2", "two", "second" },
+    { "3", "three", "third" },
+    { "4", "four", "fourth" },
+    { "5", "five", "fifth" },
+    { "6", "six", "sixth" },
+    { "7", "seven", "seventh" },
+    { "8", "eight", "eighth" },
+    { "9", "nine", "ninth" },
+    { "10", "ten", "tenth" },
+    { "11", "eleven", "eleventh" },
+    { "12", "twelve", "twelfth" },
+  };
+
+  int i, j;
+
+  for (i=0; i<13; i++)
+    for (j=0; j<3; j++)
+      if (strcmp(string_tolower(s), number_text[i][j]) == 0)
+       return i;
+
+  return atoi(s);
 }
 
-void SetFilePermissions_Tape(char *filename)
+boolean get_string_boolean_value(char *s)
 {
-  chmod(filename, TAPE_PERMS);
+  if (strcmp(string_tolower(s), "true") == 0 ||
+      strcmp(string_tolower(s), "yes") == 0 ||
+      strcmp(string_tolower(s), "on") == 0 ||
+      get_string_integer_value(s) == 1)
+    return TRUE;
+  else
+    return FALSE;
 }
 
-void SetFilePermissions_Score(char *filename)
+char *getFormattedSetupEntry(char *token, char *value)
 {
-  chmod(filename, SCORE_PERMS);
+  int i;
+  static char entry[MAX_LINE_LEN];
+
+  sprintf(entry, "%s:", token);
+  for (i=strlen(entry); i<TOKEN_VALUE_POSITION; i++)
+    entry[i] = ' ';
+  entry[i] = '\0';
+
+  strcat(entry, value);
+
+  return entry;
 }
 
-void SetFilePermissions_Setup(char *filename)
+void freeSetupFileList(struct SetupFileList *setup_file_list)
 {
-  chmod(filename, SETUP_PERMS);
+  if (!setup_file_list)
+    return;
+
+  if (setup_file_list->token)
+    free(setup_file_list->token);
+  if (setup_file_list->value)
+    free(setup_file_list->value);
+  if (setup_file_list->next)
+    freeSetupFileList(setup_file_list->next);
+  free(setup_file_list);
+}
+
+static struct SetupFileList *newSetupFileList(char *token, char *value)
+{
+  struct SetupFileList *new = checked_malloc(sizeof(struct SetupFileList));
+
+  new->token = checked_malloc(strlen(token) + 1);
+  strcpy(new->token, token);
+
+  new->value = checked_malloc(strlen(value) + 1);
+  strcpy(new->value, value);
+
+  new->next = NULL;
+
+  return new;
+}
+
+char *getTokenValue(struct SetupFileList *setup_file_list, char *token)
+{
+  if (!setup_file_list)
+    return NULL;
+
+  if (strcmp(setup_file_list->token, token) == 0)
+    return setup_file_list->value;
+  else
+    return getTokenValue(setup_file_list->next, token);
+}
+
+static void setTokenValue(struct SetupFileList *setup_file_list,
+                         char *token, char *value)
+{
+  if (!setup_file_list)
+    return;
+
+  if (strcmp(setup_file_list->token, token) == 0)
+  {
+    free(setup_file_list->value);
+    setup_file_list->value = checked_malloc(strlen(value) + 1);
+    strcpy(setup_file_list->value, value);
+  }
+  else if (setup_file_list->next == NULL)
+    setup_file_list->next = newSetupFileList(token, value);
+  else
+    setTokenValue(setup_file_list->next, token, value);
+}
+
+#ifdef DEBUG
+static void printSetupFileList(struct SetupFileList *setup_file_list)
+{
+  if (!setup_file_list)
+    return;
+
+  printf("token: '%s'\n", setup_file_list->token);
+  printf("value: '%s'\n", setup_file_list->value);
+
+  printSetupFileList(setup_file_list->next);
+}
+#endif
+
+struct SetupFileList *loadSetupFileList(char *filename)
+{
+  int line_len;
+  char line[MAX_LINE_LEN];
+  char *token, *value, *line_ptr;
+  struct SetupFileList *setup_file_list = newSetupFileList("", "");
+  struct SetupFileList *first_valid_list_entry;
+
+  FILE *file;
+
+  if (!(file = fopen(filename, MODE_READ)))
+  {
+    Error(ERR_WARN, "cannot open configuration file '%s'", filename);
+    return NULL;
+  }
+
+  while(!feof(file))
+  {
+    /* read next line of input file */
+    if (!fgets(line, MAX_LINE_LEN, file))
+      break;
+
+    /* cut trailing comment or whitespace from input line */
+    for (line_ptr = line; *line_ptr; line_ptr++)
+    {
+      if (*line_ptr == '#' || *line_ptr == '\n' || *line_ptr == '\r')
+      {
+       *line_ptr = '\0';
+       break;
+      }
+    }
+
+    /* cut trailing whitespaces from input line */
+    for (line_ptr = &line[strlen(line)]; line_ptr > line; line_ptr--)
+      if ((*line_ptr == ' ' || *line_ptr == '\t') && line_ptr[1] == '\0')
+       *line_ptr = '\0';
+
+    /* ignore empty lines */
+    if (*line == '\0')
+      continue;
+
+    line_len = strlen(line);
+
+    /* cut leading whitespaces from token */
+    for (token = line; *token; token++)
+      if (*token != ' ' && *token != '\t')
+       break;
+
+    /* find end of token */
+    for (line_ptr = token; *line_ptr; line_ptr++)
+    {
+      if (*line_ptr == ' ' || *line_ptr == '\t' || *line_ptr == ':')
+      {
+       *line_ptr = '\0';
+       break;
+      }
+    }
+
+    if (line_ptr < line + line_len)
+      value = line_ptr + 1;
+    else
+      value = "\0";
+
+    /* cut leading whitespaces from value */
+    for (; *value; value++)
+      if (*value != ' ' && *value != '\t')
+       break;
+
+    if (*token && *value)
+      setTokenValue(setup_file_list, token, value);
+  }
+
+  fclose(file);
+
+  first_valid_list_entry = setup_file_list->next;
+
+  /* free empty list header */
+  setup_file_list->next = NULL;
+  freeSetupFileList(setup_file_list);
+
+  if (first_valid_list_entry == NULL)
+    Error(ERR_WARN, "configuration file '%s' is empty", filename);
+
+  return first_valid_list_entry;
+}
+
+void checkSetupFileListIdentifier(struct SetupFileList *setup_file_list,
+                                 char *identifier)
+{
+  if (!setup_file_list)
+    return;
+
+  if (strcmp(setup_file_list->token, TOKEN_STR_FILE_IDENTIFIER) == 0)
+  {
+    if (strcmp(setup_file_list->value, identifier) != 0)
+    {
+      Error(ERR_WARN, "configuration file has wrong version");
+      return;
+    }
+    else
+      return;
+  }
+
+  if (setup_file_list->next)
+    checkSetupFileListIdentifier(setup_file_list->next, identifier);
+  else
+  {
+    Error(ERR_WARN, "configuration file has no version information");
+    return;
+  }
 }
 
 
index 3af58389d25d9186d86d59620af76d7d0bbf431c..978cb23b965ba5ed535c52919190db37beef716b 100644 (file)
 #include "system.h"
 
 
+/* functions for version handling */
+#define VERSION_IDENT(x,y,z)   ((x) * 10000 + (y) * 100 + (z))
+#define VERSION_MAJOR(x)       ((x) / 10000)
+#define VERSION_MINOR(x)       (((x) % 10000) / 100)
+#define VERSION_PATCH(x)       ((x) % 100)
+
 /* values for InitCounter() and Counter() */
 #define INIT_COUNTER                   0
 #define READ_COUNTER                   1
 #define BYTE_ORDER_BIG_ENDIAN          0
 #define BYTE_ORDER_LITTLE_ENDIAN       1
 
+/* values for createDirectory() */
+#define PERMS_PRIVATE                  0
+#define PERMS_PUBLIC                   1
+
+/* values for general file handling stuff */
+#define MAX_FILENAME_LEN               256
+#define MAX_LINE_LEN                   1000
+
+/* values for setup file stuff */
+#define TYPE_BOOLEAN                   1
+#define TYPE_SWITCH                    2
+#define TYPE_KEY                       3
+#define TYPE_INTEGER                   4
+#define TYPE_STRING                    5
+
+#define TOKEN_STR_FILE_IDENTIFIER      "file_identifier"
+
+#define TOKEN_VALUE_POSITION           30
+
+struct SetupFileList
+{
+  char *token;
+  char *value;
+  struct SetupFileList *next;
+};
+
 void InitCounter(void);
 unsigned long Counter(void);
 void Delay(unsigned long);
@@ -73,6 +105,9 @@ int getFile32BitInteger(FILE *, int);
 void putFile32BitInteger(FILE *, int, int);
 boolean getFileChunk(FILE *, char *, int *, int);
 void putFileChunk(FILE *, char *, int, int);
+void ReadUnusedBytesFromFile(FILE *, unsigned long);
+void WriteUnusedBytesToFile(FILE *, unsigned long);
+
 char *getKeyNameFromKey(Key);
 char *getX11KeyNameFromKey(Key);
 Key getKeyFromX11KeyName(char *);
@@ -99,12 +134,20 @@ inline void swap_numbers(int *, int *);
 inline void swap_number_pairs(int *, int *, int *, int *);
 
 char *getUserDataDir(void);
-void createDirectory(char *, char *);
+char *getSetupDir(void);
+void createDirectory(char *, char *, int);
 void InitUserDataDirectory(void);
-void SetFilePermissions_Level(char *);
-void SetFilePermissions_Tape(char *);
-void SetFilePermissions_Score(char *);
-void SetFilePermissions_Setup(char *);
+void SetFilePermissions(char *, int);
+int getFileVersionFromCookieString(const char *);
+boolean checkCookieString(const char *, const char *);
+
+int get_string_integer_value(char *);
+boolean get_string_boolean_value(char *);
+char *getFormattedSetupEntry(char *, char *);
+void freeSetupFileList(struct SetupFileList *);
+char *getTokenValue(struct SetupFileList *, char *);
+struct SetupFileList *loadSetupFileList(char *);
+void checkSetupFileListIdentifier(struct SetupFileList *, char *);
 
 #if !defined(PLATFORM_UNIX)
 void initErrorFile();
index da629d537244d5e8a2330c6fdce43c6c9464f80d..27cc057bde42de7ad8d069aac1422924ab4a964d 100644 (file)
@@ -262,13 +262,6 @@ struct SetupInfo
   struct SetupInputInfo input[MAX_PLAYERS];
 };
 
-struct SetupFileList
-{
-  char *token;
-  char *value;
-  struct SetupFileList *next;
-};
-
 struct PlayerInfo
 {
   boolean present;             /* player present in level playfield */
@@ -1552,11 +1545,6 @@ extern int               num_element_info;
 #define X11_ICONMASK_FILENAME  "rocks_iconmask.xbm"
 #define MSDOS_POINTER_FILENAME "mouse.pcx"
 
-#define VERSION_IDENT(x,y,z)   ((x) * 10000 + (y) * 100 + (z))
-#define VERSION_MAJOR(x)       ((x) / 10000)
-#define VERSION_MINOR(x)       (((x) % 10000) / 100)
-#define VERSION_PATCH(x)       ((x) % 100)
-
 /* file version numbers for resource files (levels, tapes, score, setup, etc.)
 ** currently supported/known file version numbers:
 **     1.0 (old)