/* @(#)osf.c 17.1.1.1 (ESO-DMD) 01/25/02 17:35:07 */ /*=========================================================================== Copyright (C) 1995 European Southern Observatory (ESO) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. Correspondence concerning ESO-MIDAS should be addressed as follows: Internet e-mail: midas@eso.org Postal address: European Southern Observatory Data Management Division Karl-Schwarzschild-Strasse 2 D 85748 Garching bei Muenchen GERMANY ===========================================================================*/ /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .TYPE Module .NAME osf .LANGUAGE C .AUTHOR IPG-ESO Garching .CATEGORY Host operating system interfaces. File management. .COMMENTS File management. These routines provide miscellaneous operations on files and directories. The routines use the physical file name to access files. The routines return a non-negative integer on successful return. Otherwise, a value of -1 is set to indicate an error condition and the variable ``oserror'' contains the system error code. Each file has a host independent logical filename to be handled by the portable directory mechanism. Associated to each file there is a status structure with the owner, protection flags and dates of creation and modification. .VERSION 0.0 25-Aug-1986 Definition J. D. Ponz .VERSION 1.3 21-Apr-1987 osfcreate : -> still better performance B. P. .VERSION 1.4 08-May-1987 osfphname : -> use getenv(3) B. P. .VERSION 1.7 27-Nov-1990 Corrected osfcreate when 0 bytes asked .VERSION 1.8 30-Jan-1991 Added osfmkdir (Create New Directory) .VERSION 2.0 19-Feb-1992 osfinfo uses another filestatus structure. CG. .VERSION 2.1 29-May-1992 osfcreate set default mask when mode is 0. .VERSION 2.2 13-Jul-1992 blocksize removed. SCO/PC does not support it. CG. 010912 last modif -----------------------------------------------------------*/ #include /* ANSI-C prototyping */ #include #include /* Function definitions */ #include #include #include #include #include #include #include #define OSFMASK 0666 /* This value is also restricted by umask() */ long osfcreate(phname, nobyt, mode) /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE Creates a new file or rewrites an existing one (no version number ). Access is done by physical file name. Owner and group identifications of the process creating the file define the owner and group identification of the file. The argument mode gives the file protection code. .RETURNS The actual number of bytes allocated; on error -1L and the system error code is set. .REMARKS System dependencies: --UNIX: creat(2),write(2),close(2),lseek(2) ------------------------------------------------------------*/ char *phname; /* IN : physical filename */ long nobyt; /* IN : number of bytes to be allocated */ int mode; /* IN : file mode */ { int fid; long ret; #ifdef __FreeBSD__ off_t lseek(); #else long lseek(); #endif char c = ' '; if((fid = creat(phname,(mode ? mode:OSFMASK) )) < 0) { /* create the file */ oserror = errno; return(-1); } ret = 0; /* Default returned value */ if (nobyt > 0) { /* Position on last byte of the file */ if((ret = lseek(fid,nobyt - 1,FILE_START)) == -1L) { oserror = errno; return(-1L); } if(write(fid,&c,1) != 1) { /* Write last byte */ oserror = errno; close(fid); return(-1L); } ret++; } if(close(fid) < 0) { /* close file */ oserror = errno; return(-1L); } return(ret); /* return number of bytes */ } int osfdelete(phname) /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE Deletes file on disk by removing the directory entry corresponding to the physical name. The file has to be closed. .RETURNS Value 0 on normal return, -1 on error and oserror is set. .REMARKS System dependencies: --UNIX: unlink(2) ------------------------------------------------------------*/ char *phname; /* IN : physical filename */ { if (unlink(phname) < 0) { oserror = errno; return(-1); } return(0); } int osfcontrol(phname, function, value1, value2) /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE Change file protection and/or owner. Access to the file is by physical name. The argument function defines the operation to be done, value1 is the protection code or the owner code and value2 is free or the actual group identification. .RETURNS Value 0 on normal return, -1 on error (oserror is set). .REMARKS System dependencies: --UNIX: chmod(2), chown(2) ------------------------------------------------------------*/ char *phname; /* IN : physical filename */ int function; /* IN : function code */ int value1; /* IN : protection or owner code */ int value2; /* IN : 0 or group code */ { switch (function) { case CHMOD: /* change file protection */ if(chmod(phname, value1) < 0) { oserror = errno; return(-1); } break; case CHOWN: /* change owner and group of the file */ if(chown(phname, value1, value2) < 0) { oserror = errno; return(-1); } break; default: oserror = EINVAL; return(-1); } return(0); } int osfinfo(phname, status) /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE Get file status information. Access to the file is by physical name. .RETURNS Value 0 on normal return, -1 on error (check oserror). .REMARKS System dependencies: --UNIX: stat(2) ------------------------------------------------------------*/ char *phname; /* IN : physical filename */ struct filestatus *status; /* OUT : output file status */ { struct stat buf; /* ** get file status and return it to the structure ``filestatus'' */ if (stat(phname,&buf) == -1) { oserror = errno; return(-1); } /* ** transfer values obtained to structure ``filestatus'' */ status->filesize = buf.st_size; status->owner = buf.st_uid; status->date = buf.st_mtime; status->protection = buf.st_mode; return(0); } int osfmkdir(phname) /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE Create a new directory .RETURNS Value 0 on normal return, -1 on error (check oserror). .REMARKS Use system with mkdir ------------------------------------------------------------*/ char *phname; /* IN : physical directory name */ { char *cmd; cmd = malloc(8 + strlen(phname)); strcpy(cmd, "mkdir "); strcat(cmd, phname); oserror = system(cmd); free(cmd); return(oserror ? -1 : 0); } int osfrename(oldname, newname) /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE Renames a disk file by giving old and new physical names. .RETURNS Value 0 on normal return, -1 on error (check oserror). .REMARKS System dependencies: --UNIX: link(2), unlink(2) ------------------------------------------------------------*/ char *oldname; /* IN : old physical filename */ char *newname; /* IN : new physical filename */ { unlink(newname); /* remove newname if exist */ if (link(oldname, newname) < 0) { char *cmd; cmd = malloc(8 + strlen(oldname) + strlen(newname)); strcpy(cmd, "mv -f "); strcat(cmd, oldname); strcat(cmd, " "); strcat(cmd, newname); oserror = system(cmd); free(cmd); return(oserror ? -1 : 0); } if(unlink(oldname) < 0) { oserror=errno; return(-1); } return(0); } int osftranslate(logname, phname) /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE Translate logical names into physical names. i.e. $KEYS ==> myfile.key .METHOD Searches the system variable list for the logname. .RETURNS length of physical name on normal return, -1 when logname does not exist (phname empty). .REMARKS System dependencies: --UNIX: getenv(3). ------------------------------------------------------------*/ char *logname; /* IN : logical name */ char *phname; /* OUT: translated physical filename */ { register int nr; char *getenv(); register char *t, *ptr, cc; /* Do the logical translation */ if ((t = getenv(logname)) == NULL) { *phname = '\0'; return(-1); } ptr = phname; for (nr=0; ; nr++) /* copy phys. filename */ { cc = *t++; if (cc == '\0') { *ptr = '\0'; return (nr); } *ptr++ = cc; } } int osfphname(logname, phname) /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE Translate logical names into physical names. i.e. $KEYS ==> myfile.key .METHOD Searches the system variable list for the logname. .RETURNS Value 0 on normal return, -1 when logname does not exist (phname empty). .REMARKS System dependencies: --UNIX: getenv(3). ------------------------------------------------------------*/ char *logname; /* IN : logical name */ char *phname; /* OUT: translated physical filename */ { char *getenv(); register char *t1; /* ** Do the logical translation */ if ((t1 = getenv(logname)) == NULL){ *phname = '\0'; return(-1); } strcpy(phname,t1); return(0); } int osflgname(phname, logname) /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE Physical into logical filename translation. The logical filename is a structure consisting of three character strings to define the logical path (node, device and directory), the logical name of the file and the type of file. .RETURNS Value 0 on normal return, -1 if structure limits are too small. .REMARKS System dependencies: --UNIX: none ------------------------------------------------------------*/ char *phname; /* IN : input physical filename */ struct lname *logname; /* OUT: translated logical name */ { char *locph, *sep; int len; #ifdef NO_STRCHR /* Some pure BSD systems */ #define strrchr rindex #endif #ifndef strrchr /* On IBM6000 strchr() is a macro */ extern char *strrchr(); #endif locph=phname; /* ** Look for the last occurrence of the separator "/". From the ** the beginning of the physical name till this separator ** is the logical path name. */ if((sep=strrchr(locph,'/'))!=NULL) { if((len=sep-locph)>_LPLEN) { oserror = EINVAL; return(-1); } strncpy(logname->lpath,locph,len); locph += len+1; } /* ** Look for the last occurrence of the separator ".". From this ** separator till the end of the physical name ** is the file type. */ if((sep=strrchr(locph,'.'))!=NULL) { if((len=strlen(sep+1))>_LTLEN) { oserror = EINVAL; return(-1); } strncpy(logname->ltype,sep+1,len); *sep = '\0'; } /* ** Between both separators "/" and "." ** is the logical file name. */ if((len=strlen(locph))>_LFLEN) { oserror = EINVAL; return(-1); } strncpy(logname->lfile,locph,len); return(0); }