# clogon # port of wm/logon to the command line # # dalai(dalai@swbt.net) # http://www.swbt.net/~dalai implement clogon; include "sys.m"; sys: Sys; include "draw.m"; include "sh.m"; include "newns.m"; clogon: module { init: fn(nil: ref Draw->Context, argv: list of string); }; init(nil: ref Draw->Context, argv: list of string) { sys = load Sys Sys->PATH; sys->print("clogon, by dalai(dalai@swbt.net)\n"); sys->pctl(sys->FORKNS|sys->FORKFD, nil); progdir := "#p/" + string sys->pctl(0, nil); kfd := sys->open(progdir+"/ctl", sys->OWRITE); if(kfd == nil) { sys->sprint("cannot open %s: %r", progdir+"/ctl"); sys->raise("fail:bad prog dir"); } usr := ""; if(argv != nil) { argv = tl argv; if(argv != nil && hd argv == "-u") { argv = tl argv; if(argv != nil) { usr = hd argv; argv = tl argv; } } } if (usr == nil || !logon(usr)) { sys->print("usage: clogon -u user\n"); } (ok, nil) := sys->stat("namespace"); if(ok >= 0) { ns := load Newns Newns->PATH; if(ns == nil) sys->print("failed to load namespace builder\n"); else if ((nserr := ns->newns(nil, nil)) != nil){ sys->print("error in user namespace file: %s", nserr); sys->print("\n"); } } sys->fprint(kfd, "killgrp"); errch := chan of string; spawn exec(argv, errch); err := <-errch; if (err != nil) { sys->fprint(stderr(), "logon: %s\n", err); sys->raise("fail:exec failed"); } } exec(argv: list of string, errch: chan of string) { sys->pctl(sys->NEWFD, 0 :: 1 :: 2 :: nil); e := ref Sys->Exception; if (sys->rescue("fail:*", e) == Sys->EXCEPTION) { sys->rescued(Sys->ONCE, nil); exit; } argv = "/dis/sh/sh.dis" :: "-i" :: "-n" :: nil; cmd := load Command hd argv; if (cmd == nil) { errch <-= sys->sprint("cannot load %s: %r", hd argv); } else { errch <-= nil; cmd->init(nil, argv); } } logon(user: string): int { userdir := "/usr/"+user; if(sys->chdir(userdir) < 0) { sys->print("There is no home directory for that user mounted on this machine\n"); return 0; } # # Set the user id # fd := sys->open("/dev/user", sys->OWRITE); if(fd == nil) { sys->print("failed to open /dev/user: %r\n"); return 0; } b := array of byte user; if(sys->write(fd, b, len b) < 0) { sys->print("failed to write /dev/user with error: %r\n"); return 0; } return 1; } stderr(): ref Sys->FD { return sys->fildes(2); }