1 #if HAVE_CONFIG_H
2 #   include "config.h"
3 #endif
4 
5 #if HAVE_STDIO_H
6 #   include <stdio.h>
7 #endif
8 #if HAVE_STRING_H
9 #   include <string.h>
10 #endif
11 #if HAVE_MEMORY_H
12 #   include <memory.h>
13 #endif
14 #if HAVE_STDLIB_H
15 #   include <stdlib.h>
16 #endif
17 
18 extern void free(void *ptr);
19 
20 #include "msgtypesc.h"
21 #include "sndrcv.h"
22 #include "tcgmsgP.h"
23 
24 /**
25  * Process node0 has a file (assumed unopened) named fname.
26  * This file will be copied to all other processes which must
27  * simultaneously invoke pfilecopy. Since the processes may be
28  * using the same directory one probably ought to make sure
29  * that each process uses a different name in the call.
30  *
31  *    e.g.
32  *
33  *    on node 0    pfilecopy(99, 0, 'argosin')
34  *    on node 1    pfilecopy(99, 0, 'argosin_001')
35  *    on node 2    pfilecopy(99, 0, 'argosin_002')
36  */
tcgi_pfilecopy(long * type,long * node0,char * filename)37 void tcgi_pfilecopy(long *type, long *node0, char *filename)
38 {
39     char *buffer;
40     FILE *file;
41     long length, nread=32768, len_nread=sizeof(long);
42     long typenr = (*type & 32767) | MSGINT;   /* Force user type integer */
43     long typebuf =(*type & 32767) | MSGCHR;
44 
45     if (!(buffer = malloc((unsigned) nread))) {
46         Error("pfilecopy: failed to allocate the I/O buffer",nread);
47     }
48 
49     if (*node0 == NODEID_()) {
50 
51         /* I have the original file ... open and check its size */
52 
53         if ((file = fopen(filename,"r")) == (FILE *) NULL) {
54             (void) fprintf(stderr, "me=" FMT_INT ", filename = %s.\n",
55                            NODEID_(), filename);
56             Error("pfilecopy: node0 failed to open original file", *node0);
57         }
58 
59         /* Quick sanity check on the length */
60 
61         (void) fseek(file, 0L, (int) 2);   /* Seek to end of file */
62         length = ftell(file);              /* Find the length of file */
63         (void) fseek(file, 0L, (int) 0);   /* Seek to beginning of file */
64         if ( (length<0) || (length>1e12) ) {
65             Error("pfilecopy: the file length is -ve or very big", length);
66         }
67 
68         /* Send the file in chunks of nread bytes */
69 
70         while (nread) {
71             nread = fread(buffer, 1, (int) nread, file);
72             BRDCST_(&typenr, (char *) &nread, &len_nread, node0);
73             typenr++;
74             if (nread) {
75                 BRDCST_(&typebuf, buffer, &nread, node0);
76                 typebuf++;
77             }
78         }
79     }
80     else {
81 
82         /* Open the file for the duplicate */
83 
84         if ((file = fopen(filename,"w+")) == (FILE *) NULL) {
85             (void) fprintf(stderr,"me=" FMT_INT ", filename = %s.\n",
86                            NODEID_(), filename);
87             Error("pfilecopy: failed to open duplicate file", *node0);
88         }
89 
90         /* Receive data and write to file */
91 
92         while (nread) {
93             BRDCST_(&typenr, (char *) &nread, &len_nread, node0);
94             typenr++;
95             if (nread) {
96                 BRDCST_(&typebuf, buffer, &nread, node0);
97                 typebuf++;
98                 if (nread != (long)fwrite(buffer, 1, (int) nread, file)) {
99                     Error("pfilecopy: error data to duplicate file", nread);
100                 }
101             }
102         }
103     }
104 
105     /* Tidy up the stuff we have been using */
106 
107     (void) fflush(file);
108     (void) fclose(file);
109     (void) free(buffer);
110 }
111 
112 /** The original C interface to PFCOPY_. */
PFILECOPY_(long * type,long * node0,char * filename)113 void PFILECOPY_(long *type, long *node0, char *filename)
114 {
115      tcgi_pfilecopy(type, node0, filename);
116 }
117 
118 /** Fortran wrapper around pfilecopy */
PFCOPY_(long * type,long * node0,char * fname,int len)119 void PFCOPY_(long *type, long *node0, char *fname, int len)
120 {
121 
122     char *filename;
123 
124 #ifdef DEBUG
125     (void) printf("me=%d, type=%d, node0=%d, fname=%x, fname=%.8s, len=%d\n",
126                   NODEID_(), *type, *node0, fname, fname, len);
127 #endif
128 
129     /* Strip trailing blanks off the file name */
130 
131     while ((len > 0) && (fname[len-1] == ' ')) {
132         len--;
133     }
134     if (len <= 0) {
135         Error("pfcopy_: file name length is toast", (long) len);
136     }
137 
138     /* Generate a NULL terminated string */
139 
140     filename = malloc( (unsigned) (len+1) );
141     if (filename) {
142         (void) bcopy(fname, filename, len);
143         filename[len] = '\0';
144     }
145     else {
146         Error("PFCOPY_: failed to malloc space for filename", (long) len);
147     }
148 
149     /* Now call the C routine to do the work */
150 
151     tcgi_pfilecopy(type, node0, filename);
152 
153     (void) free(filename);
154 }
155