1 /*
2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 %
4 % File:         PXCC: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:       Experimental (Do Not Distribute)
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 
67 /* There is an assumption here that coercing addresses into ints is OK */
68 /*
69 asm("   alias   _unix_stdin,UNIXSTDIN");
70 asm("   alias   _unix_stdout,UNIXSTDOUT");
71 asm("   alias   _unix_stderr,UNIXSTDERR");
72 asm("   alias   _unix_null,UNIXNULL");
73 asm("   alias   _unix_eof,UNIXEOF");
74 asm("   alias   _unix_tty,UNIXTTY");
75 */
76 /* Initialize some PSL external variables with FileDescriptors for SysClearIO.
77  */
78 extern FILE * unix_stdin, * unix_stdout, * unix_stderr, * unix_tty;
79 
80 /* Import NULL and EOF constants for error returns from stdio fns.
81  */
82 extern int unix_null, unix_eof;
83 
84 /* Tag( unixinitio )
85  */
unixinitio()86 unixinitio()
87 {
88     unix_stdin = stdin;
89     unix_stdout = stdout;
90     unix_stderr = stderr;
91     unix_null = (long)NULL;
92     unix_eof = EOF;
93     unix_tty = fopen("/dev/tty", "r");
94 }
95 
96 /* Tag( unixputc )
97  * Used by kernel routines that write to the console
98  */
unixputc(c)99 unixputc(c)
100 char c;
101 {
102     fputc(c, stdout);
103 }
104 
105 /* Tag( unixputs )
106  */
unixputs(str)107 unixputs(str)
108 char *str;
109 {
110     fputs(str, stdout);
111 }
112 
113 /* Tag( unixputn )
114  */
unixputn(n)115 unixputn(n)
116 int n;
117 {
118     fprintf(stdout, "%x", n);
119 }
120 
121 /* Tag( unixcleario )
122  */
unixcleario()123 unixcleario()
124 {
125     unixinitio();
126 
127 #ifndef LINUX
128     /* set the stdin, stdout and stderr buffers to be empty */
129     stdin->_cnt = 0;
130     stdin->_ptr = stdin->_base;
131     stdout->_cnt = 0;
132     stdout->_ptr = stdout->_base;
133     stderr->_cnt = 0;
134     stderr->_ptr = stderr->_base;
135 #endif
136 
137 }
138 
139 /* The function expand_file_name is used to expand shell variable references
140    and ~ notation for directories in file names before calling fopen.
141    This eliminates the need for the HPUX-PATH and VAX-PATH kludges that were
142    once required, however, such a mechanism may still be used to override the
143    values supplied by the shell environment.  The file name is first copied
144    to a temporary copy because the parsing algorithm must write into the
145    string (this may change).  For now, the maximum string length supported
146    is 255 characters, but no checking is done to see if this is exceeded.
147    $ and ~ variables are expanded in one pass by calling the functions getenv,
148    getuid, getpwuid, and getpwnam.  If any expansion fails, the original
149    string is returned.
150 */
151 
152 #include <pwd.h>
153 struct passwd *getpwuid();
154 struct passwd *getpwnam();
155 char *getenv();
156 char collect[255], copy[255];  /* Made global so it won't be overwritten
157                   Used to be local to expand_file_name */
158 
159 /* Tag( expand_file_name )
160  */
expand_file_name(fname)161 char *expand_file_name(fname)
162 char *fname;
163 {
164   register char *c, *t, *e, *s, save;
165   struct passwd *p;
166   register int tilde;
167   c = copy;
168   s = fname;
169   while (*c++ = *s++);
170   s = copy;
171   c = collect;
172   *c = '\0';
173   while (*s)
174     {
175       if ((tilde = (*s == '~')) || (*s == '$'))
176         {
177       for (e = ++s; (*e != '/' && *e != '\0' && *e != '$'); e++)
178         ;
179           t = 0;                        /* default initialization */
180           if (e == s)
181             {
182           if (tilde) t = ((getpwuid(getuid())) -> pw_dir);
183         }
184           else
185             {
186           save = *e;
187               *e = '\0';
188               if (tilde)
189                 {
190           if (p = getpwnam(s))  t = (p -> pw_dir);
191         }
192               else
193                 t = getenv(s);
194               *e = save;
195               s = e;
196             }
197           if (t)
198         while (*c++ = *t++)
199           ;
200           else
201         return(fname);   /* name not found, just return original fname */
202           c--;
203         }
204     for (; (*s != '\0' && *s != '$'); *c++ = *s++)
205       ;
206       *c = '\0';
207   }
208   return (collect);
209 }
210 
211 extern int errno;
212 
213 
unixopen(filename,type)214 unixopen(filename, type)
215      char *filename, *type;
216 {
217   int fptr;
218 
219   fptr = (int) fopen(expand_file_name(filename), type);
220   return(fptr);
221 }
222 
223 
224 #if 0
225 unixopen(filename, type)
226      char *filename, *type;
227 {
228   int fptr;
229 
230   /*  printf("open %s %s ",filename,type);    */
231   fptr = (int) fopen(expand_file_name(filename), type);
232   if(fptr==(int)NULL)
233   { /* try file name in dos syntax */
234     char c,nfname[255];
235     int i,j,k,kmax;
236     /*  printf("open failed %s %s ",filename,type); */
237     k=0;kmax=8;j=0;
238     for(i=0;filename[i];i++)
239     { c=filename[i]; nfname[j++]=c; k++;
240       if(c == '\\')     {k=0; kmax=8;}
241       else if(c == '.') {k=0; kmax=3;}
242       else if(k > kmax) j--;
243     };
244     nfname[j]='\0';
245     /*   printf(" reformatted  %s  ",nfname); */
246     fptr = (int) fopen(expand_file_name(nfname), type);
247     /*   printf(" --> %x\n",fptr);  */
248   };
249   return(fptr);
250 }
251 #endif
252 
unixcd(filename)253 unixcd(filename)
254      char *filename;
255 {
256   chdir(expand_file_name(filename));
257 }
258 
unixfclose(ix)259 unixfclose (ix)
260 FILE* ix;
261 
262 { fclose (ix); }
263 
external_system(command)264 external_system(command)
265      char *command;
266 {
267   int value;
268   value = system(command);
269   return(value);
270 }
271 
272 /* Tag( external_exit )
273  */
external_exit(status)274 external_exit(status)
275      int status;
276 {
277   exit(status);
278 }
279 
280 char *static_argv[20];  /* static place to hold argv so it doesn't get gc'd */
281 
copy_argv(argc,argv)282 copy_argv(argc,argv)    /* copy argv into static space. */
283 int argc;
284 char *argv[];
285 {
286   int i;
287 
288   for (i=0; i < argc; i++)
289      static_argv[i]=argv[i];
290 
291   return((int)static_argv);
292 }
293 
294 /* convert a pathname to canonical form */
295 char *
external_fullpath(relpath)296 external_fullpath(relpath)
297      char * relpath;
298 {
299   return realpath(relpath,NULL);
300 }
301