home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format 56 / af056sub.adf / parnfs.lha / server.c < prev    next >
C/C++ Source or Header  |  1993-12-02  |  16KB  |  619 lines

  1. /*
  2.  * $Id: server.c,v 1.1 1993/12/02 20:45:46 Rhialto Exp $
  3.  * $Log: server.c,v $
  4.  * Revision 1.1  1993/12/02  20:45:46  Rhialto
  5.  * Initial revision
  6.  *
  7.  * The bulk of the server code: receive packets and act upon them.
  8.  */
  9.  
  10. #include "netfs.h"
  11. #include <stdio.h>
  12. #include <string.h>
  13. #include "getopt.c"
  14.  
  15. #ifdef DEBUG
  16. #   include "syslog.h"
  17. #else
  18. #   define    debug(x)
  19. #endif
  20.  
  21. long        UnitNr;
  22. char           *DevName = "parnet.device";
  23. ULONG        DevFlags;
  24. struct DosPacket *DosPkt;
  25. ULONG        WaitMask;
  26. ULONG        Validation;
  27. ULONG        MyValidation;
  28. struct MsgPort *DosPort;
  29. struct MsgPort *AsyncDosPort;
  30. struct Process *Proc;
  31. void           *pr_WindowPtr = -2;
  32.  
  33. void
  34. chkabort(void)
  35. {
  36.     /* do not check for break */
  37. }
  38.  
  39. void
  40. dumppkt(Packet *pkt)
  41. {
  42.     debug(("Packet: %08lx; %08lx, %08lx %08lx %08lx %08lx %08lx\n",
  43.       *(long *)pkt, pkt->p_Action,
  44.       pkt->p_Arg[0], pkt->p_Arg[1], pkt->p_Arg[2],
  45.       pkt->p_Arg[3], pkt->p_Arg[4], pkt->p_Arg[5]));
  46. }
  47.  
  48. Prototype ULONG dopacket(struct DosPacket *packet, struct MsgPort *port);
  49.  
  50. ULONG
  51. dopacket(struct DosPacket *packet, struct MsgPort *port)
  52. {
  53.     packet->dp_Port = DosPort;
  54.  
  55.     PutMsg(port, packet->dp_Link);
  56.     WaitPort(DosPort);
  57.     GetMsg(DosPort);
  58.  
  59.     return packet->dp_Res1;
  60. }
  61.  
  62. void
  63. doasyncpacket(struct DosPacket *packet, struct MsgPort *port)
  64. {
  65.     packet->dp_Port = AsyncDosPort;
  66.  
  67.     PutMsg(port, packet->dp_Link);
  68. }
  69.  
  70. /*
  71.  * Create a DOS style packet: a message and a dos packet linked to
  72.  * each other. The size of the message is variable so you can include
  73.  * extra information behind it, or use it as an I/O request.
  74.  */
  75.  
  76. struct DosPacket *
  77. CreateDosPkt(int size)
  78. {
  79.     struct DosPacket *dp;
  80.     struct Message *msg;
  81.  
  82.     size += sizeof(struct Message) + sizeof(struct DosPacket);
  83.  
  84.     if (msg = AllocMem(size, MEMF_PUBLIC | MEMF_CLEAR)) {
  85.     dp = (char *)msg + size - sizeof(struct DosPacket);
  86.  
  87.     dp->dp_Link = msg;
  88.     msg->mn_Node.ln_Name = (char *)dp;
  89.     msg->mn_Length = size;
  90.     }
  91.     return dp;
  92. }
  93.  
  94. void
  95. DeleteDosPkt(struct DosPacket *dp)
  96. {
  97.     if (dp) {
  98.     struct Message *msg = dp->dp_Link;
  99.  
  100.     FreeMem(msg, msg->mn_Length);
  101.     }
  102. }
  103.  
  104. struct MsgPort *
  105. FindProc(BPTR fl, char *bstr)
  106. {
  107.     struct FileLock *lock;
  108.  
  109.     if (strchr(bstr + 1, ':')) {
  110.     return DeviceProc(bstr + 1);
  111.     }
  112.  
  113.     lock = BTOC(fl);
  114.  
  115.     return lock->fl_Task;
  116. }
  117.  
  118. UBYTE *
  119. SkipString(UBYTE *s)
  120. {
  121.     s = s + s[0] + 2;
  122.     s = (UBYTE *)((ULONG)(s + 3) & ~3);
  123.     return s;
  124. }
  125.  
  126. /* ---------------------------------------------------------------------- */
  127.  
  128. void
  129. HandleRequest(struct IOParReq *io, Packet *pkt)
  130. {
  131.     LONG        tmp;
  132.     ULONG        replysize;
  133.  
  134.     debug(("type %d action %d\n", pkt->p_Type, pkt->p_Action));
  135.  
  136.     switch (DoProtocol(io, pkt)) {
  137.     case pt_Request:
  138.     break;
  139.     default:
  140.     return;
  141.     }
  142.  
  143.     /* Now we know it's a request, we can do something about it. */
  144.  
  145.     replysize = STDREPLY;
  146.     Proc->pr_Result2 = 0;
  147.  
  148.     switch (pkt->p_Action) {
  149. /*  case ACTION_DIE:           / *  attempt to die?             */
  150. /*  case ACTION_CURRENT_VOLUME:/ * -               VolNode,UnitNr*/
  151.     case ACTION_RENAME_DISK:    /* New name           Bool      */
  152.     {
  153.         char *newname;
  154.  
  155.         newname = SkipString((char *)&pkt->p_Arg[0])+1;
  156.         debug(("Relabel '%s' -> '%s'\n", ((char *)&pkt->p_Arg[0])+1, newname));
  157.         pkt->p_Res1 = Relabel((char *)&pkt->p_Arg[0]+1, newname);
  158.         pkt->p_Res2 = Proc->pr_Result2;
  159.     }
  160.     break;
  161.     case ACTION_LOCATE_OBJECT:    /* Lock,Name,Mode    Lock         */
  162.     tmp = CurrentDir(pkt->p_Arg[0]);
  163.     pkt->p_Res1 = Lock((char *)&pkt->p_Arg[2]+1, pkt->p_Arg[1]);
  164.     pkt->p_Res2 = Proc->pr_Result2;
  165.     CurrentDir(tmp);
  166.     break;
  167.     case ACTION_FREE_LOCK:    /* Lock            Bool      */
  168.     UnLock(pkt->p_Arg[0]);
  169.     pkt->p_Res1 = DOSTRUE;
  170.     pkt->p_Res2 = Proc->pr_Result2;
  171.     break;
  172.     case ACTION_DELETE_OBJECT:    /* Lock,Name        Bool         */
  173.     tmp = CurrentDir(pkt->p_Arg[0]);
  174.     pkt->p_Res1 = DeleteFile((char *)&pkt->p_Arg[1]+1);
  175.     pkt->p_Res2 = Proc->pr_Result2;
  176.     CurrentDir(tmp);
  177.     break;
  178.     case ACTION_RENAME_OBJECT:    /* SLock,SName,DLock,DName   Bool    */
  179.     {
  180.         struct MsgPort *handler;
  181.         char *sname;
  182.         char *dname;
  183.  
  184.         sname = (char *)(&pkt->p_Arg[2]);
  185.         dname = SkipString(sname);
  186.  
  187.         DosPkt->dp_Action = ACTION_RENAME_OBJECT;
  188.         DosPkt->dp_Arg1 = pkt->p_Arg[0];
  189.         DosPkt->dp_Arg2 = CTOB(sname);
  190.         DosPkt->dp_Arg3 = pkt->p_Arg[1];
  191.         DosPkt->dp_Arg4 = CTOB(dname);
  192.  
  193.         handler = FindProc(pkt->p_Arg[0], sname+1);
  194.         if (handler == NULL)
  195.         handler = FindProc(pkt->p_Arg[1], dname+1);
  196.         if (handler != NULL) {
  197.         dopacket(DosPkt, handler);
  198.  
  199.         pkt->p_Res1 = DosPkt->dp_Res1;
  200.         pkt->p_Res2 = DosPkt->dp_Res2;
  201.         } else {
  202.         pkt->p_Res1 = DOSFALSE;
  203.         pkt->p_Res2 = ERROR_INVALID_LOCK;
  204.         }
  205.     }
  206.     break;
  207.     case ACTION_COPY_DIR:    /* Lock            Lock      */
  208.     pkt->p_Res1 = DupLock(pkt->p_Arg[0]);
  209.     pkt->p_Res2 = Proc->pr_Result2;
  210.     break;
  211.     case ACTION_SET_PROTECT:    /* -,Lock,Name,Mask       Bool      */
  212.     tmp = CurrentDir(pkt->p_Arg[0]);
  213.     pkt->p_Res1 = SetProtection((char *)&pkt->p_Arg[2]+1, pkt->p_Arg[1]);
  214.     pkt->p_Res2 = Proc->pr_Result2;
  215.     CurrentDir(tmp);
  216.     break;
  217.     case ACTION_CREATE_DIR:    /* Lock,Name        Lock         */
  218.     tmp = CurrentDir(pkt->p_Arg[0]);
  219.     pkt->p_Res1 = CreateDir((char *)&pkt->p_Arg[1]+1);
  220.     pkt->p_Res2 = Proc->pr_Result2;
  221.     CurrentDir(tmp);
  222.     break;
  223. /*
  224.  * Note that for ExNext() the FileInfoBlock is copied from the client
  225.  * to the server, and back again. This is because ExNext needs the fib
  226.  * to be initialised by a previous call. In fact, it even may insist
  227.  * on the *very same* fib to be used in each call in a sequence.
  228.  * Possibly it may even require that several simultaneous scans of the
  229.  * same directory use *different* fibs. Obviously, we can't comply with
  230.  * those requirements. For the moment it seems to work ok, but who knows
  231.  * it might break in the future!
  232.  * Also, because the fib is copied in and out, we refer to it through
  233.  * the incoming field names of the packet exclusively. Care must be
  234.  * taken with overlapping fields in request and reply.
  235.  */
  236.     case ACTION_EXAMINE_OBJECT: /* Lock,Fib           Bool         */
  237.     case ACTION_EXAMINE_NEXT:    /* Lock,Fib           Bool         */
  238.     DosPkt->dp_Action = pkt->p_Action;
  239.     DosPkt->dp_Arg1 = pkt->p_Arg[0];
  240.     DosPkt->dp_Arg2 = CTOB(&pkt->p_Arg[1]);
  241.  
  242.     dopacket(DosPkt, ((struct FileLock *)BTOC(pkt->p_Arg[0]))->fl_Task);
  243.  
  244.     pkt->p_Res2 = DosPkt->dp_Res2;
  245.     if (pkt->p_Res1 = DosPkt->dp_Res1)
  246.         replysize = STDREPLY + sizeof(struct FileInfoBlock);
  247. #ifdef xDEBUG
  248.     {
  249.         struct FileInfoBlock *fib;
  250.         fib = (struct FileInfoBlock *)&pkt->p_Data[0];
  251.         debug(("key %x size %d name '%.*s'\n", fib->fib_DiskKey, fib->fib_Size,
  252.             fib->fib_FileName[0], &fib->fib_FileName[1]));
  253.     }
  254. #endif
  255.     break;
  256. /*  case ACTION_DISK_INFO:     / * InfoData           Bool:TRUE     */
  257.     case ACTION_INFO:    /* Lock,InfoData           Bool:TRUE     */
  258.     pkt->p_Res1 = Info(pkt->p_Arg[0], (void *)&pkt->p_Data[0]);
  259.     pkt->p_Res2 = Proc->pr_Result2;
  260.     if (pkt->p_Res1)
  261.         replysize = STDREPLY + sizeof(struct InfoData);
  262.     break;
  263. /*  case ACTION_FLUSH:           / * writeout bufs, disk motor off     */
  264.     case ACTION_SET_COMMENT:    /* -,Lock,Name,Comment       Bool      */
  265.     tmp = CurrentDir(pkt->p_Arg[0]);
  266.     pkt->p_Res1 = SetComment((char *)&pkt->p_Arg[1]+1,
  267.                  SkipString((char *)&pkt->p_Arg[1])+1);
  268.     pkt->p_Res2 = Proc->pr_Result2;
  269.     CurrentDir(tmp);
  270.     break;
  271.     break;
  272.     case ACTION_PARENT: /* Lock                ParentLock    */
  273.     pkt->p_Res1 = ParentDir(pkt->p_Arg[0]);
  274.     pkt->p_Res2 = Proc->pr_Result2;
  275.     break;
  276. /*  case ACTION_INHIBIT:       / * Bool            Bool      */
  277.     case ACTION_SET_DATE: /* -,Lock,Name,CPTRDateStamp       Bool      */
  278.     tmp = CurrentDir(pkt->p_Arg[0]);
  279. /*V37*/ pkt->p_Res1 = SetFileDate((char *)&pkt->p_Arg[4]+1,
  280.                   (struct DateStamp *)&pkt->p_Arg[1]);
  281.     pkt->p_Res2 = Proc->pr_Result2;
  282.     CurrentDir(tmp);
  283.     break;
  284.     case ACTION_SAME_LOCK:  /* Lock1,Lock2           Result    */
  285.     if (pkt->p_Arg[0] == 0 || pkt->p_Arg[1] == 0) {
  286.         /* We never send 0 locks */
  287.         pkt->p_Res1 = DOSFALSE;
  288.         pkt->p_Res2 = ERROR_INVALID_LOCK;
  289.     } else {
  290.         DosPkt->dp_Action = ACTION_SAME_LOCK;
  291.         DosPkt->dp_Arg1 = pkt->p_Arg[0];
  292.         DosPkt->dp_Arg2 = pkt->p_Arg[1];
  293.  
  294.         dopacket(DosPkt, ((struct FileLock *)BTOC(pkt->p_Arg[0]))->fl_Task);
  295.  
  296.         pkt->p_Res1 = DosPkt->dp_Res1;
  297.         pkt->p_Res2 = DosPkt->dp_Res2;
  298.     }
  299.     break;
  300.     case ACTION_READ:    /* FHArg1,CPTRBuffer,Length      ActLength  */
  301.     tmp = Read(pkt->p_Arg[0], &pkt->p_Data[0], pkt->p_Arg[1]);
  302.     pkt->p_Res1 = tmp;
  303.     pkt->p_Res2 = Proc->pr_Result2;
  304.     if (tmp > 0)
  305.         replysize = STDREPLY + tmp;
  306.     break;
  307.     case ACTION_WRITE:    /* FHArg1,CPTRBuffer,Length      ActLength  */
  308.     pkt->p_Res1 = Write(pkt->p_Arg[0], &pkt->p_Arg[2], pkt->p_Arg[1]);
  309.     pkt->p_Res2 = Proc->pr_Result2;
  310.     break;
  311.     case ACTION_OPENRW:     /* FileHandle,Lock,Name    Bool      */
  312.     case ACTION_OPENOLD:    /* FileHandle,Lock,Name    Bool      */
  313.     case ACTION_OPENNEW:    /* FileHandle,Lock,Name    Bool      */
  314.     tmp = CurrentDir(pkt->p_Arg[0]);
  315.     pkt->p_Res1 = Open((char *)&pkt->p_Arg[1]+1, pkt->p_Action);
  316.     pkt->p_Res2 = Proc->pr_Result2;
  317.     CurrentDir(tmp);
  318.     break;
  319.     case ACTION_CLOSE:    /* FHArg1            Bool:Success */
  320.     pkt->p_Res1 = Close(pkt->p_Arg[0]);
  321.     pkt->p_Res2 = Proc->pr_Result2;
  322.     break;
  323.     case ACTION_SEEK:    /* FHArg1,Position,Mode      OldPosition */
  324.     pkt->p_Res1 = Seek(pkt->p_Arg[0], pkt->p_Arg[1], pkt->p_Arg[2]);
  325.     pkt->p_Res2 = Proc->pr_Result2;
  326.     break;
  327. #ifdef notdef
  328.     case ACTION_FORMAT: /* vol,type            Bool:success */
  329.     break;
  330. #endif
  331.     case ACTION_MAKE_LINK: /* parent,name,target,mode       Bool      */
  332.     {
  333.         ULONG soft;
  334.  
  335.         tmp = CurrentDir(pkt->p_Arg[0]);
  336.         soft = pkt->p_Arg[1];
  337.         dumppkt(pkt);
  338.         if (soft) {
  339.         debug(("MakeLink soft '%s' -> '%s'\n",
  340.                SkipString((char *)&pkt->p_Arg[2])+1,
  341.                (char *)&pkt->p_Arg[2]+1));
  342. /*V37*/     pkt->p_Res1 = MakeLink(SkipString((char *)&pkt->p_Arg[2])+1,
  343.                        (ULONG)(char *)&pkt->p_Arg[2]+1,
  344.                        soft);
  345.         } else {
  346.         pkt->p_Res1 = MakeLink((char *)&pkt->p_Arg[3]+1,
  347.                        pkt->p_Arg[2],
  348.                        soft);
  349.         }
  350.         pkt->p_Res2 = Proc->pr_Result2;
  351.         CurrentDir(tmp);
  352.     }
  353.     break;
  354.     case ACTION_READ_LINK: /* parent,name,target,size       length    */
  355.     {
  356.         struct FileLock *fl;
  357.         ULONG        size;
  358.  
  359.         fl = BTOC(pkt->p_Arg[0]);
  360.         size = min(pkt->p_Arg[1], MAXDATA);
  361.  
  362. /*V37*/     pkt->p_Res1 = ReadLink(fl->fl_Task,
  363.                    pkt->p_Arg[0],
  364.                    (char *)&pkt->p_Arg[2]+1,
  365.                    (char *)&pkt->p_Data[0],
  366.                    size);
  367.         pkt->p_Res2 = Proc->pr_Result2;
  368.         if (pkt->p_Res1 >= 0)
  369.         replysize = STDREPLY + pkt->p_Res1;
  370.     }
  371.     break;
  372.     case ACTION_SET_FILE_SIZE:
  373. /*V37*/ pkt->p_Res1 = SetFileSize(pkt->p_Arg[0], pkt->p_Arg[1], pkt->p_Arg[2]);
  374.     pkt->p_Res2 = Proc->pr_Result2;
  375.     break;
  376. /*  case ACTION_WRITE_PROTECT: */
  377.     case ACTION_FH_FROM_LOCK: /* FH,Lock            BOOL     */
  378. /*V37*/ pkt->p_Res1 = OpenFromLock(pkt->p_Arg[0]);
  379.     pkt->p_Res2 = Proc->pr_Result2;
  380.     break;
  381.     case ACTION_CHANGE_MODE:
  382. /*V37*/ pkt->p_Res1 = ChangeMode(pkt->p_Arg[0], pkt->p_Arg[1], pkt->p_Arg[2]);
  383.     pkt->p_Res2 = Proc->pr_Result2;
  384.     break;
  385.     case ACTION_COPY_DIR_FH:    /* fh_Arg1           Lock      */
  386. /*V37*/ pkt->p_Res1 = DupLockFromFH(pkt->p_Arg[0]);
  387.     pkt->p_Res2 = Proc->pr_Result2;
  388.     break;
  389.     case ACTION_PARENT_FH:
  390. /*V37*/ pkt->p_Res1 = ParentOfFH(pkt->p_Arg[0]);
  391.     pkt->p_Res2 = Proc->pr_Result2;
  392.     break;
  393.     case ACTION_EXAMINE_FH:    /* fh_Arg1,Fib           Bool      */
  394.     {
  395.         struct FileHandle *fh;
  396.  
  397.         fh = (struct FileHandle *)BTOC(pkt->p_Arg[0]);
  398.         DosPkt->dp_Action = ACTION_EXAMINE_FH;
  399.         DosPkt->dp_Arg1 = fh->fh_Arg1;
  400.         DosPkt->dp_Arg2 = CTOB(&pkt->p_Data[0]);
  401.  
  402.         dopacket(DosPkt, fh->fh_Type);
  403.  
  404.         pkt->p_Res2 = DosPkt->dp_Res2;
  405.         if (pkt->p_Res1 = DosPkt->dp_Res1)
  406.         replysize = STDREPLY + sizeof(struct FileInfoBlock);
  407.     }
  408.     break;
  409.     case ACTION_LOCK_RECORD:    /* fh,pos,len,mode,time    Bool      */
  410.     {
  411.         struct DosPacket *dp;
  412.         struct FileHandle *fh;
  413.  
  414.         fh = (struct FileHandle *)BTOC(pkt->p_Arg[0]);
  415.         dp = CreateDosPkt(2*sizeof(long));
  416.         debug(("LOCK_RECORD %x, dp %x\n", fh, dp));
  417.         dp->dp_Action = ACTION_LOCK_RECORD;
  418.         dp->dp_Arg1 = fh->fh_Arg1;
  419.         dp->dp_Arg2 = pkt->p_Arg[1];
  420.         dp->dp_Arg3 = pkt->p_Arg[2];
  421.         dp->dp_Arg4 = pkt->p_Arg[3];
  422.         dp->dp_Arg5 = pkt->p_Arg[4];
  423.  
  424.         ((long *)dp)[-1] = pkt->p_Origin;
  425.         ((long *)dp)[-2] = pkt->p_Arg[5];     /* client cookie */
  426.  
  427.         doasyncpacket(dp, fh->fh_Type);
  428.     }
  429.     break;
  430.     case ACTION_FREE_RECORD:    /* fh,pos,len           Bool      */
  431. /*V37*/ pkt->p_Res1 = UnLockRecord(pkt->p_Arg[0], pkt->p_Arg[1], pkt->p_Arg[2]);
  432.     pkt->p_Res2 = Proc->pr_Result2;
  433.     break;
  434.     default:
  435.     pkt->p_Res1 = DOSFALSE;
  436.     pkt->p_Res2 = ERROR_ACTION_NOT_KNOWN;
  437.     break;
  438.     }
  439.  
  440.     debug(("res: %d err: %d\n", pkt->p_Res1, pkt->p_Res2));
  441.     DoReply(io, pkt, replysize);
  442. }
  443.  
  444. void
  445. HandleAsyncDosPkt(struct Message *msg)
  446. {
  447.     char        buf[STDREPLY + 2*sizeof(long)];
  448.     Packet       *p = buf;
  449.     struct DosPacket *dp = (struct DosPacket *)msg->mn_Node.ln_Name;
  450.  
  451.     debug(("HandleAsyncDosPkt(msg %x) dp %x res: %x/%d\n",
  452.        msg, dp, dp->dp_Res1, dp->dp_Res2));
  453.  
  454.     p->p_Res1 = dp->dp_Res1;
  455.     p->p_Res2 = dp->dp_Res2;
  456.     p->p_Data[0] = dp->dp_Action;
  457.  
  458.     switch (dp->dp_Action) {
  459.     case ACTION_LOCK_RECORD:
  460.     p->p_Origin  = ((long *)dp)[-1];
  461.     p->p_Data[1] = ((long *)dp)[-2];            /* client cookie */
  462.     break;
  463.     default:
  464.     debug(("Funny DOS packet returning %x %d\n", msg, dp->dp_Action));
  465.     goto end;
  466.     }
  467.  
  468.     DoReplyAsync(ParReq, p, sizeof(buf));
  469.     DeleteDosPkt(dp);
  470.  
  471. end:;
  472. }
  473.  
  474. /* ---------------------------------------------------------------------- */
  475.  
  476. Prototype void DoAsyncReply(Packet *pkt);
  477.  
  478. void
  479. DoAsyncReply(Packet *pkt)
  480. {
  481.     debug(("We're not supposed to get these!\n"));
  482. }
  483.  
  484.  
  485. /* ---------------------------------------------------------------------- */
  486.  
  487. ULONG
  488. InitServer(void)
  489. {
  490.     debug(("InitServer\n"));
  491.  
  492.     DosPkt = CreateDosPkt(0);
  493.     DosPort = CreatePort("NetServer DosPort", -1);
  494.     AsyncDosPort = CreatePort("NetServer AsyncDosPort", -1);
  495.  
  496.     WaitMask = 1L << RdPort->mp_SigBit |
  497.            1L << AsyncDosPort->mp_SigBit |
  498.            SIGBREAKF_CTRL_C;
  499.  
  500.     Proc = (struct Process *)FindTask(NULL);
  501.     pr_WindowPtr = Proc->pr_WindowPtr;
  502.     Proc->pr_WindowPtr = (void *)-1;
  503.  
  504.     return 0;
  505. }
  506.  
  507. void
  508. CleanupServer(void)
  509. {
  510.     debug(("CleanupServer\n"));
  511.     if (pr_WindowPtr != (void *)-2)
  512.     Proc->pr_WindowPtr = pr_WindowPtr;
  513.     if (DosPkt) {
  514.     DeleteDosPkt(DosPkt);
  515.     DosPkt = NULL;
  516.     }
  517. }
  518.  
  519. void
  520. ServeLoop(void)
  521. {
  522.     ULONG        sigs;
  523.  
  524.     while (1) {
  525.     debug(("ServeLoop: Wait ...\n"));
  526.     sigs = Wait(WaitMask);
  527.     {
  528.         struct Message *msg;
  529.  
  530.         while (msg = GetMsg(AsyncDosPort)) {
  531.         HandleAsyncDosPkt(msg);
  532.         }
  533.     }
  534.     if (sigs & SIGBREAKF_CTRL_C)
  535.         break;
  536.     {
  537.         struct IOParReq *io;
  538.         Packet       *pkt;
  539.  
  540.         while (io = (struct IOParReq *)GetMsg(RdPort)) {
  541.         pkt = ((struct IOStdReq *)io)->io_Data;
  542.         if (((struct IOStdReq *)io)->io_Error == 0)
  543.             HandleRequest(io, pkt);
  544.         else
  545.             DoReset(ParReq);
  546.         SendRead(io, pkt, PKTSIZE);
  547.         }
  548.     }
  549.     }
  550. }
  551.  
  552. /* ---------------------------------------------------------------------- */
  553.  
  554. int
  555. main(int argc, char **argv)
  556. {
  557.     int         c;
  558.  
  559. #ifdef DEBUG
  560.     initsyslog();
  561. #endif                /* DEBUG */
  562.  
  563.     if (DOSBase->dl_lib.lib_Version < 37) {
  564.     Write(Output(),
  565.         "You should upgrade to at least 2.0 as soon as possible!\n"
  566.         "If any client uses a 2.0+ packet, you will crash!\n", 106);
  567.     }
  568.  
  569.     /* Primary defaults */
  570.     MyAddr = SRV_ADDR;
  571.     PeerAddr = CLI_ADDR;
  572.     NetFSPort = NETFS_PORT;
  573.  
  574.     while ((c = getopt(argc, argv, "sd:u:f:p:a:c:")) != -1) {
  575.     switch (c) {
  576.     case 's':
  577.         /* Secundary server/client */
  578.         MyAddr = CLI_ADDR;
  579.         PeerAddr = SRV_ADDR;
  580.         NetFSPort = NETFS_PORT + 1;
  581.         break;
  582.     case 'd':
  583.         DevName = optarg;
  584.         break;
  585.     case 'u':
  586.         UnitNr = strtol(optarg, NULL, 0);
  587.         break;
  588.     case 'f':
  589.         DevFlags = strtol(optarg, NULL, 0);
  590.         break;
  591.     case 'p':
  592.         NetFSPort = strtol(optarg, NULL, 0);
  593.         break;
  594.     case 'a':
  595.         MyAddr = strtol(optarg, NULL, 0);
  596.         break;
  597.     case 'c':
  598.         PeerAddr = strtol(optarg, NULL, 0);
  599.         break;
  600.     case '?':
  601.         return 20;
  602.     }
  603.     }
  604.  
  605.     debug(("call OpenNetwork\n"));
  606.     if (OpenNetwork())
  607.     return 20;
  608.  
  609.     if (InitServer() == 0) {
  610.     ServeLoop();
  611.     CleanupServer();
  612.     }
  613.  
  614.     CloseNetwork();
  615. #ifdef DEBUG
  616.     uninitsyslog();
  617. #endif                /* DEBUG */
  618. }
  619.