1 /*
2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 %
4 % File:         PXK:UNIX-IO.C
5 % Description:  Unix PSL FileDescriptors are implemented as stdio streams
6 %                 ("FILE *".)
7 % Author:       Russell D. Fish
8 % Created:      Thu Feb 16 1984
9 % Modified:     17-Jul-84 22:49:12 (RAM)
10 % Mode:         Text
11 % Package:
12 % Status:       Open Source: BSD License
13 %
14 % (c) Copyright 1983, Hewlett-Packard Company, see the file
15 %            HP_disclaimer at the root of the PSL file tree
16 %
17 % (c) Copyright 1982, University of Utah
18 %
19 % Redistribution and use in source and binary forms, with or without
20 % modification, are permitted provided that the following conditions are met:
21 %
22 %    * Redistributions of source code must retain the relevant copyright
23 %      notice, this list of conditions and the following disclaimer.
24 %    * Redistributions in binary form must reproduce the above copyright
25 %      notice, this list of conditions and the following disclaimer in the
26 %      documentation and/or other materials provided with the distribution.
27 %
28 % THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
29 % AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
30 % THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
31 % PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNERS OR
32 % CONTRIBUTORS
33 % BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
34 % CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
35 % SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
36 % INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
37 % CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
38 % ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39 % POSSIBILITY OF SUCH DAMAGE.
40 %
41 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
42 %
43 % Revisions:
44 %
45 % 15-Sep-88 (T. Yamamoto and C. Burdorf)
46 %  Moved collect out of expand_file_name so it won't be overwritten as a
47 %  local before it is referenced.
48 % 20-Sep-86 (Leigh Stoller)
49 %  Removed assembler alias statements because they are not portable. Instead,
50 %  a sed script will be used to convert the _variables of C to VARIABLES of
51 %  PSL.
52 % 17-Jul-84 22:48:32 (RAM)
53 %  Added unixcd, a routine that calls expand_file_name before calling chdir.
54 % 3-Jul-84 10:45:57 (RAM)
55 %  Added expand_file_name (called from unixopen) to expand shell variable
56 %  references and ~ home directory syntax.
57 % 29-Jun-84 14:21:21 (RAM)
58 %  Added unixputs and unixopen.
59 % 21-May-84 17:41:41 (Vicki O'Day)
60 %  Added unixcleario.  It is called by syscleario.
61 %
62 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
63 */
64 
65 #include <stdio.h>
66 #include <stdlib.h>
67 #include <unistd.h>
68 
69 /* There is an assumption here that coercing addresses into ints is OK */
70 /*
71 asm("   alias   _unix_stdin,UNIXSTDIN");
72 asm("   alias   _unix_stdout,UNIXSTDOUT");
73 asm("   alias   _unix_stderr,UNIXSTDERR");
74 asm("   alias   _unix_null,UNIXNULL");
75 asm("   alias   _unix_eof,UNIXEOF");
76 asm("   alias   _unix_tty,UNIXTTY");
77 */
78 /* Initialize some PSL external variables with FileDescriptors for SysClearIO.
79  */
80 
81 extern FILE * unixstdin, * unixstdout, * unixstderr, * unixtty;
82 
83 /* Import NULL and EOF constants for error returns from stdio fns.
84  */
85 extern int unixnull[2], unixeof[2];
86 
87 /* Tag( unixinitio )
88  */
89 void
unixinitio()90 unixinitio()
91 {
92     unixstdin = stdin;
93     unixstdout = stdout;
94     unixstderr = stderr;
95     unixnull[0] = (long) NULL;
96     unixnull[1] = (long) NULL;
97     unixeof[0] = EOF;
98     unixeof[1] = EOF;
99     unixtty = fopen("/dev/tty", "r");
100 }
101 
102 /* Tag( unixputc )
103  * Used by kernel routines that write to the console
104  */
105 void
unixputc(c)106 unixputc(c)
107 char c;
108 {
109     fputc(c, stdout);
110 }
111 
112 /* Tag( unixputs )
113  */
114 void
unixputs(str)115 unixputs(str)
116 char *str;
117 {
118     fputs(str, stdout);
119 }
120 
121 /* Tag( unixputn )
122  */
123 void
unixputn(n)124 unixputn(n)
125 long long n;
126 {
127     fprintf(stdout, "%llx", n);
128 }
129 
130 /* Tag( unixcleario )
131  */
132 void
unixcleario()133 unixcleario()
134 {
135     unixinitio();
136 
137     /* set the stdin, stdout and stderr buffers to be empty */
138     fpurge(stdin);
139     fpurge(stdout);
140     fpurge(stderr);
141 
142 }
143 
144 /* The function expand_file_name is used to expand shell variable references
145    and ~ notation for directories in file names before calling fopen.
146    This eliminates the need for the HPUX-PATH and VAX-PATH kludges that were
147    once required, however, such a mechanism may still be used to override the
148    values supplied by the shell environment.  The file name is first copied
149    to a temporary copy because the parsing algorithm must write into the
150    string (this may change).  For now, the maximum string length supported
151    is 255 characters, but no checking is done to see if this is exceeded.
152    $ and ~ variables are expanded in one pass by calling the functions getenv,
153    getuid, getpwuid, and getpwnam.  If any expansion fails, the original
154    string is returned.
155 */
156 
157 #include <pwd.h>
158 struct passwd *getpwuid();
159 struct passwd *getpwnam();
160 char *getenv();
161 char collect[255], copy[255];  /* Made global so it won't be overwritten
162                   Used to be local to expand_file_name */
163 
164 /* Tag( expand_file_name )
165  */
expand_file_name(fname)166 char *expand_file_name(fname)
167 char *fname;
168 {
169   register char *c, *t, *e, *s, save;
170   struct passwd *p;
171   register int tilde;
172   c = copy;
173   s = fname;
174   while ((*c++ = *s++));
175   s = copy;
176   c = collect;
177   *c = '\0';
178   while (*s)
179     {
180       if ((tilde = (*s == '~')) || (*s == '$'))
181         {
182       for (e = ++s; (*e != '/' && *e != '\0' && *e != '$'); e++)
183         ;
184           t = 0;                        /* default initialization */
185           if (e == s)
186             {
187           if (tilde) t = ((getpwuid(getuid())) -> pw_dir);
188         }
189           else
190             {
191           save = *e;
192               *e = '\0';
193               if (tilde)
194                 {
195           if ((p = getpwnam(s)))  t = (p -> pw_dir);
196         }
197               else
198                 t = getenv(s);
199               *e = save;
200               s = e;
201             }
202           if (t)
203         while ((*c++ = *t++))
204           ;
205           else
206         return(fname);   /* name not found, just return original fname */
207           c--;
208         }
209     for (; (*s != '\0' && *s != '$'); *c++ = *s++)
210       ;
211       *c = '\0';
212   }
213   return (collect);
214 }
215 
216 extern int errno;
217 
unixopen(filename,type)218 FILE* unixopen(filename, type)
219      char *filename, *type;
220 {
221   FILE* fptr;
222 
223   fptr = fopen(expand_file_name(filename), type);
224   return(fptr);
225 }
226 
227 void
unixcd(filename)228 unixcd(filename)
229      char *filename;
230 {
231   chdir(expand_file_name(filename));
232 }
233 
234 int
unixfclose(ix)235 unixfclose (ix)
236 FILE* ix;
237 
238 { return fclose (ix); }
239 
240 int
external_system(command)241 external_system(command)
242      char *command;
243 {
244   int value;
245   value = system(command);
246   return(value);
247 }
248 
249 /* Tag( external_exit )
250  */
251 int
external_exit(status)252 external_exit(status)
253      int status;
254 {
255   exit(status);
256 }
257 
258 char *static_argv[20];  /* static place to hold argv so it doesn't get gc'd */
259 
260 char **
copy_argv(argc,argv)261 copy_argv(argc,argv)    /* copy argv into static space. */
262 int argc;
263 char *argv[];
264 {
265   int i;
266 
267   for (i=0; i < argc; i++)
268      static_argv[i]=argv[i];
269 
270   return(static_argv);
271 }
272 
273 /* convert a pathname to canonical form */
274 char *
external_fullpath(relpath)275 external_fullpath(relpath)
276      char * relpath;
277 {
278   return realpath(relpath,NULL);
279 }
280 
xgetw(f)281 long long xgetw (f)
282 FILE* f;
283 { long long a1,a2;
284 
285   a1 = (long long) getw(f);
286   a2 = (long long) getw(f);
287   return (a2 << 32 | a1);
288 }
289 
290 
291