/* @(#)osh.c 17.1.1.1 (ES0-DMD) 01/25/02 17:35:08 */ /*=========================================================================== 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 Massachusetss Ave, Cambridge, MA 02139, USA. Corresponding 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 osh .LANGUAGE C .AUTHOR IPG-ESO Garching .CATEGORY Host operating system interfaces. Host services. .COMMENTS Provide miscellaneous host services. The routines return time and date stamps, return cpu time used by the current process, translates host error codes and executes host commands. Time resolution is host dependent parameter. The routines return always a non-negative integer number on successful return. Otherwise, a value of -1 is set to indicate an error condition and the variable ``oserror'' contains the symbolic error code. Symbolic error codes for each function to be defined. .VERSION 0.0 25-Aug-1986 Definition. J. D. Ponz .VERSION 1.0 28-Oct-1986 Programmation. B. Pirenne .VERSION 1.1 15-Mar-1987 Add oshela. B. Pirenne .VERSION 1.5 14-Apr-1987 bsd-sysv compatible. B. Pirenne .VERSION 1.6 15-Jul-1987 oshcpu returns a real number; date through a structure. B. Pirenne .VERSION 1.7 10-Dec-1987 Cosmetic changes I. Suisalu .VERSION 1.8 05-Oct-1988 Time edition simplifications. F. Ochsenbein .VERSION 1.9 01-Aug-1990 oshcmd takes care of buffer overflow. F. O. .VERSION 2.0 07-Aug-1990 Added oshtm oshtl (conversion long to structure) FO .VERSION 2.1 910911 Using memcpy() instead of bcopy(). CG .VERSION 2.2 950502 Adding oshmidvers. CG. ------------------------------------------------------------*/ /* * Define _POSIX_SOURCE to indicate * that this is a POSIX program */ #define _POSIX_SOURCE 1 #include /* MIDVERS & patchlevel values */ #include /* ANSI-C prototyping */ #include #include #include #include #include #include #include #include #ifndef CLK_TCK #define CLK_TCK 50 #endif int oshcpu(op, ctime) /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE Gets CPU time. Precision is : hundreds of seconds. Cpu time returned is the sum of the time spend for both system tasks and process itself needed for the completion of the task. The cpu time is expressed in seconds, in a floating point format. .RETURNS Value 0 on normal return. value -1 if the operation to do is unknown or if the get operation was not preceded by an initialization. .REMARKS System dependencies: --UNIX: times(3c) ------------------------------------------------------------*/ int op; /* IN : operation to execute : INIT_CPU_CLOCK \ to initialize timer, GET_CPU_CLOCK to get the time. */ float *ctime; /* OUT: ctime is the cpu time passed since the init. op.; */ { struct tms buffer; /* buffer to receive time accounting information */ static time_t firstime=0L; time_t lastime; switch (op) { case INIT_CPU_CLOCK : /**** Initialize timer */ if(times(&buffer) == -1L) { oserror = errno; return(-1); } firstime = buffer.tms_utime + buffer.tms_stime + buffer.tms_cutime + buffer.tms_cstime; *ctime = 0.; break; case GET_CPU_CLOCK : /**** get time */ if(!(int)firstime){ oserror=EINVAL; return(-1); } if(times(&buffer) == -1L) { oserror = errno; return(-1); } lastime = buffer.tms_utime + buffer.tms_stime + buffer.tms_cutime + buffer.tms_cstime - firstime; /* ** conversion of the time from 1/HZ s. to sec. */ *ctime = (float)lastime / CLK_TCK; break; default : /**** Operation code error */ oserror = EINVAL; return(-1); } return (0); } long oshtime() /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE Gets CURRENT time. Precision is : 1 seconds. .RETURNS Time (normally as seconds elapsed since Jan. 1, 1970) .REMARKS ------------------------------------------------------------*/ { return((long) time((time_t *)0)); } struct tm *oshtm(clock) /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE Convert time from long to structure .RETURNS Address of a filled tm structure (see time.h) ------------------------------------------------------------*/ long clock; /* IN: Time in seconds since Jan. 1, 1970 */ { static time_t aclock; aclock = clock; return(gmtime(&aclock)); } #define Jan1_1970 135140L /* Date in 400-yr cycle */ #define Jan1_1980 138792L /* Date in 400-yr cycle */ #define Jan1_2000 0L /* Date in 400-yr cycle */ long oshtl(T) /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE Convert time structure into seconds since Jan. 1, 1970 .RETURNS The time in seconds. .REMARKS Computation is done here, system call seems to be non-existent... ------------------------------------------------------------*/ struct tm *T; /* IN: Time structure to convert */ { register long int j, y, t; /* Compute Day of 400 yr cycle */ y = T->tm_year; if (y < 1000) y += 1900; y %= 400; y += 400; /* To be sure j is positive */ j = y - (11 - T->tm_mon)/10; t = ((1461L*j)/4 + (306L * ((T->tm_mon+10)%12) + 5)/10 - (3* ((j + 100L)/100L))/4 + T->tm_mday + 59L) % 146097L; /* Compute Week day */ T->tm_wday = (t+6L)%7L; t -= Jan1_1970; /* Origin = Jan 1, 1970 */ if (t < -24855) t += 146097L; if (t > 24855) t -= 146097L; /* Transform Day into seconds */ if (t < -24855) t = -24855; if (t > 24855) t = 24855; t = t * 86400L + T->tm_hour * 3600L + T->tm_min * 60L + T->tm_sec; return(t); } int oshdate(date_string, date_struct) /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE Gets date and time stamp. No special structure adopted. .RETURNS A pointer to the time structure is defined in (system) {\begin{TeX} \begin{itemize} \item int tm_year number \item int tm_mon number [0-11] \item int tm_mday [1-31] \item int tm_yday [0-355] \item int tm_wday [0-6] (Sunday = 0) \item int tm_hour [0-23] \item int tm_min [0-59] \item int tm_sec [0-59]. \item int tm_saving \end{itemize} \end{TeX}} .REMARKS System dependencies: --UNIX: time(2) ------------------------------------------------------------*/ char date_string[28]; /* OUT : date-time stamp */ struct tm *date_struct; /* OUT : date-time structure (see description) */ { struct tm *dt; time_t curseconds; int i, m; static char template[]="WW, DD MMM YYYY hh:mm:ss"; static char Day_list[]= "SuMoTuWeThFrSa"; static char Month_list[] = "JanFebMarAprMayJunJulAugSepOctNovDec"; /* ** get current time in seconds since 1/1/1970 */ if((curseconds = time((time_t *)0)) < 0) { oserror = errno; return(-1); } /* ** fill in the structure with date information */ dt = localtime(&curseconds); if (dt->tm_year < 1900) dt->tm_year += 1900; memcpy((char *)date_struct,(char *)dt,sizeof(struct tm)); /* ** now create a string with time and date according ** to the above picture */ for (i = 2*dt->tm_wday, m=0; m <= 1; m++) template[m] = Day_list[i++]; for (i = dt->tm_mday, m=5; m>=4; m--, i/=10) template[m] = '0'+i%10; for (i = 3*dt->tm_mon, m = 7; m <= 9; m++) template[m] = Month_list[i++]; for (i = dt->tm_year, m = 14; m >= 11; m--, i/=10) template[m] = '0' + i%10; for (i = dt->tm_hour, m = 19; m >= 18; m--, i/=10) template[m] = '0' + i%10; for (i = dt->tm_min, m = 22; m >= 21; m--, i/=10) template[m] = '0' + i%10; for (i = dt->tm_sec, m = 25; m >= 24; m--, i/=10) template[m] = '0' + i%10; /* ** now copy template to date_string */ for (m=0; m < sizeof(template); m++) date_string[m] = template[m]; return(0); } extern char *sys_errlist[]; extern int sys_nerr; int oshmsg(code, message) /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE Gets system error message. .RETURNS Value 0 on normal return, -1 if the error code does not exist. .REMARKS System dependencies: --UNIX: sys_errlist[] ------------------------------------------------------------*/ int code; /* IN : system error code */ char *message; /* OUT : system error message */ { if (code < 0 || code >= sys_nerr) { oserror = EINVAL; return(-1); } strcpy(message,sys_errlist[code]); return(0); } int oshcmd(command, input, output, error) /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE Executes system command(maybe with arguments). The routine defines also the pathnames for standard input, output and error units. Enviroment variable SHELL must be defined. .RETURNS Value 0 on normal return. The status of the execution of the command in the other cases. .REMARKS System dependencies: --UNIX: system(3S) ------------------------------------------------------------*/ char *command; /* IN : system command */ char *input; /* IN : standard input stream */ char *output; /* IN : standard output stream */ char *error; /* IN : error output stream */ { char buffer[256]; char *p; #define strappend(s) strncpy(p,s,buffer+sizeof(buffer)-(p+1)), p += strlen(p) strncpy(buffer,command,sizeof(buffer)-1); buffer[sizeof(buffer)-1] = '\0'; p = buffer + strlen(buffer); if(input != NULL) if (*input) { strappend(" <"); strappend(input); } if(output != NULL) if (*output) { strappend(" >"); strappend(output); } if(error != NULL) if (*error) { strappend(" 2>"); strappend(error); } return(system(buffer)); } #define MAX_CURRENT_WORKING_DIR 128 static char current_working_dir[MAX_CURRENT_WORKING_DIR]; int oshgetcwd(path) /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE Return current working directory. .RETURNS Value 0 on normal return. -1 on failure and oserror set. .REMARKS System dependencies: --UNIX: getcwd(3) ------------------------------------------------------------*/ char **path; { if (getcwd(current_working_dir,(size_t)MAX_CURRENT_WORKING_DIR) == NULL) { oserror = errno; return(-1); } else { *path = current_working_dir; return(0); } } int oshchdir(path) /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE Change current working directory. .RETURNS Value 0 on normal return. -1 on failure and oserror set. .REMARKS System dependencies: --UNIX: chdir(3) ------------------------------------------------------------*/ char *path; { if (chdir(path) == -1) { oserror = errno; return(-1); } else return(0); } char *oshmidvers() /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE Get MIDVERS string (located in patchlevel.h). .RETURNS Pointer to static variable MIDVERS -------------------------------------------------------------------- */ { return(MIDVERS); }