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