home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / dec93 / os20 / util / multiuser.lha / MultiUser / C.src / MAssign.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-21  |  9.9 KB  |  390 lines

  1. /************************************************************
  2. * MultiUser - MultiUser Task/File Support System                *
  3. * ---------------------------------------------------------    *
  4. * Assign Clone for Non-Binding Assigns                                *
  5. * ---------------------------------------------------------    *
  6. * © Copyright 1993 by Geert Uytterhoeven                            *
  7. * All Rights Reserved.                                                    *
  8. ************************************************************/
  9.  
  10.  
  11. #include <exec/memory.h>
  12. #include <exec/execbase.h>
  13. #include <dos/dos.h>
  14. #include <dos/dosextens.h>
  15. #include <proto/exec.h>
  16. #include <proto/dos.h>
  17. #include <libraries/multiuser.h>
  18. #include <proto/multiuser.h>
  19. #include <string.h>
  20.  
  21. #include "MAssign_rev.h"
  22.  
  23.  
  24. char __VersTag__[] = VERSTAG;
  25.  
  26.  
  27. #define MAXPATHLEN    512
  28.  
  29.  
  30. static BOOL AddAssign(char *name, char *target, struct ExecBase *SysBase,
  31.                              struct DosLibrary *DOSBase, struct muBase *muBase);
  32. static struct DosPacket *WaitPktPort(struct MsgPort *port,
  33.                                                  struct ExecBase *SysBase);
  34. static ULONG GetPktOwner(struct DosPacket *pkt, struct muBase *muBase);
  35. static BPTR LockTarget(char *target, struct muUserInfo *uinfo,
  36.                               struct muGroupInfo *ginfo, LONG *error,
  37.                               struct DosLibrary *DOSBase);
  38. static void StripDevName(unsigned char *old, unsigned char *new);
  39. static BOOL Handler(struct DosList *dlist, char *target,
  40.                           struct MsgPort *pubport, struct ExecBase *SysBase,
  41.                           struct DosLibrary *DOSBase, struct muBase *muBase);
  42.  
  43.  
  44. int __saveds Start(char *arg)
  45. {
  46.     struct ExecBase *SysBase;
  47.     struct DosLibrary *DOSBase;
  48.     struct muBase *muBase = NULL;
  49.     struct RDArgs *args;
  50.     LONG argarray[] = {
  51. #define argNAME    0
  52. #define argTARGET    1
  53.         NULL, NULL
  54.     };
  55.     LONG error = NULL;
  56.     int rc = RETURN_OK;
  57.     struct muExtOwner *owner;
  58.     char *name;
  59.     int i;
  60.  
  61.     SysBase = *(struct ExecBase **)4;
  62.     
  63.     if ((!(DOSBase = (struct DosLibrary *)OpenLibrary("dos.library", 37))) ||
  64.          (!(muBase = (struct muBase *)OpenLibrary("multiuser.library", 39)))) {
  65.         rc = RETURN_FAIL;
  66.         goto Exit;
  67.     }
  68.     owner = muGetTaskExtOwner(NULL);
  69.     if (muGetRelationshipA(owner, NULL, NULL) & muRelF_ROOT_UID) {
  70.         args = ReadArgs("NAME/A,TARGET/A", argarray, NULL);
  71.         if (!args)
  72.             error = IoErr();
  73.         else {
  74.             for (i = 0; ((char *)argarray[argNAME])[i] &&
  75.                             (((char *)argarray[argNAME])[i] != ':'); i++);
  76.             if (((char *)argarray[argNAME])[i] != ':') {
  77.                 VPrintf("Invalid device name %s\n", (char **)argarray[argNAME]);
  78.                 rc = RETURN_ERROR;
  79.             } else if (name = AllocVec(i+1, MEMF_CLEAR|MEMF_PUBLIC)) {
  80.                 memcpy(name, (char *)argarray[argNAME], i);
  81.                 if (!AddAssign(name, (char *)argarray[argTARGET], SysBase,
  82.                                     DOSBase, muBase))
  83.                     rc = RETURN_ERROR;
  84.                 FreeVec(name);
  85.             } else
  86.                 error = IoErr();
  87.         }
  88.         FreeArgs(args);
  89.     } else {
  90.         PutStr("MAssign must be run by root\n");
  91.         rc = RETURN_ERROR;
  92.     }
  93.     muFreeExtOwner(owner);
  94.     if (error) {
  95.         PrintFault(error, NULL);
  96.         rc = RETURN_ERROR;
  97.     }
  98.  
  99. Exit:
  100.     CloseLibrary((struct Library *)muBase);
  101.     CloseLibrary((struct Library *)DOSBase);
  102.  
  103.     return(rc);
  104. }
  105.  
  106.  
  107. static BOOL AddAssign(char *name, char *target, struct ExecBase *SysBase,
  108.                              struct DosLibrary *DOSBase, struct muBase *muBase)
  109. {
  110.     struct DosList *dlist;
  111.     struct MsgPort *port;
  112.     BOOL res = FALSE;
  113.  
  114.     if ((port = CreateMsgPort()) && (dlist = MakeDosEntry(name, DLT_DEVICE))) {
  115.         dlist->dol_Task = port;
  116.         dlist->dol_misc.dol_handler.dol_SegList = -1;
  117.         if (AddDosEntry(dlist))
  118.             res = Handler(dlist, target, port, SysBase, DOSBase, muBase);
  119.         else
  120.             VPrintf("%s conflicts with another assign\n", (LONG *)&name);
  121.         FreeDosEntry(dlist);
  122.     } else
  123.         PrintFault(IoErr(), NULL);
  124.  
  125.     DeleteMsgPort(port);
  126.     return(res);
  127. }
  128.  
  129.  
  130. static struct DosPacket *WaitPktPort(struct MsgPort *port,
  131.                                                  struct ExecBase *SysBase)
  132. {
  133.     struct Message *msg;
  134.     struct DosPacket *pkt = NULL;
  135.  
  136.     do
  137.         if (msg = GetMsg(port))
  138.             pkt = (struct DosPacket *)msg->mn_Node.ln_Name;
  139.         else
  140.             WaitPort(port);
  141.     while (!pkt);
  142.     return(pkt);
  143. }
  144.  
  145.  
  146. static ULONG GetPktOwner(struct DosPacket *pkt, struct muBase *muBase)
  147. {
  148.     struct MsgPort *port;
  149.     struct Task *task;
  150.     ULONG owner = NULL;
  151.  
  152.     if ((port = pkt->dp_Port) && (port->mp_Flags == PA_SIGNAL) &&
  153.          (task = port->mp_SigTask))
  154.                 owner = muGetTaskOwner(task);
  155.     return(owner);
  156. }
  157.  
  158.  
  159. static BPTR LockTarget(char *target, struct muUserInfo *uinfo,
  160.                               struct muGroupInfo *ginfo, LONG *error,
  161.                               struct DosLibrary *DOSBase)
  162. {
  163.     BPTR lock = NULL;
  164.     char path[MAXPATHLEN];
  165.     int len = 0, i = 0, slen;
  166.     char *str;
  167.  
  168.     *error = NULL;
  169.     while (len < MAXPATHLEN)
  170.         if (target[i])
  171.             if (target[i] == '%') {
  172.                 switch (target[i+1]) {
  173.                     case 'u':
  174.                         if (uinfo) {
  175.                             str = uinfo->UserID;
  176. Copy:                        if ((slen = strlen(str)) <= MAXPATHLEN-len) {
  177.                                 memcpy(&path[len], str, slen);
  178.                                 len += slen;
  179.                             } else {
  180.                                 *error = ERROR_LINE_TOO_LONG;
  181.                                 return(NULL);
  182.                             }
  183.                         } else {
  184. NotFound:                *error = ERROR_OBJECT_NOT_FOUND;
  185.                             return(NULL);
  186.                         }
  187.                         break;
  188.  
  189.                     case 'h':
  190.                         if (uinfo) {
  191.                             str = uinfo->HomeDir;
  192.                             goto Copy;
  193.                         } else
  194.                             goto NotFound;
  195.  
  196.                     case 'g':
  197.                         if (ginfo) {
  198.                             str = ginfo->GroupID;
  199.                             goto Copy;
  200.                         } else
  201.                             goto NotFound;
  202.  
  203.                     case '%':
  204.                         path[len++] = '%';
  205.                         break;
  206.  
  207.                     default:
  208.                         *error = ERROR_BAD_TEMPLATE;
  209.                         return(NULL);
  210.                 }
  211.                 i += 2;
  212.             } else
  213.                 path[len++] = target[i++];
  214.         else
  215.             break;
  216.     if (len < MAXPATHLEN) {
  217.         path[len] = '\0';
  218.         if (!(lock = Lock(path, ACCESS_READ)))
  219.             *error = IoErr();
  220.     } else
  221.         *error = ERROR_LINE_TOO_LONG;
  222.     return(lock);
  223. }
  224.  
  225.  
  226. // Note: both old and new are CPTRs to a BSTR!
  227.  
  228. static void StripDevName(unsigned char *old, unsigned char *new)
  229. {
  230.     int len, i;
  231.  
  232.     len = old[0];
  233.     for (i = 0; (i < len) && (old[i+1] != ':'); i++);
  234.     if (i == len)
  235.         memcpy(new, old, len+1);
  236.     else {
  237.         memcpy(new+1, old+i+2, len-i-1);
  238.         new[0] = len-i-1;
  239.     }
  240. }
  241.  
  242.  
  243. static BOOL Handler(struct DosList *dlist, char *target,
  244.                           struct MsgPort *pubport, struct ExecBase *SysBase,
  245.                           struct DosLibrary *DOSBase, struct muBase *muBase)
  246. {
  247.     BOOL die = FALSE;
  248.     BOOL removed = FALSE;
  249.     char *newpath = NULL;
  250.     struct Task *task;
  251.     BYTE oldpri;
  252.     struct muUserInfo *uinfo;
  253.     struct muGroupInfo *ginfo = NULL, *ginfo2;
  254.     struct MsgPort *privport, *port;
  255.     struct DosPacket *pubpkt, *privpkt;
  256.     BPTR lock;
  257.     ULONG owner;
  258.     BOOL res = FALSE;
  259.     struct TagItem tags[3];
  260.     LONG type, arg1, arg2, arg3, arg4, res1, res2;
  261.  
  262.     if ((uinfo = muAllocUserInfo()) && (ginfo = muAllocGroupInfo()) &&
  263.          (newpath = AllocVec(256, MEMF_CLEAR|MEMF_PUBLIC)) &&
  264.          (privpkt = AllocDosObject(DOS_STDPKT, NULL))) {
  265.         task = SysBase->ThisTask;
  266.         oldpri = SetTaskPri(task, 5);
  267.         privport = &((struct Process *)task)->pr_MsgPort;
  268.  
  269.         do {
  270.             pubpkt = WaitPktPort(pubport, SysBase);
  271.             type = pubpkt->dp_Type;
  272.             arg1 = pubpkt->dp_Arg1;
  273.             arg2 = pubpkt->dp_Arg2;
  274.             arg3 = pubpkt->dp_Arg3;
  275.             arg4 = pubpkt->dp_Arg4;
  276.             switch (pubpkt->dp_Type) {
  277.                 case ACTION_DIE:
  278.                     die = TRUE;
  279.                     ReplyPkt(pubpkt, DOSTRUE, NULL);
  280.                     break;
  281.  
  282.                 case ACTION_FINDINPUT:
  283.                 case ACTION_FINDOUTPUT:
  284.                 case ACTION_FINDUPDATE:
  285.                 case ACTION_SET_PROTECT:
  286.                 case ACTION_SET_COMMENT:
  287.                 case ACTION_SET_DATE:
  288.                 case ACTION_SET_OWNER:
  289.                 case ACTION_LOCATE_OBJECT:
  290.                 case ACTION_CREATE_DIR:
  291.                 case ACTION_DELETE_OBJECT:
  292.                 case ACTION_RENAME_OBJECT:
  293.                 case ACTION_MAKE_LINK:
  294.                 case ACTION_READ_LINK:
  295.                 case ACTION_DISK_CHANGE:
  296.                 case ACTION_IS_FILESYSTEM:
  297.                 case ACTION_CURRENT_VOLUME:
  298.                 case ACTION_FLUSH:
  299.                 case ACTION_MORE_CACHE:
  300.                     owner = GetPktOwner(pubpkt, muBase);
  301.                     uinfo->uid = (owner & muMASK_UID)>>16;
  302.                     if (muGetUserInfo(uinfo, muKeyType_uid)) {
  303.                         ginfo->gid = owner & muMASK_GID;
  304.                         ginfo2 = muGetGroupInfo(ginfo, muKeyType_gid);
  305.                         if (lock = LockTarget(target, uinfo, ginfo2, &res2,
  306.                                                      DOSBase)) {
  307.                             port = ((struct FileLock *)BADDR(lock))->fl_Task;
  308.                             tags[0].ti_Tag = muT_UserID;
  309.                             tags[0].ti_Data = (LONG)uinfo->UserID;
  310.                             tags[1].ti_Tag = muT_Password;
  311.                             tags[1].ti_Data = (LONG)"";
  312.                             tags[2].ti_Tag = TAG_DONE;
  313.                             if (muLoginA(tags)) {
  314.                                 switch (pubpkt->dp_Type) {
  315.                                     case ACTION_FINDINPUT:
  316.                                     case ACTION_FINDOUTPUT:
  317.                                     case ACTION_FINDUPDATE:
  318.                                     case ACTION_SET_PROTECT:
  319.                                     case ACTION_SET_COMMENT:
  320.                                     case ACTION_SET_DATE:
  321.                                     case ACTION_SET_OWNER:
  322.                                         StripDevName(BADDR(arg3), newpath);
  323.                                         arg2 = lock;
  324.                                         arg3 = MKBADDR(newpath);
  325. PassPkt:                                privpkt->dp_Type = type;
  326.                                         privpkt->dp_Arg1 = arg1;
  327.                                         privpkt->dp_Arg2 = arg2;
  328.                                         privpkt->dp_Arg3 = arg3;
  329.                                         privpkt->dp_Arg4 = arg4;
  330.                                         SendPkt(privpkt, port, privport);
  331.                                         WaitPkt();
  332.                                         res1 = privpkt->dp_Res1;
  333.                                         res2 = privpkt->dp_Res2;
  334.                                         break;
  335.  
  336.                                     case ACTION_LOCATE_OBJECT:
  337.                                     case ACTION_CREATE_DIR:
  338.                                     case ACTION_DELETE_OBJECT:
  339.                                     case ACTION_RENAME_OBJECT:
  340.                                     case ACTION_MAKE_LINK:
  341.                                     case ACTION_READ_LINK:
  342.                                         StripDevName(BADDR(arg2), newpath);
  343.                                         arg1 = lock;
  344.                                         arg2 = MKBADDR(newpath);
  345.                                         goto PassPkt;
  346.  
  347.                                     case ACTION_IS_FILESYSTEM:
  348.                                     case ACTION_CURRENT_VOLUME:
  349.                                     case ACTION_FLUSH:
  350.                                     case ACTION_MORE_CACHE:
  351.                                         goto PassPkt;
  352.                                 }
  353.                                 tags[0].ti_Tag = muT_Quiet;
  354.                                 tags[0].ti_Data = TRUE;
  355.                                 tags[1].ti_Tag = TAG_DONE;
  356.                                 muLogoutA(tags);
  357.                             } else {
  358.                                 res1 = DOSFALSE;
  359.                                 res2 = ERROR_OBJECT_NOT_FOUND;
  360.                             }
  361.                             UnLock(lock);
  362.                             ReplyPkt(pubpkt, res1, res2);
  363.                         } else
  364.                             ReplyPkt(pubpkt, DOSFALSE, res2);
  365.                     } else
  366.                         ReplyPkt(pubpkt, DOSFALSE, ERROR_OBJECT_NOT_FOUND);
  367.                     break;
  368.  
  369.                 default:
  370.                     ReplyPkt(pubpkt, DOSFALSE, ERROR_ACTION_NOT_KNOWN);
  371.                     break;
  372.             }
  373.             if (die && AttemptLockDosList(LDF_DEVICES|LDF_WRITE)) {
  374.                 removed = RemDosEntry(dlist);
  375.                 UnLockDosList(LDF_DEVICES|LDF_WRITE);
  376.             }
  377.         } while (!die || !removed);
  378.         SetTaskPri(task, oldpri);
  379.         FreeDosObject(DOS_STDPKT, privpkt);
  380.         res = TRUE;
  381.     } else
  382.         PrintFault(IoErr(), NULL);
  383.  
  384.     muFreeUserInfo(uinfo);
  385.     muFreeGroupInfo(ginfo);
  386.     FreeVec(newpath);
  387.  
  388.     return(res);
  389. }
  390.