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