View | Details | Raw Unified | Return to bug 31587
Collapse All | Expand All

(-)module.c (-6 / +92 lines)
Lines 72-77 Link Here
72
#include "arith.h"
72
#include "arith.h"
73
#include "match.h"
73
#include "match.h"
74
#include "parse.h" /* FIXME */
74
#include "parse.h" /* FIXME */
75
#include "md5.h"
75
76
76
#define MODULE_EXTENSION ".mod"
77
#define MODULE_EXTENSION ".mod"
77
78
Lines 170-175 Link Here
170
/* The FILE for the module we're reading or writing.  */
171
/* The FILE for the module we're reading or writing.  */
171
static FILE *module_fp;
172
static FILE *module_fp;
172
173
174
/* MD5 context structure.  */
175
static struct md5_ctx ctx;
176
173
/* The name of the module we're reading (USE'ing) or writing.  */
177
/* The name of the module we're reading (USE'ing) or writing.  */
174
static char module_name[GFC_MAX_SYMBOL_LEN + 1];
178
static char module_name[GFC_MAX_SYMBOL_LEN + 1];
175
179
Lines 1275-1280 Link Here
1275
  if (fputc (out, module_fp) == EOF)
1279
  if (fputc (out, module_fp) == EOF)
1276
    gfc_fatal_error ("Error writing modules file: %s", strerror (errno));
1280
    gfc_fatal_error ("Error writing modules file: %s", strerror (errno));
1277
1281
1282
  /* Add this to our MD5.  */
1283
  md5_process_bytes (&out, sizeof (out), &ctx);
1284
  
1278
  if (out != '\n')
1285
  if (out != '\n')
1279
    module_column++;
1286
    module_column++;
1280
  else
1287
  else
Lines 3916-3921 Link Here
3916
}
3923
}
3917
3924
3918
3925
3926
/* Read a MD5 sum from the header of a module file.  If the file cannot
3927
   be opened, or we have any other error, we return -1.  */
3928
3929
static int
3930
read_md5_from_module_file (const char * filename, unsigned char md5[16])
3931
{
3932
  FILE *file;
3933
  char buf[1024];
3934
  int n;
3935
3936
  /* Open the file.  */
3937
  if ((file = fopen (filename, "r")) == NULL)
3938
    return -1;
3939
3940
  /* Read two lines.  */
3941
  if (fgets (buf, sizeof (buf) - 1, file) == NULL
3942
      || fgets (buf, sizeof (buf) - 1, file) == NULL)
3943
    {
3944
      fclose (file);
3945
      return -1;
3946
    }
3947
3948
  /* Close the file.  */
3949
  fclose (file);
3950
3951
  /* If the header is not what we expect, or is too short, bail out.  */
3952
  if (strncmp (buf, "MD5:", 4) != 0 || strlen (buf) < 4 + 16)
3953
    return -1;
3954
3955
  /* Now, we have a real MD5, read it into the array.  */
3956
  for (n = 0; n < 16; n++)
3957
    {
3958
      unsigned int x;
3959
3960
      if (sscanf (&(buf[4+2*n]), "%02x", &x) != 1)
3961
	return -1;
3962
3963
      md5[n] = x;
3964
    }
3965
3966
  return 0;
3967
}
3968
3919
/* Given module, dump it to disk.  If there was an error while
3969
/* Given module, dump it to disk.  If there was an error while
3920
   processing the module, dump_flag will be set to zero and we delete
3970
   processing the module, dump_flag will be set to zero and we delete
3921
   the module file, even if it was already there.  */
3971
   the module file, even if it was already there.  */
Lines 3924-3936 Link Here
3924
gfc_dump_module (const char *name, int dump_flag)
3974
gfc_dump_module (const char *name, int dump_flag)
3925
{
3975
{
3926
  int n;
3976
  int n;
3927
  char *filename, *p;
3977
  char *filename, *filename_tmp, *p;
3928
  time_t now;
3978
  time_t now;
3979
  fpos_t md5_pos;
3980
  unsigned char md5_new[16], md5_old[16];
3929
3981
3930
  n = strlen (name) + strlen (MODULE_EXTENSION) + 1;
3982
  n = strlen (name) + strlen (MODULE_EXTENSION) + 1;
3931
  if (gfc_option.module_dir != NULL)
3983
  if (gfc_option.module_dir != NULL)
3932
    {
3984
    {
3933
      filename = (char *) alloca (n + strlen (gfc_option.module_dir));
3985
      n += strlen (gfc_option.module_dir);
3986
      filename = (char *) alloca (n);
3934
      strcpy (filename, gfc_option.module_dir);
3987
      strcpy (filename, gfc_option.module_dir);
3935
      strcat (filename, name);
3988
      strcat (filename, name);
3936
    }
3989
    }
Lines 3941-3957 Link Here
3941
    }
3994
    }
