RAND_load_file(..., -1) now means "read the complete file";
[openssl.git] / crypto / rand / randfile.c
index cf98643d3c778b5a5a1a6f043ab5d01a204c27fe..cea9f54e731388f1e4209ca60649fb2ee0d18835 100644 (file)
@@ -82,6 +82,9 @@
 
 int RAND_load_file(const char *file, long bytes)
        {
+       /* If bytes >= 0, read up to 'bytes' bytes.
+        * if bytes == -1, read complete file. */
+
        MS_STATIC unsigned char buf[BUFSIZE];
        struct stat sb;
        int i,ret=0,n;
@@ -92,22 +95,27 @@ int RAND_load_file(const char *file, long bytes)
        i=stat(file,&sb);
        /* If the state fails, put some crap in anyway */
        RAND_add(&sb,sizeof(sb),0);
-       ret+=sizeof(sb);
        if (i < 0) return(0);
-       if (bytes <= 0) return(ret);
+       if (bytes == 0) return(ret);
 
        in=fopen(file,"rb");
        if (in == NULL) goto err;
        for (;;)
                {
-               n=(bytes < BUFSIZE)?(int)bytes:BUFSIZE;
+               if (bytes > 0)
+                       n = (bytes < BUFSIZE)?(int)bytes:BUFSIZE;
+               else
+                       n = BUFSIZE;
                i=fread(buf,1,n,in);
                if (i <= 0) break;
                /* even if n != i, use the full array */
                RAND_add(buf,n,i);
                ret+=i;
-               bytes-=n;
-               if (bytes <= 0) break;
+               if (bytes > 0)
+                       {
+                       bytes-=n;
+                       if (bytes == 0) break;
+                       }
                }
        fclose(in);
        memset(buf,0,BUFSIZE);
@@ -122,27 +130,23 @@ int RAND_write_file(const char *file)
        FILE *out = NULL;
        int n;
 
+#ifdef VMS
        /* Under VMS, fopen(file, "wb") will create a new version of the
           same file.  This is not good, so let's try updating an existing
-          one, and create file only if it doesn't already exist.  This
-          should be completely harmless on system that have no file
-          versions.                                    -- Richard Levitte */
+          one, and create file only if it doesn't already exist. */
        out=fopen(file,"rb+");
-       if (out == NULL
-#ifdef ENOENT
-           && errno == ENOENT
+       if (out == NULL && errno != ENOENT)
+               goto err;
 #endif
-          )
+
+       if (out == NULL)
                {
-               errno = 0;
 #if defined O_CREAT && defined O_EXCL
                /* chmod(..., 0600) is too late to protect the file,
                 * permissions should be restrictive from the start */
-               {
-                   int fd = open(file, O_CREAT | O_EXCL, 0600);
-                   if (fd != -1)
+               int fd = open(file, O_CREAT | O_EXCL, 0600);
+               if (fd != -1)
                        out = fdopen(fd, "wb");
-               }
 #else          
                out=fopen(file,"wb");
 #endif
@@ -167,8 +171,13 @@ int RAND_write_file(const char *file)
                ret+=i;
                if (n <= 0) break;
                }
+#ifdef VMS
+       /* We may have updated an existing file using mode "rb+",
+        * now remove any old extra bytes */
        if (ret > 0)
                ftruncate(fileno(out), ret);
+#endif
+
        fclose(out);
        memset(buf,0,BUFSIZE);
 err: