ignore & before array
[unix-history] / usr / src / old / berknet / mach.c
CommitLineData
2c049c08 1static char sccsid[] = "@(#)mach.c 4.2 (Berkeley) %G%";
40da0d40
KM
2
3/* sccs id variable */
4static char *mach_sid = "@(#)mach.c 1.6";
5/*
6
7 This file is meant to handle all the machine
8 dependencies in the network code.
9 Everything is conditionally compiled.
10
11 It can be uses w/o network stuff to simulate
12 v7 for other programs, too.
13*/
14# include <stdio.h>
15# include "mach.h"
16
17char shomedir[100];
18
19int debugflg;
20
21/* the CC and SRC machines have the submit() call */
22# ifndef CC
23# ifndef SRC
24submit(a) {}
2c049c08
DC
25# endif
26# endif
40da0d40
KM
27
28# ifdef FUID
29setgid() {};
2c049c08 30# endif
40da0d40
KM
31
32/*
33 Set the owner uid/gid of a file.
34 On v7, this is done by the chown command
35 with three args - (file, uid, gid).
36 On Vanilla V6 this is done using the
37 top byte of the second parameter as the gid byte.
38 On Berkeley Funny uids on V6, no gid is specified.
39*/
40mchown(sfn,uid,gid)
41 char *sfn;
42 int uid;
43 int gid;
44{
45# ifndef V6
46 chown(sfn,uid,gid);
2c049c08 47# else
40da0d40
KM
48# ifndef FUID
49 uid = uidmask(uid);
50 uid = ((gid&0377) << 8) | (uid & 0377);
2c049c08 51# endif
40da0d40
KM
52 chown(sfn,uid);
53 if(debugflg)
54 fprintf(stderr, "chown %s to %d(%o)\n",sfn,uid,uid);
2c049c08 55# endif
40da0d40
KM
56}
57
58
59/*
60 SnFromuid(uid)
61
62 The login name corresponding to uid.
63 Reads the password file.
64 Successive calls overwrite the static string returned.
65 Returns NULL if error.
66*/
67char *SnFromUid(uid)
68 register int uid;
69{
70 register struct passwd *pwd;
71 static int ouid = -1;
72 static char oresult[20] = "";
73 uid = uidmask(uid);
74 if(uid == ouid)
75 return(oresult);
76# ifdef HPASSWD
77 if(getname(uid,oresult) == 0){
78 ouid = uid;
79 return(oresult);
80 }
2c049c08 81# endif
40da0d40
KM
82 pwd = getpwuid(uid);
83 if(pwd != NULL){
84 strcpy(oresult,pwd->pw_name);
85 ouid = uid;
86 return(oresult);
87 }
88 return(NULL);
89}
90uidfromsn(sn)
91register char *sn;
92{
93 register int him = -1;
94 register struct passwd *pwd;
95# ifdef HPASSWD
96 him = getuserid(sn);
2c049c08 97# endif
40da0d40
KM
98 if(him == -1){
99 pwd = getpwnam(sn);
100 if(pwd != NULL)him = guid(pwd->pw_uid,pwd->pw_gid);
101 }
102 return(him);
103}
104
105/* handle the regular unix and local mods difference for user id's */
106/* this call returns the 1 word uid = to what getuid will return */
2c049c08 107guid(uid,gid){
40da0d40
KM
108 uid = uidmask(uid);
109# ifdef FUID
110 return((uid & 0377) | (gid << 8));
2c049c08 111# else
40da0d40 112 return(uid);
2c049c08
DC
113# endif
114 }
40da0d40
KM
115
116# ifdef OLDTTY
117isatty(i){
118 return(ttyn(i) != 'x');
119 }
120char *ttyname(i){ /* return NULL if not TTY */
121 char c;
122 static char ttystr[] = "/dev/ttyx";
123 c = ttyn(i);
124 ttystr[8] = c;
125 return(c == 'x' ? NULL : ttystr);
126 }
2c049c08 127# endif
40da0d40
KM
128
129# ifdef CCTTY
130# undef ttyname()
131char *myttyname(i){ /* return NULL for non tty */
132 static char s[15],*p;
133 p = ttyname(i);
134 if(p == NULL)return(NULL);
135 strcpy(s,"/dev/");
136 strcat(s,p);
137 return(s);
138 }
139# define ttyname(S) myttyname(S)
2c049c08 140# endif
40da0d40
KM
141
142/* expand control chars in string s */
143expandcc(s)
144 register char *s; {
145 char stemp[100];
146 register char *p;
147
148 if(s == NULL)return;
149 strcpy(stemp,s);
150 p = stemp;
151 while(*p){
152 if(!isprint(*p)){
153 *s++ = '^';
154 *s++ = *p++ + 0140;
155 }
156 else *s++ = *p++;
157 }
158}
159
160/* get passwd from passwdf */
161getpwdf(pwd)
162 struct passwd *pwd; {
163# ifdef PASSWDF
164# ifndef TESTING
165 register char *p, *q;
166 char buf1[BUFSIZ], found;
167 FILE *pw;
168 debug("reading passwdf\n");
169 pwd->pw_passwd[0] = 0;
170 pw = fopen("/etc/passwdf","r");
171 if(pw == NULL) return;
172 found = 0;
173 while(fgets(buf1,BUFSIZ,pw) != NULL){
174 for(p=buf1; *p && *p != ':'; p++);
175 *p = 0;
176 if(strcmp(buf1,pwd->pw_name) == 0){
177 found = 1;
178 break;
179 }
180 }
181 fclose(pw);
182 if(!found)return;
183 q = ++p;
184 for(;*p && *p != ':';p++);
185 *p = 0;
186 strcpy(pwd->pw_passwd,q);
187 /*
188 debug("user %s passwd %s %s",pwd->pw_name,pwd->pw_passwd);
189 */
2c049c08
DC
190# endif
191# endif
40da0d40
KM
192 }
193/*
194 getutmp()
195 return a pointer to the system utmp structure associated with
196 terminal sttyname, e.g. "/dev/tty3"
197 Is version independent-- will work on v6 systems
198 return NULL if error
199*/
200struct utmp *getutmp(sttyname)
201char *sttyname;
202{
203# ifdef OLDTTY
204 struct v6utmp {
205 char v6ut_name[8];
206 char v6ut_tty;
207 char v6ut_fill;
208 long v6ut_time;
209 int v6ut_fl1;
210 } v6utmpstr;
2c049c08 211# endif
40da0d40
KM
212 static struct utmp utmpstr;
213 FILE *fdutmp;
214
215 debug("reading utmp\n");
216 if(sttyname == NULL || sttyname[0] == 0)return(NULL);
217
218 fdutmp = fopen("/etc/utmp","r");
219 if(fdutmp == NULL)return(NULL);
220
221# ifndef OLDTTY
222 while(fread(&utmpstr,1,sizeof utmpstr,fdutmp) == sizeof utmpstr)
223 if(strcmp(utmpstr.ut_line,sttyname+5) == 0){
224 fclose(fdutmp);
225 return(&utmpstr);
226 }
2c049c08 227# else
40da0d40
KM
228 while(fread(&v6utmpstr,1,sizeof v6utmpstr,fdutmp) == sizeof v6utmpstr)
229 if(v6utmpstr.v6ut_tty == sttyname[8]){
230 strcpy(utmpstr.ut_name,v6utmpstr.v6ut_name);
231 strcpy(utmpstr.ut_line,"ttyx");
232 utmpstr.ut_line[3] = v6utmpstr.v6ut_tty;
233 utmpstr.ut_time = v6utmpstr.v6ut_time;
234 fclose(fdutmp);
235 return(&utmpstr);
236 }
2c049c08 237# endif
40da0d40
KM
238 fclose(fdutmp);
239 return(NULL);
240}
241
242/*
243 these are all the v7 routines not available on the v6 machines
244*/
245
246# ifdef V6
247
248char **environ; /* global environment pointer */
249
250ioctl(a,b,c){
251 return(0); /* always succeeds */
252 }
253long atol(s)
254 register char *s; {
255 long i = 0;
256 while('0' <= *s && *s <= '9')
257 i = i * 10 + (*s++ - '0');
258 return(i);
259 }
260long gettime(){
261 long tt;
262 time(&tt);
263 return(tt);
264 }
265long getsize(str)
266 struct stat *str; {
267 long wk;
268 wk = ((long)(str->st_size0 & 0377)) << 16;
269 wk += (long)((unsigned)str->st_size1);
270 return(wk);
271 }
272/*
273 getenv("HOME")
274
275 always returns home directory.
276 returns NULL if there is error.
277*/
278char *getenv(){
279 register char *shdir = NULL;
280 register struct passwd *pwd;
281 register int it;
282 if(shomedir[0] != 0)return(shomedir);
283# ifdef BERKELEY
284 /* hget only works on Berkeley machines */
285 it = ttyn(2);
286# ifdef OLDTTY
287 if(it == 'x')it = ttyn(1);
288 if(it == 'x')it = ttyn(0);
289 if(it != 'x' && hget(it) == 0)shdir = hgethome();
2c049c08 290# endif
40da0d40
KM
291# ifdef CCTTY
292 if(it == -1)it = ttyn(1);
293 if(it == -1)it = ttyn(0);
294 if(it != -1 && hget(it) == 0)shdir = hgethome();
2c049c08
DC
295# endif
296# endif
40da0d40
KM
297 if(shdir == NULL){
298 pwd = PwdCurrent();
299 if(pwd != NULL)shdir = pwd->pw_dir;
300 }
301 if(shdir != NULL)strcpy(shomedir,shdir);
302 return(shdir);
303 }
304
305/* doesn't handle split passwd files */
306struct passwd *
307getpwuid(uid)
308register uid;
309{
310 register struct passwd *p;
311 struct passwd *getpwent();
312
313 uid = uidmask(uid);
314 setpwent();
315 while( (p = getpwent()) && guid(p->pw_uid,p->pw_gid) != uid );
316 endpwent();
317 return(p);
318}
319
320static char PASSWD[] = "/etc/passwd";
321static char EMPTY[] = "";
322static FILE *pwf = NULL;
323static char line[BUFSIZ+1];
324static struct passwd passwd;
325
326setpwent()
327{
328 debug("reading passwd\n");
329 if( pwf == NULL )
330 pwf = fopen( PASSWD, "r" );
331 else
332 rewind( pwf );
333}
334
335endpwent()
336{
337 if( pwf != NULL ){
338 fclose( pwf );
339 pwf = NULL;
340 }
341}
342
343static char *
344pwskip(p)
345register char *p;
346{
347 while( *p && *p != ':' )
348 ++p;
349 if( *p ) *p++ = 0;
350 return(p);
351}
352
353struct passwd *
354getpwent()
355{
356 register char *p;
357
358 if (pwf == NULL) {
359 if( (pwf = fopen( PASSWD, "r" )) == NULL )
360 return(0);
361 }
362 p = fgets(line, BUFSIZ, pwf);
363 if (p==NULL)
364 return(0);
365 passwd.pw_name = p;
366 p = pwskip(p);
367 passwd.pw_passwd = p;
368 p = pwskip(p);
369 passwd.pw_uid = atoi(p);
370 passwd.pw_uid = uidmask(passwd.pw_uid);
371 p = pwskip(p);
372 passwd.pw_gid = atoi(p);
373 passwd.pw_quota = 0;
374 passwd.pw_comment = EMPTY;
375 p = pwskip(p);
376 passwd.pw_gecos = p;
377 p = pwskip(p);
378 passwd.pw_dir = p;
379 p = pwskip(p);
380 passwd.pw_shell = p;
381 while(*p && *p != '\n') p++;
382 *p = '\0';
383 return(&passwd);
384}
385
386struct passwd *
387getpwnam(name)
388char *name;
389{
390 register struct passwd *p;
391 struct passwd *getpwent();
392
393 setpwent();
394 while( (p = getpwent()) && strcmp(name,p->pw_name) );
395 endpwent();
396 return(p);
397}
398/*
399 getlogin()
400
401 Return current user name by looking at /etc/utmp (calls getutmp()).
402 Returns NULL if not found.
403*/
404char *getlogin()
405{
406 register struct utmp *putmp;
407 register char *s;
408 char sttyname[30];
409
410 if(isatty(2))strcpy(sttyname,ttyname(2));
411 else if(isatty(0))strcpy(sttyname,ttyname(0));
412 else if(isatty(1))strcpy(sttyname,ttyname(1));
413 else return(NULL);
414
415 putmp = getutmp(sttyname);
416 if(putmp == NULL)return(NULL);
417 s = putmp->ut_name;
418 while(*s != 0 && *s != ' ')s++;
419 *s = 0;
420 if(putmp->ut_name[0] == 0)return(NULL);
421 return(putmp->ut_name);
422}
423/*
424 * Unix routine to do an "fopen" on file descriptor
425 * The mode has to be repeated because you can't query its
426 * status
427 */
428
429FILE *
430fdopen(fd, mode)
431register char *mode;
432{
433 extern int errno;
434 register FILE *iop;
435 extern FILE *_lastbuf;
436
437 for (iop = _iob; iop->_flag&(_IOREAD|_IOWRT); iop++)
438 if (iop >= _lastbuf)
439 return(NULL);
440 iop->_cnt = 0;
441 iop->_file = fd;
442 if (*mode != 'r') {
443 iop->_flag |= _IOWRT;
444 if (*mode == 'a')
445 lseek(fd, 0L, 2);
446 } else
447 iop->_flag |= _IOREAD;
448 return(iop);
449}
450system(s)
451char *s;
452{
453 int status, pid, w;
454 register int (*istat)(), (*qstat)();
455
456 while((pid = fork()) == -1)sleep(2);
457 if (pid == 0) {
458 execl("/bin/sh", "sh", "-c", s, 0);
459 _exit(127);
460 }
461 istat = signal(SIGINT, SIG_IGN);
462 qstat = signal(SIGQUIT, SIG_IGN);
463 while ((w = wait(&status)) != pid && w != -1)
464 ;
465 if (w == -1)
466 status = -1;
467 signal(SIGINT, istat);
468 signal(SIGQUIT, qstat);
469 return(status);
470}
471
472char *
473getpass(prompt)
474char *prompt;
475{
476 struct sgttyb ttyb;
477 int flags;
478 register char *p;
479 register c;
480 FILE *fi = NULL;
481 static char pbuf[9];
482 int (*signal())();
483 int (*sig)();
484
485 /* modified because Cory needs super-user to stty /dev/tty */
486 if ((fi = fopen("/dev/tty", "r")) == NULL)
487 fi = stdin;
488 else
489 setbuf(fi, (char *)NULL);
490 if(gtty(fileno(fi),&ttyb) < 0){
491 pbuf[0] = 0;
492 return(pbuf);
493 }
494 /*
495 if(gtty(0,&ttyb) >= 0)fi = stdin;
496 else if(gtty(2,&ttyb) >= 0)fi = stderr;
497 else {
498 pbuf[0] = 0;
499 return(pbuf);
500 }
501 */
502 sig = signal(SIGINT, SIG_IGN);
503 flags = ttyb.sg_flags;
504 ttyb.sg_flags &= ~ECHO;
505 if(stty(fileno(fi), &ttyb) < 0) perror("stty:");
506 fprintf(stderr, prompt);
507 for (p=pbuf; (c = getc(fi))!='\n' && c!=EOF;) {
508 if (p < &pbuf[8])
509 *p++ = c;
510 }
511 *p = '\0';
512 fprintf(stderr, "\n");
513 ttyb.sg_flags = flags;
514 stty(fileno(fi), &ttyb);
515 signal(SIGINT, sig);
516 if (fi != stdin)
517 fclose(fi);
518 return(pbuf);
519}
520/*
521 * Compare strings (at most n bytes): s1>s2: >0 s1==s2: 0 s1<s2: <0
522 */
523
524strncmp(s1, s2, n)
525register char *s1, *s2;
526register n;
527{
528
529 while (--n >= 0 && *s1 == *s2++)
530 if (*s1++ == '\0')
531 return(0);
532 return(n<0 ? 0 : *s1 - *--s2);
533}
534
535/* set the umask, ignore in v6 */
536
537umask(n){}
538
40da0d40 539/* end of non-vax v7 routines */
2c049c08 540# endif
40da0d40
KM
541/*
542 PwdCurrent()
543
544 Read the password file and return pwd to
545 entry for current user.
546 Return NULL if error.
547
548 This code is a little screwed up because of the conventions
549 regarding the state of the utmp file after someone su's--
550 either to root or to another person.
551 The final decision was to return getpwuid(getuid) if
552 the machine has one login name per userid,
553 and if there are multiple login names per userid, to
554 search the passwd file for the getlogin() name and return
555 the passwd file entry for that.
556 If there is no utmp entry, just use the userid.
557 This means that people who su on machine with multiple
558 user-id's will get the passwd entry for the account recorded
559 in the utmp file, not their current userid.
560*/
561struct passwd *
562PwdCurrent()
563{
564 register struct passwd *pwd;
565 register char *sn;
566
567# ifdef MULTNAMS
568 sn = getlogin();
569 if(sn != NULL && sn[0] != 0 && sn[0] != ' '){
570 pwd = getpwnam(sn);
571 if(pwd != NULL)return(pwd);
572 }
2c049c08 573# endif
40da0d40
KM
574
575 return(getpwuid(uidmask(getuid())));
576}
577/*VARARGS0*/
578debug(s,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,t)
579char *s; {
580 if(debugflg){
581 printf(s,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,t);
582 putchar('\n');
583 }
584 }