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