3942
  strcat (filename, MODULE_EXTENSION);
3995
  strcat (filename, MODULE_EXTENSION);
3943
3996
3997
  /* Name of the temporary file used to write the module.  */
3998
  filename_tmp = (char *) alloca (n + 1);
3999
  strcpy (filename_tmp, filename);
4000
  strcat (filename_tmp, "0");
4001
4002
  /* There was an error while processing the module.  We delete the
4003
     module file, even if it was already there.  */
3944
  if (!dump_flag)
4004
  if (!dump_flag)
3945
    {
4005
    {
3946
      unlink (filename);
4006
      unlink (filename);
3947
      return;
4007
      return;
3948
    }
4008
    }
3949
4009
3950
  module_fp = fopen (filename, "w");
4010
  /* Write the module to the temporary file.  */
4011
  module_fp = fopen (filename_tmp, "w");
3951
  if (module_fp == NULL)
4012
  if (module_fp == NULL)
3952
    gfc_fatal_error ("Can't open module file '%s' for writing at %C: %s",
4013
    gfc_fatal_error ("Can't open module file '%s' for writing at %C: %s",
3953
		     filename, strerror (errno));
4014
		     filename_tmp, strerror (errno));
3954
4015
4016
  /* Write the header, including space reserved for the MD5 sum.  */
3955
  now = time (NULL);
4017
  now = time (NULL);
3956
  p = ctime (&now);
4018
  p = ctime (&now);
3957
4019
Lines 3959-3966 Link Here
3959
4021
3960
  fprintf (module_fp, "GFORTRAN module created from %s on %s\n", 
4022
  fprintf (module_fp, "GFORTRAN module created from %s on %s\n", 
3961
	   gfc_source_file, p);
4023
	   gfc_source_file, p);
3962
  fputs ("If you edit this, you'll get what you deserve.\n\n", module_fp);
4024
  fputs ("MD5:", module_fp);
4025
  fgetpos (module_fp, &md5_pos);
4026
  fputs ("00000000000000000000000000000000 -- "
4027
	 "If you edit this, you'll get what you deserve.\n\n", module_fp);
3963
4028
4029
  /* Initialize the MD5 context that will be used for output.  */
4030
  md5_init_ctx (&ctx);
4031
4032
  /* Write the module itself.  */
3964
  iomode = IO_OUTPUT;
4033
  iomode = IO_OUTPUT;
3965
  strcpy (module_name, name);
4034
  strcpy (module_name, name);
3966
4035
Lines 3973-3981 Link Here
3973
4042
3974
  write_char ('\n');
4043
  write_char ('\n');
3975
4044
4045
  /* Write the MD5 sum to the header of the module file.  */
4046
  md5_finish_ctx (&ctx, md5_new);
4047
  fsetpos (module_fp, &md5_pos);
4048
  for (n = 0; n < 16; n++)
4049
    fprintf (module_fp, "%02x", md5_new[n]);
4050
3976
  if (fclose (module_fp))
4051
  if (fclose (module_fp))
3977
    gfc_fatal_error ("Error writing module file '%s' for writing: %s",
4052
    gfc_fatal_error ("Error writing module file '%s' for writing: %s",
3978
		     filename, strerror (errno));
4053
		     filename_tmp, strerror (errno));
4054
4055
  /* Read the MD5 from the header of the old module file and compare.  */
4056
  if (read_md5_from_module_file (filename, md5_old) != 0
4057
      || memcmp (md5_old, md5_new, sizeof (md5_old)) != 0)
4058
    {
4059
      /* Module file have changed, replace the old one.  */
4060
      unlink (filename);
4061
      rename (filename_tmp, filename);
4062
    }
4063
  else
4064
    unlink (filename_tmp);
3979
}
4065
}
3980
4066
3981
4067

Return to bug 31587