/* * login() is a stupid little login process that loads a prototype * environment before forking off processes. */ #include #include #include #include char *format(); char *basename(); /* * login, itself */ main(argc,argv) char **argv; { char homedir[200]; char logname[200]; char *tenv; char *ptr; char *site; extern char *getenv(); #define Skip(x,c) if (ptr=strchr(x,c)) *ptr++ = 0; else continue FILE *fp; char line[200]; char login[100]; char *who, *home, *cmd, *args; int drv; if (fp=fopen("/etc/login.env", "r")) { while (fgets(line, 200, fp)) { strtok(line, "\n"); if (line[0] != '#') putenv(format(strdup(line))); } fclose(fp); } if ((site = getenv("SITE")) == (char*)0) site = "ms-dos"; fp = fopen("/etc/passwd", "r"); printf("%s login: ", site); fflush(stdout); while (gets(login)) { if (strlen(login) == 0) goto next2; while (fgets(line, 200, fp)) { strtok(line, "\n"); Skip(who=line, ';'); /* username */ Skip(ptr, ';'); /* password */ Skip(ptr, ';'); /* uid */ Skip(ptr, ';'); /* gid */ Skip(ptr, ';'); /* gcos */ Skip(home=ptr, ';'); /* home directory */ if (ptr = strchr(cmd=ptr, ' ')) { *ptr++ = 0; args = ptr; } else args = (char*)0; format(args); if (strcmp(login, who) == 0) { if (home[1] == ':') { /* stupid kludge */ drv = home[0] & ~0x20; drv -= ('A' - 1); _chdrive(drv); } chdir(home); sprintf(homedir, "HOME=%s", home); putenv(homedir); sprintf(logname, "LOGNAME=%s", who); putenv(logname); spawnl(P_OVERLAY, cmd, basename(cmd), args, (char*)0); printf("cannot load %s\n", cmd); goto next; } } puts("Fat chance, buddo!\n"); next: rewind(fp); next2: fputs("login: ", stdout); fflush(stdout); } exit(0); } /* main */ /* * format() takes a string and processes appropriate escapes. Because ms-dos * likes backslashes, they are not the best way of escaping things, so... * We use % to introduce escape seqences: * %s - a space * %b - a backspace * %n - a newline * %f - a formfeed * %r - a return * %E - an escape char * %% - a % * % - is the ascii character specified by those digits */ char * format(s) register char *s; { register char *p; register c; char *base = s; if (base == (char*)0) return (char*)0; for (p=s; *s; s++, p++) { if (*s == '%') { switch (*++s) { case 's': *p = ' '; break; case 'b': *p = '\b'; break; case 'n': *p = '\n'; break; case 'r': *p = '\r'; break; case 'f': *p = '\f'; break; case 'E': *p = '\033';break; case '%': *p = '%'; break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': for (c=0, --s; isalpha(s[1]);++s) c = (c*10) + (*s - '0'); *p = c; break; default: *p = '?'; break; } } else if (p < s) *p = *s; } *p = 0; return base; } /* format */ /* * basename() returns the base part of a filename, with extension intact */ char * basename(s) register char *s; { register char *t; for (t=s+strlen(s)-1; t >= s; --t) if (*t == '\\' || *t == '/' || *t == ':') return 1+t; return s; } /* basename */