! subroutine putms(mspath,dskfile,tmpdir,lnkfile,wrpass,msscomment) #ifdef MPI use mpi_module,only: mytid #endif implicit none ! ! Called by sub savefile (output.f): ! call putms(outpath,diskfile,tempdir,' ','NCARTGCM',' ') c c Dispose existing disk file dskfile to mss as mspath, with optional c write password. Also save a link of the file in tmpdir. c (if mspath arg is all blanks, do not do the mswrite, i.e., only c save link to tmpdir) c c On input: c character mspath is full mss path and file name to which dskfile c is to be disposed c character dskfile is existing disk file in cwd c character tmpdir is directory in which to save a link to dskfile c character wrpass, if non-zero length, is write password for mspath c On output: c dskfile has been disposed to mspath, optionally with write password c A link to dskfile has been saved in tmpdir c c Notes: c Non-existence of dskfile is a fatal error. c Ishell is used only if tmpdir has to be created; all other commands c are via fortran calls. c Files are disposed with retention period of 367 days. c If wrpass has non-zero length, then it is given as a write password c on the mss file. If wrpass length > 8, only the first 8 chars c are used (this is an mswrite restriction). c By default, the file is disposed to mss in transparent format c If mspath already exists on the mss, it will be overwritten, c provided the write password given (wrpass(1:8)) is correct. c Errors in links or mswrite results in warning message, but is c non-fatal. c If tmpdir does not exist, it is created with global permissions c prior to linking. c c B. Foster 2/95 ! ! Args: character(len=*),intent(in) :: | mspath,dskfile,tmpdir,lnkfile,wrpass character(len=*),intent(in) :: msscomment ! ! Local: integer,parameter :: mxfilelen = 240 ! maximum number chars in file name logical exists character(len=80) :: errmsg character(len=96) :: opts character(len=mxfilelen) :: tmpfile,cmd character*10 wpass integer :: lmspath,ldskfile,ltmpdir,llnkfile,ltmpfile, | lwrpass,lcomment,ier,istat ! ! External: integer,external :: ilink,iunlink,isystem #ifdef MPI ! ! If an MPI job, only master task should execute this routine, and ! slave tasks must wait. Mytid is use-associated from the mpi module. ! include "mpif.h" ! for barrier call at end of routine if (mytid /= 0) goto 100 write(6,"('putms: MPI master task: mspath = ',a)") trim(mspath) #endif c c If any of first 3 arguments have zero length, stop with error msg: c write(6,"(' ',/72('-'),/'PUTMS:')") lmspath = len_trim(mspath) ldskfile = len_trim(dskfile) ltmpdir = len_trim(tmpdir) if (ldskfile.le.0) then write(6,"('>>> Bad dskfile=',a)") dskfile write(6,"(72('-'),/)") stop 'putms' endif if (ltmpdir.le.0) then write(6,"('>>> Bad tmpdir=',a)") tmpdir write(6,"(72('-'),/)") stop 'putms' endif c c If dskfile does not exist, stop with fatal error message: c inquire(file=dskfile,exist=exists) if (.not.exists) then write(6,"('>>> Cannot find file ',a)") dskfile(1:ldskfile) write(6,"(72('-'),/)") stop 'putms' endif c c Construct full tmp path with file name (tmpfile = tmpdir/dskfile, if c lnkfile is zero-length, tmpdir/lnkfile otherwise): c (tmpfile may be up to mxfilelen characters long) c llnkfile = len_trim(lnkfile) if (llnkfile.gt.0) then if (ltmpdir+llnkfile+1.gt.mxfilelen) then write(6,"('>>> WARNING: lengths of tmpdir+lnkfile too ', + 'long (sum must be <= ',i4,'): ltmpdir=',i3,' llnkfile=', + i3)") mxfilelen,ltmpdir,llnkfile endif write(tmpfile,"(a,'/',a)") tmpdir(1:ltmpdir),lnkfile(1:llnkfile) else if (ltmpdir+ldskfile+1.gt.mxfilelen) then write(6,"('>>> WARNING: lengths of tmpdir+dskfile too ', + 'long (sum must be <= ',i4,'): ltmpdir=',i3,' ldskfile=', + i3)") mxfilelen,ltmpdir,ldskfile endif write(tmpfile,"(a,'/',a)") tmpdir(1:ltmpdir),dskfile(1:ldskfile) endif ltmpfile = len_trim(tmpfile) c c If tmpdir does not exist, create it with global permissions: c inquire(file=tmpdir,exist=exists) if (.not.exists) then cmd = ' ' write(cmd,"('mkdir -m 777 ',a)") tmpdir(1:ltmpdir) ! ! isystem is local (util.F), and uses platform dependent escape ! functions to the shell (for AIX, isystem adds null-termination ! to the command string). ! istat = isystem(cmd(1:len_trim(cmd))) if (istat.eq.0) then write(6,"('Created ',a,' with global permissions')") + tmpdir(1:ltmpdir) else write(6,"('>>> WARNING: error creating tmpdir',a, + ' istat=',i3)") tmpdir(1:ltmpdir) endif endif c c Dispose dskfile to mspath: c if (lmspath.gt.0) then lwrpass = len_trim(wrpass) lcomment = len_trim(msscomment) opts = ' ' if (lcomment.gt.0) + write(opts,"('CMNT=',a)") msscomment(1:lcomment) if (lwrpass.gt.8) then write(6,"('>>> WARNING: only first 8-chars of wrpass ', + 'will be used',/' Write password will be: ',a)") + wrpass(1:8) endif #if defined(UNICOS) || defined(IRIX) || defined(OSF1) || defined(AIX) #ifdef MSS if (lwrpass.le.0) then call mswrite(ier,dskfile(1:ldskfile),mspath(1:lmspath), + ' ',367,opts) else write(wpass,"(' ,',a)") wrpass(1:8) call mswrite(ier,dskfile(1:ldskfile),mspath(1:lmspath), + wpass,367,opts) endif if (ier.eq.0) then write(6,"('Disposed file ',a,' to mss ',a)") + trim(dskfile),trim(mspath) if (lcomment.gt.0) + write(6,"('mss comment: ',a)") msscomment(1:lcomment) else call mserror(errmsg) write(6,"('>>> WARNING: error from mswrite of disk file ', + a,' to mspath ',a)") dskfile(1:ldskfile),mspath(1:lmspath) if (lwrpass.gt.0) write(6,"(' Write password = ',a)") + wrpass(1:8) write(6,"(' Error message: ',a)") errmsg endif ! error return from mswrite #endif #else ! ! 2/00: mswrite appears to be on most machines -- if OS is ! unresolved, try msrcp: ! write(6,"('>>> WARNING putms: unresolved OS cpp directive', | ' -- will try msrcp system call.')") cmd = ' ' cmd = "msrcp "//dskfile(1:ldskfile)//" mss:"//trim(mspath) write(6,"('Executing isystem call on AIX: cmd=',/,a)") | trim(cmd) istat = isystem(cmd) ! cmd is null-terminated by isystem for aix write(6,"('After system call on AIX: istat=',i3)") istat #endif endif ! lmspath > 0 c c Save a link to tmpdir (first remove any pre-existing tmpfile): c istat = iunlink(tmpfile,0) istat = ilink(dskfile,tmpfile,1) if (lmspath.le.0) write(6,"('(File NOT disposed to mss)')") write(6,"(72('-'),/)") #ifdef MPI ! ! If mpi job, slave tasks jump down here and wait for master proc: 100 continue call mpi_barrier(MPI_COMM_WORLD,ier) if (mytid==0) then write(6,"('putms MPI: master passed barrier after ', | ' acquiring mspath ',a)") trim(mspath) else write(6,"('putms MPI: task ',i2,' passed barrier...')") mytid endif #endif return end