/* * f o p n x n */ /*)LIBRARY */ #ifdef DOCUMENTATION Title fopnxn Open a file on another node (using RFA) Index fopnxn Open a file on another node (using RFA) synopsis .s.nf NFILE * fopnxn(name, mode, inisiz, recsiz); char *name; /* File to open */ char *mode; /* Open modes */ int inisiz; /* initial size of file */ int recsiz; /* record size for random access files */ .s.f Description Fopnxn() provides the services of fopenx() across DECnet. The usage is the same as fopenx(), with some exceptions: .s.list .le ;The file name must include a node name and uic. .le ;The file pointer returned can only be used with rgetb(), rputb() and rclose(). .le ;The remote node must have DECnet object 128 defined as the cooresponding RFA (remote file access) task. .le ;On error, both $$ferr and $$nerr should be checked. .els.s See the description of fopenx() for more details on the other arguments. Returns NULL on error. $$ferr is set to IE.BAD if the node name or uic are omitted. Actual file errors retuen the FCS error code in $$ferr with the network error code, $$nerr = 1. Network errors will set $$nerr, with the value of $$ferr unpredicatable. The NFILE structure created when a file is successfully openned contains some of the FDB information from the remote file. See stdnet.h for details. Implementation Details Fopnxn() does not set a default uic and device, so they must be specified. It is also safer since the remote system may not have the same device or uic. The RFA object on the remote node does the actual file open or create. On successfull completion of the call, the remote RFA task will have the file open. .s Don't use fopnxn on non-disk devices, the results are unpredicatable. .s Note that "no buffer space available" (IE.NBF or E$$NSP) and "invalid lun" (IE.ILU or E$$NOC) may be generated by fopenx() on the remote side and returned. .s The NFILE pointer returned will only work with rgetb(), rputb() and rclose(). Using is with regular C IO functions will crash the task. .s Access mode checks are done in this function before the network code is called. Bugs Only works with RSX FCS. You need to known what your doing. #endif #include #include #include #define IE_BAD -1 /* bad parameter ferr value */ extern int $$ferr; NFILE * fopnxn(fnam, mode, inisiz, recsiz) char *fnam; char *mode; int inisiz; /* initial size of file */ int recsiz; /* record size for fixed length file */ { char *nodep; /* remote node name */ char *filp; /* pointer to filename less node name */ char filspc[40]; /* private copy of file spec */ char *chk_fnam(); if (scan(mode) == NULL) { /* check option args */ $$ferr = IE_BAD; /* report bad args */ return(NULL); } strcpy(filspc, fnam); /* get private copy of file spec */ nodep = filspc; /* set pointers */ if (!(filp = chk_fnam(filspc))) return(NULL); return(rmt_opn(nodep, filp, mode, inisiz, recsiz)); } char *chk_fnam(fspc) /* find and check file spec */ char *fspc; { char *fp; /* beginning of file name string */ char *cp; $$ferr = IE_BAD; /* assume bad args */ /* check for :: separating node name and file name */ if ((fp = strchr(fspc, ':')) == NULL) return(NULL); *fp++ = NULL; /* terminate node name string */ if (*fp++ != ':') return(NULL); /* double :: req. for node nm */ /* check if uic was specified */ if ((cp = strchr(fp, '[')) == NULL) { $$ferr = -52; /* IE.BDI - bad directory syntax */ return(NULL); } $$ferr = IS_SUC; return(fp); } static int scan(modep) /* scan option string */ char *modep; /* options passed by caller */ { char *p; int af; /* access count flag, must be 1 */ af = 0; for (p = modep; *p != NULL; p++) { switch (*p) { case 'r': case 'a': case 'm': case 'w': af++; continue; case 'n': /* legal options */ case 'u': case 'p': case 's': case 'x': case 'l': continue; default: return(NULL); } } /* end options string scan */ if (af == 1) return(1); /* only one access mode allowed */ else return(NULL); }