home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 35 Internet / 35-Internet.zip / lpopper.zip / commands.c < prev    next >
C/C++ Source or Header  |  1999-11-09  |  37KB  |  1,051 lines

  1. #include "popper.h"
  2.  
  3. int Debug=0;
  4.  
  5. struct Letter  *mBox=NULL;
  6. long msgCount=0;
  7. long TotalLen=0;
  8. long uMsgCount=0;
  9. long uTotalLen=0;
  10. char PwdPath[512]="passwd";
  11. char BoxPath[512]=".\\";
  12.  
  13. static char UserName[9]={0};
  14. void CrashPack (void)
  15. { fprintf(stderr, "Session crashed for user %s, emergency packing mailbox\n", UserName);
  16.   PackBox(UserName, 0);
  17. }
  18.  
  19. int CheckUser(char * UserName)
  20. { struct Pwd Pw;
  21.  
  22.   strncpy(Pw.User, UserName, 16);
  23.   Pw.User[16]=0;
  24.  
  25.   if(ReadUser(&Pw, PwdPath)!=0) return(0);
  26.   if(Pw.Pass[0]=='*') return(0);
  27.  
  28.   return(1);
  29. }
  30. int CheckPass(char * User, char * Pass)
  31. { struct Pwd Pw;
  32.  
  33.   strncpy(Pw.User, User, 8);
  34.   Pw.User[16]=0;
  35.  
  36.   if(ReadUser(&Pw, PwdPath)!=0) return(0);
  37.   if(Pw.Pass[0]=='*') return(0);
  38.   if(strcmp(Pw.Pass, Pass)==0) return(1);
  39.  
  40.   return(0);
  41. }
  42.  
  43. int CheckBox (char * rBox, char * tBox)
  44. { long Len;
  45.   FILE *rFile, *tFile;
  46.  
  47.   if(access(tBox, 0)!=0) return(0);
  48.  
  49. /*move tFile(tBox) to rFile(rBox)*/
  50.  
  51.   tFile=_fsopen(tBox, "rb", SH_DENYRW);
  52.   if(tFile==NULL)
  53.     { perror("Can't open old temporary maildrop");
  54.       return(-1);
  55.     }
  56.  
  57.   rFile=_fsopen(rBox, "a+b", SH_DENYRW);
  58.   if(rFile==NULL)
  59.     { perror("Can't open maildrop");
  60.       fclose(tFile);
  61.       return(-1);
  62.     }
  63.  
  64.   fseek(rFile, 0, SEEK_END);
  65.   fseek(tFile, 0, SEEK_END);
  66.   Len=ftell(tFile);
  67.   fseek(tFile, 0, SEEK_SET);
  68.   if(Len<0)
  69.     { perror("Can't read temporary maildrop");
  70.       return(-1);
  71.     }
  72.       
  73. /*Appending from fFrom to end of fTo beginning from fFrom[From] to fFrom[To]*/
  74. /*int CopyBlock (FILE * fFrom, FILE * fTo, long From, long To)*/
  75.   if(CopyBlock(tFile, rFile, 0l, Len)!=0)
  76.     { perror("Can't append temporary mailbox to main maildrop : some mails wasted");
  77.     }
  78.   fclose(tFile);
  79.   fclose(rFile);
  80.   unlink(tBox);
  81.  
  82.   return(0);
  83. }
  84.  
  85.  
  86. /***************************************************************/
  87.  
  88. #define USERCMD "USER"
  89. #define PASSCMD "PASS"
  90. #define QUITCMD "QUIT"
  91. #define NOCMD   "NOOP"
  92. #define STATCMD "STAT"
  93. #define LISTCMD "LIST"
  94. #define RETRCMD "RETR"
  95. #define DELECMD "DELE"
  96. #define LASTCMD "LAST"
  97. #define RSETCMD "RSET"
  98. #define TOPCMD  "TOP"
  99. #define UIDLCMD "UIDL"
  100.  
  101. int DoCommand(int Socket)
  102. { char * Buffer;
  103.   char * Buffer2;
  104.   int Res;
  105.   char Password[19]={0};
  106.   FILE * fBox=NULL;
  107.   register unsigned long i;
  108.   long MsgNo, LastMsg=0;
  109.   char Ch;
  110.   int WasLF=0;
  111.   int WasCR=0;
  112.   int sRes;
  113.   signed int Lines;
  114.   char * Arg1;
  115.   char * Arg2;
  116.   int LoggedIn=0;
  117.  
  118.   Buffer=(char*)malloc(2048);
  119.   if(Buffer==NULL) return(-1);
  120.  
  121.   Buffer2=(char*)malloc(2048);
  122.   if(Buffer2==NULL)
  123.     { free(Buffer);
  124.       return(-1);
  125.     }
  126.  
  127.   sprintf(Buffer2, "+OK POP3 server glad to meet you here ;)\x0D\x0A"/*TimeStamp*/);
  128.   sRes=write(Socket, Buffer2, strlen(Buffer2));
  129.   if(sRes<0)
  130.     { free(Buffer);
  131.       free(Buffer2);
  132.       return(-1);
  133.     }
  134.  
  135.  
  136.  
  137.  
  138.  
  139. /*Aut.*/
  140.   memset(UserName, 0, 9);
  141.   do {
  142.  
  143. /*Waiting for USER command*/
  144.        do { sRes=SkGetS(Socket, Buffer);
  145.             if(sRes!=0)
  146.               { free(Buffer);
  147.                 free(Buffer2);
  148.                 if(fBox) fclose(fBox);
  149.                 return(-1);
  150.               }
  151.             DelEndCRLF(Buffer);
  152.             DelSpaces(Buffer);
  153.  
  154.             if(memicmp(Buffer, USERCMD, strlen(USERCMD))==0)
  155.               { DelSpaces(&Buffer[strlen(USERCMD)]);
  156.                 strncpy(UserName, &Buffer[strlen(USERCMD)], 16);
  157.                 UserName[16]=0;
  158.                 if(CheckUser(UserName))
  159.                   { sprintf(Buffer2, "+OK Hello, %s! Please remember your password!\x0D\x0A", UserName);
  160.                     sRes=write(Socket, Buffer2, strlen(Buffer2));
  161.                     if(sRes<0)
  162.                       { free(Buffer);
  163.                         free(Buffer2);
  164.                         return(-1);
  165.                       }
  166.                   }
  167.                  else
  168.                   { sprintf(Buffer2, "-ERR Don't know who is %s\x0D\x0A", UserName);
  169.                     sRes=write(Socket, Buffer2, strlen(Buffer2));
  170.                     if(sRes<0)
  171.                       { free(Buffer);
  172.                         free(Buffer2);
  173.                         return(-1);
  174.                       }
  175.                     UserName[0]=0;
  176.                     continue;
  177.                   }
  178.                 break;
  179.               }
  180.             if(memicmp(Buffer, QUITCMD, strlen(QUITCMD))==0)
  181.               { sprintf(Buffer2, "+OK POP3 server signing off\x0D\x0A");
  182.                 sRes=write(Socket, Buffer2, strlen(Buffer2));
  183.                 if(sRes<0)
  184.                   { free(Buffer);
  185.                     free(Buffer2);
  186.                     return(-1);
  187.                   }
  188.                 break;
  189.               }
  190.             sprintf(Buffer2, "-ERR Don't know how to do \"%s\"\x0D\x0A", Buffer);
  191.             sRes=write(Socket, Buffer2, strlen(Buffer2));
  192.             if(sRes<0)
  193.               { free(Buffer);
  194.                 free(Buffer2);
  195.                 return(-1);
  196.               }
  197.  
  198.           } while(1);
  199.        if(memicmp(Buffer, QUITCMD, strlen(QUITCMD))==0) return(0);
  200.  
  201.  
  202.  
  203.  
  204.  
  205.  
  206.  
  207.  
  208.  
  209. /*Get password and check it*/
  210.        LoggedIn=0;
  211.        sRes=SkGetS(Socket, Buffer);
  212.        if(sRes!=0)
  213.          { free(Buffer);
  214.            free(Buffer2);
  215.            if(fBox) fclose(fBox);
  216.            return(-1);
  217.          }
  218.        DelEndCRLF(Buffer);
  219.        DelSpaces(Buffer);
  220.      
  221.        if(memicmp(Buffer, PASSCMD, strlen(PASSCMD))==0)
  222.          { DelSpaces(&Buffer[strlen(PASSCMD)]);
  223.            strncpy(Password, &Buffer[strlen(PASSCMD)], 16);
  224.            Password[16]=0;
  225.            if(!CheckPass(UserName, Password))
  226.              { sprintf(Buffer2, "-ERR Login failed\x0D\x0A");
  227.                sRes=write(Socket, Buffer2, strlen(Buffer2));
  228.                if(sRes<0)
  229.                  { free(Buffer);
  230.                    free(Buffer2);
  231.                    return(-1);
  232.                  }
  233.  
  234.                Password[0]=0;
  235.                UserName[0]=0;
  236.                continue;
  237.              }
  238.             else
  239.              { sprintf(Buffer,  "%s%s",    BoxPath, UserName);
  240.                sprintf(Buffer2, "%s%s.mb", BoxPath, UserName);
  241.  
  242. /*Check previous box if any*/
  243.                CheckBox (Buffer, Buffer2);
  244.  
  245. /*Open mailbox*/
  246.                if(rename(Buffer, Buffer2)<0)
  247.                  { sprintf(Buffer2, "-ERR Can't open maildrop for %s\x0D\x0A", UserName);
  248.                    sRes=write(Socket, Buffer2, strlen(Buffer2));
  249.                    if(sRes<0)
  250.                      { free(Buffer);
  251.                        free(Buffer2);
  252.                        return(-1);
  253.                      }
  254.  
  255.                    strcpy(Buffer, QUITCMD);
  256.                    break;
  257.                  }
  258.                
  259.                fBox=_fsopen(Buffer, "w+b", SH_DENYRW);
  260.                if(fBox==NULL)
  261.                  { sprintf(Buffer2, "-ERR Can't clear maildrop for %s\x0D\x0A", UserName);
  262.                    sRes=write(Socket, Buffer2, strlen(Buffer2));
  263.                    if(sRes<0)
  264.                      { free(Buffer);
  265.                        free(Buffer2);
  266.                        return(-1);
  267.                      }
  268.  
  269.                    strcpy(Buffer, QUITCMD);
  270.                    break;
  271.                  }
  272.                fclose(fBox);
  273.                fBox=_fsopen(Buffer2, "r+b", SH_DENYRW);
  274.                if(fBox==NULL)
  275.                  { sprintf(Buffer2, "-ERR Can't open maildrop for %s\x0D\x0A", UserName);
  276.                    sRes=write(Socket, Buffer2, strlen(Buffer2));
  277.                    if(sRes<0)
  278.                      { free(Buffer);
  279.                        free(Buffer2);
  280.                        return(-1);
  281.                      }
  282.  
  283.                    strcpy(Buffer, QUITCMD);
  284.                    break;
  285.                  }
  286.                sRes=RescanBox(fBox);
  287.                if(sRes)
  288.                  { sprintf(Buffer2, "-ERR Can't process maildrop for %s\x0D\x0A", UserName);
  289.                    sRes=write(Socket, Buffer2, strlen(Buffer2));
  290.                    if(sRes<0)
  291.                      { free(Buffer);
  292.                        free(Buffer2);
  293.                        if(fBox) fclose(fBox);
  294.                        return(-1);
  295.                      }
  296.  
  297.                    strcpy(Buffer, QUITCMD);
  298.                    break;
  299.                  }
  300.                signal(SIGHUP,   (void*)&CrashPack);
  301.                signal(SIGINT,   (void*)&CrashPack);
  302.                signal(SIGQUIT,  (void*)&CrashPack);
  303.                signal(SIGILL,   (void*)&CrashPack);
  304.                signal(SIGTRAP,  (void*)&CrashPack);
  305.                signal(SIGABRT,  (void*)&CrashPack);
  306.                signal(SIGEMT,   (void*)&CrashPack);
  307.                signal(SIGFPE,   (void*)&CrashPack);
  308.                signal(SIGBUS,   (void*)&CrashPack);
  309.                signal(SIGSEGV,  (void*)&CrashPack);
  310.                signal(SIGSYS,   (void*)&CrashPack);
  311.                signal(SIGPIPE,  (void*)&CrashPack);
  312.                signal(SIGTERM,  (void*)&CrashPack);
  313.                signal(SIGBREAK, (void*)&CrashPack);
  314.                sprintf(Buffer2, "+OK %s's maildrop has %lu messages (%lu octets)\x0D\x0A", UserName, uMsgCount, uTotalLen);
  315.                sRes=write(Socket, Buffer2, strlen(Buffer2));
  316.                if(sRes<0)
  317.                  { free(Buffer);
  318.                    free(Buffer2);
  319.                    if(fBox) fclose(fBox);
  320.                    return(-1);
  321.                  }
  322.                LoggedIn=1;
  323.              }
  324.            break;
  325.          }
  326.        if(memicmp(Buffer, QUITCMD, strlen(QUITCMD))==0)
  327.          { sprintf(Buffer2, "+OK POP3 server signing off\x0D\x0A");
  328.            sRes=write(Socket, Buffer2, strlen(Buffer2));
  329.            if(sRes<0)
  330.              { free(Buffer);
  331.                free(Buffer2);
  332.                if(fBox) fclose(fBox);
  333.                return(-1);
  334.              }
  335.            break;
  336.          }
  337.        sprintf(Buffer2, "-ERR Don't know how to do \"%s\"\x0D\x0A", Buffer);
  338.        sRes=write(Socket, Buffer2, strlen(Buffer2));
  339.        if(sRes<0)
  340.          { free(Buffer);
  341.            free(Buffer2);
  342.            if(fBox) fclose(fBox);
  343.            return(-1);
  344.          }
  345.      } while(LoggedIn==0);
  346.   if(memicmp(Buffer, QUITCMD, strlen(QUITCMD))==0) return(0);
  347.  
  348.  
  349.  
  350.  
  351.  
  352.  
  353.  
  354.  
  355.  
  356.  
  357.  
  358.  
  359.  
  360.  
  361. /*Transaction state*/
  362.  
  363.   do { sRes=SkGetS(Socket, Buffer);
  364.        if(sRes!=0)
  365.          { free(Buffer);
  366.            free(Buffer2);
  367.            if(fBox) fclose(fBox);
  368.            PackBox(UserName, 0);
  369.            return(-1);
  370.          }
  371.        DelEndCRLF(Buffer);
  372.        DelSpaces(Buffer);
  373.  
  374.  
  375.  
  376. /*NOOP*/
  377.        if(memicmp(Buffer, NOCMD, strlen(NOCMD))==0)
  378.          { sprintf(Buffer2, "+OK It was so hard, but i've done it!\x0D\x0A");
  379.            sRes=write(Socket, Buffer2, strlen(Buffer2));
  380.            if(sRes<0)
  381.              { free(Buffer);
  382.                free(Buffer2);
  383.                if(fBox) fclose(fBox);
  384.                PackBox(UserName, 0);
  385.                return(-1);
  386.              }
  387.            continue;
  388.          }
  389.  
  390.  
  391.  
  392. /*STAT*/
  393.        if(memicmp(Buffer, STATCMD, strlen(STATCMD))==0)
  394.          { sprintf(Buffer2, "+OK %lu %lu\x0D\x0A", uMsgCount, uTotalLen);
  395.            sRes=write(Socket, Buffer2, strlen(Buffer2));
  396.            if(sRes<0)
  397.              { free(Buffer);
  398.                free(Buffer2);
  399.                if(fBox) fclose(fBox);
  400.                PackBox(UserName, 0);
  401.                return(-1);
  402.              }
  403.            continue;
  404.          }
  405.  
  406.  
  407.  
  408. /*LIST*/
  409.        if(memicmp(Buffer, LISTCMD, strlen(LISTCMD))==0)
  410.          { DelSpaces(&Buffer[strlen(LISTCMD)]);
  411.            if(IsEmpty(&Buffer[strlen(LISTCMD)]))
  412.              { sprintf(Buffer2, "+OK %lu messages (%lu octets)\x0D\x0A", uMsgCount, uTotalLen);
  413.                sRes=write(Socket, Buffer2, strlen(Buffer2));
  414.                if(sRes<0)
  415.                  { free(Buffer);
  416.                    free(Buffer2);
  417.                    if(fBox) fclose(fBox);
  418.                    PackBox(UserName, 0);
  419.                    return(-1);
  420.                  }
  421.                for(i=0;i<msgCount;i++)
  422.                 { if(mBox[i].Deleted) continue;
  423.                   sprintf(Buffer2, "%lu %lu\x0D\x0A", i+1, mBox[i].Size);
  424.                   sRes=write(Socket, Buffer2, strlen(Buffer2));
  425.                   if(sRes<0)
  426.                     { free(Buffer);
  427.                       free(Buffer2);
  428.                       if(fBox) fclose(fBox);
  429.                       PackBox(UserName, 0);
  430.                       return(-1);
  431.                     }
  432.                 }
  433.                sprintf(Buffer2, ".\x0D\x0A");
  434.                sRes=write(Socket, Buffer2, strlen(Buffer2));
  435.                if(sRes<0)
  436.                  { free(Buffer);
  437.                    free(Buffer2);
  438.                    if(fBox) fclose(fBox);
  439.                    PackBox(UserName, 0);
  440.                    return(-1);
  441.                  }
  442.              }
  443.             else
  444.              { MsgNo=atol(&Buffer[strlen(LISTCMD)])-1;
  445.                if((MsgNo>=msgCount) || (MsgNo<0))
  446.                  { sprintf(Buffer2, "-ERR no such message as %ld, just %lu messages in maildrop\x0D\x0A", MsgNo+1, msgCount);
  447.                    sRes=write(Socket, Buffer2, strlen(Buffer2));
  448.                    if(sRes<0)
  449.                      { free(Buffer);
  450.                        free(Buffer2);
  451.                        if(fBox) fclose(fBox);
  452.                        PackBox(UserName, 0);
  453.                        return(-1);
  454.                      }
  455.                  }
  456.                 else
  457.                  { if(mBox[MsgNo].Deleted)
  458.                      { sprintf(Buffer2, "-ERR Message %lu was killed\x0D\x0A", MsgNo+1);
  459.                        sRes=write(Socket, Buffer2, strlen(Buffer2));
  460.                        if(sRes<0)
  461.                          { free(Buffer);
  462.                            free(Buffer2);
  463.                            if(fBox) fclose(fBox);
  464.                            PackBox(UserName, 0);
  465.                            return(-1);
  466.                          }
  467.                      }
  468.                     else
  469.                      { sprintf(Buffer2, "+OK %lu %lu\x0D\x0A", MsgNo+1, mBox[MsgNo].Size);
  470.                        sRes=write(Socket, Buffer2, strlen(Buffer2));
  471.                        if(sRes<0)
  472.                          { free(Buffer);
  473.                            free(Buffer2);
  474.                            if(fBox) fclose(fBox);
  475.                            PackBox(UserName, 0);
  476.                            return(-1);
  477.                          }
  478.                        LastMsg=MsgNo+1;
  479.                      }
  480.                  }
  481.              }
  482.            continue;
  483.          }
  484.  
  485.  
  486.  
  487.  
  488.  
  489. /*UIDL*/
  490.        if(memicmp(Buffer, UIDLCMD, strlen(UIDLCMD))==0)
  491.          { DelSpaces(&Buffer[strlen(UIDLCMD)]);
  492.            if(IsEmpty(&Buffer[strlen(UIDLCMD)]))
  493.              { sprintf(Buffer2, "+OK There's message's names\x0D\x0A");
  494.                sRes=write(Socket, Buffer2, strlen(Buffer2));
  495.                if(sRes<0)
  496.                  { free(Buffer);
  497.                    free(Buffer2);
  498.                    if(fBox) fclose(fBox);
  499.                    PackBox(UserName, 0);
  500.                    return(-1);
  501.                  }
  502.                for(i=0;i<msgCount;i++)
  503.                 { if(mBox[i].Deleted) continue;
  504.                   sprintf(Buffer2, "%lu %s\x0D\x0A", i+1, mBox[i].msgID);
  505.  
  506.                   sRes=write(Socket, Buffer2, strlen(Buffer2));
  507.                   if(sRes<0)
  508.                     { free(Buffer);
  509.                       free(Buffer2);
  510.                       if(fBox) fclose(fBox);
  511.                       PackBox(UserName, 0);
  512.                       return(-1);
  513.                     }
  514.                 }
  515.                sprintf(Buffer2, ".\x0D\x0A");
  516.                sRes=write(Socket, Buffer2, strlen(Buffer2));
  517.                if(sRes<0)
  518.                  { free(Buffer);
  519.                    free(Buffer2);
  520.                    if(fBox) fclose(fBox);
  521.                    PackBox(UserName, 0);
  522.                    return(-1);
  523.                  }
  524.              }
  525.             else
  526.              { MsgNo=atol(&Buffer[strlen(LISTCMD)])-1;
  527.                if((MsgNo>=msgCount) || (MsgNo<0))
  528.                  { sprintf(Buffer2, "-ERR no such message as %ld, just %lu messages in maildrop\x0D\x0A", MsgNo+1, msgCount);
  529.                    sRes=write(Socket, Buffer2, strlen(Buffer2));
  530.                    if(sRes<0)
  531.                      { free(Buffer);
  532.                        free(Buffer2);
  533.                        if(fBox) fclose(fBox);
  534.                        PackBox(UserName, 0);
  535.                        return(-1);
  536.                      }
  537.                  }
  538.                 else
  539.                  { if(mBox[MsgNo].Deleted)
  540.                      { sprintf(Buffer2, "-ERR Message %lu was killed\x0D\x0A", MsgNo+1);
  541.                        sRes=write(Socket, Buffer2, strlen(Buffer2));
  542.                        if(sRes<0)
  543.                          { free(Buffer);
  544.                            free(Buffer2);
  545.                            if(fBox) fclose(fBox);
  546.                            PackBox(UserName, 0);
  547.                            return(-1);
  548.                          }
  549.                      }
  550.                     else
  551.                      { sprintf(Buffer2, "+OK %lu %s\x0D\x0A", MsgNo+1, mBox[MsgNo].msgID);
  552.                        sRes=write(Socket, Buffer2, strlen(Buffer2));
  553.                        if(sRes<0)
  554.                          { free(Buffer);
  555.                            free(Buffer2);
  556.                            if(fBox) fclose(fBox);
  557.                            PackBox(UserName, 0);
  558.                            return(-1);
  559.                          }
  560.                        LastMsg=MsgNo+1;
  561.                      }
  562.                  }
  563.              }
  564.            continue;
  565.          }
  566.  
  567.  
  568.  
  569.  
  570. /*RETR*/
  571.        if(memicmp(Buffer, RETRCMD, strlen(RETRCMD))==0)
  572.          { DelSpaces(&Buffer[strlen(RETRCMD)]);
  573.            if(IsEmpty(&Buffer[strlen(RETRCMD)]))
  574.              { sprintf(Buffer2, "-ERR Don't know which message you want :~(\x0D\x0A");
  575.                sRes=write(Socket, Buffer2, strlen(Buffer2));
  576.                if(sRes<0)
  577.                  { free(Buffer);
  578.                    free(Buffer2);
  579.                    if(fBox) fclose(fBox);
  580.                    PackBox(UserName, 0);
  581.                    return(-1);
  582.                  }
  583.              }
  584.             else
  585.              { MsgNo=atol(&Buffer[strlen(LISTCMD)])-1;
  586.                if((MsgNo>=msgCount) || (MsgNo<0))
  587.                  { sprintf(Buffer2, "-ERR no such message as %ld, just %lu messages in maildrop\x0D\x0A", MsgNo+1, msgCount);
  588.                    sRes=write(Socket, Buffer2, strlen(Buffer2));
  589.                    if(sRes<0)
  590.                      { free(Buffer);
  591.                        free(Buffer2);
  592.                        if(fBox) fclose(fBox);
  593.                        PackBox(UserName, 0);
  594.                        return(-1);
  595.                      }
  596.                  }
  597.                 else
  598.                  { if(mBox[MsgNo].Deleted)
  599.                      { sprintf(Buffer2, "-ERR Message %lu was killed\x0D\x0A", MsgNo+1);
  600.                        sRes=write(Socket, Buffer2, strlen(Buffer2));
  601.                        if(sRes<0)
  602.                          { free(Buffer);
  603.                            free(Buffer2);
  604.                            if(fBox) fclose(fBox);
  605.                            PackBox(UserName, 0);
  606.                            return(-1);
  607.                          }
  608.                      }
  609.                     else
  610.                      { sprintf(Buffer2, "+OK %u message's lines follow\x0D\x0A", mBox[MsgNo].Lines);
  611.                        sRes=write(Socket, Buffer2, strlen(Buffer2));
  612.                        if(sRes<0)
  613.                          { free(Buffer);
  614.                            free(Buffer2);
  615.                            if(fBox) fclose(fBox);
  616.                            PackBox(UserName, 0);
  617.                            return(-1);
  618.                          }
  619.                        fseek(fBox, mBox[MsgNo].Begin, SEEK_SET);
  620.                        WasLF=0;
  621.                        WasCR=0;
  622.                        for(i=mBox[MsgNo].Begin;i<=mBox[MsgNo].End;i++)
  623.                         { if(fread(&Ch, 1, 1, fBox)!=1) break;
  624.  
  625.                           if(Ch==0x0A)
  626.                             { if(!WasCR)
  627.                                 { sprintf(Buffer2, "\x0D");
  628.                                   sRes=write(Socket, Buffer2, strlen(Buffer2));
  629.                                   if(sRes<0)
  630.                                     { free(Buffer);
  631.                                       free(Buffer2);
  632.                                       if(fBox) fclose(fBox);
  633.                                       PackBox(UserName, 0);
  634.                                       return(-1);
  635.                                     }
  636.                                 }
  637.                             }
  638.                           if(Ch==0x0D) WasCR=1;
  639.                            else WasCR=0;
  640.  
  641.                           if((WasLF) && (Ch=='.'))
  642.                             { sprintf(Buffer2, ".");
  643.                               sRes=write(Socket, Buffer2, strlen(Buffer2));
  644.                               if(sRes<0)
  645.                                 { free(Buffer);
  646.                                   free(Buffer2);
  647.                                   if(fBox) fclose(fBox);
  648.                                   PackBox(UserName, 0);
  649.                                   return(-1);
  650.                                 }
  651.                             }
  652.                           if(mBox[MsgNo].Is866)
  653.                             { if(i==mBox[MsgNo].cBeg)
  654.                                 { 
  655.                                   sprintf(Buffer2, "Content-Type: text/plain; charset=koi8-r\x0D\x0A");
  656.                                   i=mBox[MsgNo].cEnd;
  657.                                   fseek(fBox, i, SEEK_SET);
  658.                                   /*i--;*/
  659.                                 }
  660.                                else
  661.                                 { sprintf(Buffer2, "%c", cDOS2KOI(Ch));
  662.                                 }
  663.                             }
  664.                            else 
  665.                             { if(mBox[MsgNo].NoCharset)
  666.                                 { if(i==mBox[MsgNo].hEnd)
  667.                                     { 
  668.                                       sprintf(Buffer2, "Content-Type: text/plain; charset=koi8-r\x0D\x0A");
  669.                                       sRes=write(Socket, Buffer2, strlen(Buffer2));
  670.                                       if(sRes<0)
  671.                                         { free(Buffer);
  672.                                           free(Buffer2);
  673.                                           if(fBox) fclose(fBox);
  674.                                           PackBox(UserName, 0);
  675.                                           return(-1);
  676.                                         }
  677.                                     }
  678.                                 }
  679.                               sprintf(Buffer2, "%c", Ch);
  680.                             }
  681.                           sRes=write(Socket, Buffer2, strlen(Buffer2));
  682.                           if(sRes<0)
  683.                             { free(Buffer);
  684.                               free(Buffer2);
  685.                               if(fBox) fclose(fBox);
  686.                               PackBox(UserName, 0);
  687.                               return(-1);
  688.                             }
  689.                           if((Ch==0x0D) || (Ch==0x0A)) WasLF=1;
  690.                            else WasLF=0;
  691.                         }
  692.  
  693.                        if(!WasLF && mBox[MsgNo].Lines)
  694.                          { /*printf("Last - not CRLF, adding\n");*/
  695.                            sprintf(Buffer2, "\x0D\x0A");
  696.                            sRes=write(Socket, Buffer2, strlen(Buffer2));
  697.                            if(sRes<0)
  698.                              { free(Buffer);
  699.                                free(Buffer2);
  700.                                if(fBox) fclose(fBox);
  701.                                PackBox(UserName, 0);
  702.                                return(-1);
  703.                              }
  704.                          }
  705.                        sprintf(Buffer2, ".\x0D\x0A");
  706.                        sRes=write(Socket, Buffer2, strlen(Buffer2));
  707.                        if(sRes<0)
  708.                          { free(Buffer);
  709.                            free(Buffer2);
  710.                            if(fBox) fclose(fBox);
  711.                            PackBox(UserName, 0);
  712.                            return(-1);
  713.                          }
  714.                        mBox[MsgNo].Status=ROld;
  715.                        LastMsg=MsgNo+1;
  716.                      }
  717.                  }
  718.              }
  719.            continue;
  720.          }
  721.  
  722.  
  723.  
  724. /*TOP*/
  725.  
  726.        if(memicmp(Buffer, TOPCMD, strlen(TOPCMD))==0)
  727.          { Lines=0;
  728.            MsgNo=0;
  729.            Arg1=&Buffer[strlen(TOPCMD)];
  730.            DelSpaces(Arg1);
  731.            for(i=0;i<strlen(Arg1);i++)
  732.             { if(IsSpace(Arg1[i])) break;
  733.             }
  734.            if(Arg1[i]==0) 
  735.              { Arg2=&Arg1[i];
  736.              }
  737.             else
  738.              { Arg2=&Arg1[i+1];
  739.                Arg1[i]=0;
  740.              }
  741.            DelSpaces(Arg1);
  742.            DelSpaces(Arg2);
  743.            MsgNo=atol(Arg1)-1;
  744.            Lines=atoi(Arg2);
  745.  
  746.            if(IsEmpty(Arg1))
  747.              { sprintf(Buffer2, "-ERR Don't know which message you want :~(\x0D\x0A");
  748.                sRes=write(Socket, Buffer2, strlen(Buffer2));
  749.                if(sRes<0)
  750.                  { free(Buffer);
  751.                    free(Buffer2);
  752.                    if(fBox) fclose(fBox);
  753.                    PackBox(UserName, 0);
  754.                    return(-1);
  755.                  }
  756.              }
  757.             else
  758.              { if((MsgNo>=msgCount) || (MsgNo<0))
  759.                  { sprintf(Buffer2, "-ERR no such message as %ld, just %lu messages in maildrop\x0D\x0A", MsgNo+1, msgCount);
  760.                    sRes=write(Socket, Buffer2, strlen(Buffer2));
  761.                    if(sRes<0)
  762.                      { free(Buffer);
  763.                        free(Buffer2);
  764.                        if(fBox) fclose(fBox);
  765.                        PackBox(UserName, 0);
  766.                        return(-1);
  767.                      }
  768.                  }
  769.                 else
  770.                  { if(mBox[MsgNo].Deleted)
  771.                      { sprintf(Buffer2, "-ERR Message %lu was killed\x0D\x0A", MsgNo+1);
  772.                        sRes=write(Socket, Buffer2, strlen(Buffer2));
  773.                        if(sRes<0)
  774.                          { free(Buffer);
  775.                            free(Buffer2);
  776.                            if(fBox) fclose(fBox);
  777.                            PackBox(UserName, 0);
  778.                            return(-1);
  779.                          }
  780.                      }
  781.                     else
  782.                      { if(Lines<0)
  783.                          { sprintf(Buffer2, "-ERR Value %d is invalid for lines count\x0D\x0A", Lines);
  784.                            sRes=write(Socket, Buffer2, strlen(Buffer2));
  785.                            if(sRes<0)
  786.                              { free(Buffer);
  787.                                free(Buffer2);
  788.                                if(fBox) fclose(fBox);
  789.                                PackBox(UserName, 0);
  790.                                return(-1);
  791.                              }
  792.                          }
  793.                         else
  794.                          { if(Lines>mBox[MsgNo].Lines) Lines=mBox[MsgNo].Lines;
  795.  
  796.                            sprintf(Buffer2, "+OK %u message's lines follow\x0D\x0A", Lines);
  797.                            sRes=write(Socket, Buffer2, strlen(Buffer2));
  798.                            if(sRes<0)
  799.                              { free(Buffer);
  800.                                free(Buffer2);
  801.                                if(fBox) fclose(fBox);
  802.                                PackBox(UserName, 0);
  803.                                return(-1);
  804.                              }
  805.                            fseek(fBox, mBox[MsgNo].Begin, SEEK_SET);
  806.                            WasLF=0;
  807.                            
  808.                            for(i=mBox[MsgNo].Begin;i<=mBox[MsgNo].End;i++)
  809.                             { if(fread(&Ch, 1, 1, fBox)!=1) break;
  810.                               if((WasLF) && (Ch=='.'))
  811.                                 { sprintf(Buffer2, ".");
  812.                                   sRes=write(Socket, Buffer2, strlen(Buffer2));
  813.                                   if(sRes<0)
  814.                                     { free(Buffer);
  815.                                       free(Buffer2);
  816.                                       if(fBox) fclose(fBox);
  817.                                       PackBox(UserName, 0);
  818.                                       return(-1);
  819.                                     }
  820.                                 }
  821.                               if(mBox[MsgNo].Is866)
  822.                                 { if(i==mBox[MsgNo].cBeg)
  823.                                     { 
  824.                                       sprintf(Buffer2, "Content-Type: text/plain; charset=koi8-r\x0D\x0A");
  825.                                       i=mBox[MsgNo].cEnd;
  826.                                       fseek(fBox, i, SEEK_SET);
  827.                                       /*i--;*/
  828.                                     }
  829.                                    else
  830.                                     { sprintf(Buffer2, "%c", cDOS2KOI(Ch));
  831.                                     }
  832.                                 }
  833.                                else 
  834.                                 { if(mBox[MsgNo].NoCharset)
  835.                                     { if(i==mBox[MsgNo].hEnd)
  836.                                         { 
  837.                                           sprintf(Buffer2, "Content-Type: text/plain; charset=koi8-r\x0D\x0A");
  838.                                           sRes=write(Socket, Buffer2, strlen(Buffer2));
  839.                                           if(sRes<0)
  840.                                             { free(Buffer);
  841.                                               free(Buffer2);
  842.                                               if(fBox) fclose(fBox);
  843.                                               PackBox(UserName, 0);
  844.                                               return(-1);
  845.                                             }
  846.                                         }
  847.                                     }
  848.                                   sprintf(Buffer2, "%c", Ch);
  849.                                 }
  850.                               sRes=write(Socket, Buffer2, strlen(Buffer2));
  851.                               if(sRes<0)
  852.                                 { free(Buffer);
  853.                                   free(Buffer2);
  854.                                   if(fBox) fclose(fBox);
  855.                                   PackBox(UserName, 0);
  856.                                   return(-1);
  857.                                 }
  858.                               if(Ch==0x0A) 
  859.                                 { WasLF=1;
  860.                                   if(i>mBox[MsgNo].hEnd) 
  861.                                     { Lines--;
  862.                                     }
  863.                                 }
  864.                                else 
  865.                                 { WasLF=0;
  866.                                 }
  867.                               if((Lines<0) && (i>mBox[MsgNo].hEnd)) break;
  868.                             }
  869.                            if(!WasLF)
  870.                              { sprintf(Buffer2, "\x0D\x0A");
  871.                                sRes=write(Socket, Buffer2, strlen(Buffer2));
  872.                                if(sRes<0)
  873.                                  { free(Buffer);
  874.                                    free(Buffer2);
  875.                                    if(fBox) fclose(fBox);
  876.                                    PackBox(UserName, 0);
  877.                                    return(-1);
  878.                                  }
  879.                              }
  880.                            sprintf(Buffer2, ".\x0D\x0A");
  881.                            sRes=write(Socket, Buffer2, strlen(Buffer2));
  882.                            if(sRes<0)
  883.                              { free(Buffer);
  884.                                free(Buffer2);
  885.                                if(fBox) fclose(fBox);
  886.                                PackBox(UserName, 0);
  887.                                return(-1);
  888.                              }
  889.                            mBox[MsgNo].Status=ROld;
  890.                            LastMsg=MsgNo+1;
  891.                          }
  892.                      }
  893.                  }
  894.              }
  895.            continue;
  896.          }
  897.  
  898.  
  899.  
  900. /*DELE*/
  901.        if(memicmp(Buffer, DELECMD, strlen(DELECMD))==0)
  902.          { DelSpaces(&Buffer[strlen(DELECMD)]);
  903.            if(IsEmpty(&Buffer[strlen(DELECMD)]))
  904.              { sprintf(Buffer2, "-ERR Don't know which message you want to delete\x0D\x0A");
  905.                sRes=write(Socket, Buffer2, strlen(Buffer2));
  906.                if(sRes<0)
  907.                  { free(Buffer);
  908.                    free(Buffer2);
  909.                    if(fBox) fclose(fBox);
  910.                    PackBox(UserName, 0);
  911.                    return(-1);
  912.                  }
  913.              }
  914.             else
  915.              { MsgNo=atol(&Buffer[strlen(LISTCMD)])-1;
  916.                if((MsgNo>=msgCount) || (MsgNo<0))
  917.                  { sprintf(Buffer2, "-ERR no such message as %ld, just %lu messages in maildrop\x0D\x0A", MsgNo, msgCount);
  918.                    sRes=write(Socket, Buffer2, strlen(Buffer2));
  919.                    if(sRes<0)
  920.                      { free(Buffer);
  921.                        free(Buffer2);
  922.                        if(fBox) fclose(fBox);
  923.                        PackBox(UserName, 0);
  924.                        return(-1);
  925.                      }
  926.                  }
  927.                 else
  928.                  { if(mBox[MsgNo].Deleted)
  929.                      { sprintf(Buffer2, "-ERR Pervert! You can't kill one message twice\x0D\x0A");
  930.                        sRes=write(Socket, Buffer2, strlen(Buffer2));
  931.                        if(sRes<0)
  932.                          { free(Buffer);
  933.                            free(Buffer2);
  934.                            if(fBox) fclose(fBox);
  935.                            PackBox(UserName, 0);
  936.                            return(-1);
  937.                          }
  938.                      }
  939.                     else
  940.                      { sprintf(Buffer2, "+OK message %lu killed\x0D\x0A", MsgNo+1);
  941.                        sRes=write(Socket, Buffer2, strlen(Buffer2));
  942.                        if(sRes<0)
  943.                          { free(Buffer);
  944.                            free(Buffer2);
  945.                            if(fBox) fclose(fBox);
  946.                            PackBox(UserName, 0);
  947.                            return(-1);
  948.                          }
  949.                        mBox[MsgNo].Deleted=1;
  950.                        uMsgCount--;
  951.                        uTotalLen-=mBox[MsgNo].Size;
  952.                      }
  953.                  }
  954.              }
  955.            continue;
  956.          }
  957.  
  958.  
  959.  
  960. /*LAST*/
  961.        if(memicmp(Buffer, LASTCMD, strlen(LASTCMD))==0)
  962.          { if(mBox[LastMsg-1].Deleted) LastMsg=0;
  963.            if(LastMsg>msgCount) LastMsg=0;
  964.            sprintf(Buffer2, "+OK %lu\x0D\x0A", LastMsg);
  965.            sRes=write(Socket, Buffer2, strlen(Buffer2));
  966.            if(sRes<0)
  967.              { free(Buffer);
  968.                free(Buffer2);
  969.                if(fBox) fclose(fBox);
  970.                PackBox(UserName, 0);
  971.                return(-1);
  972.              }
  973.            continue;
  974.          }
  975.  
  976.  
  977.  
  978. /*RSET*/
  979.        if(memicmp(Buffer, RSETCMD, strlen(RSETCMD))==0)
  980.          { for(i=0;i<msgCount;i++)
  981.             mBox[i].Deleted=0;
  982.            uMsgCount=msgCount;
  983.            uTotalLen=TotalLen;
  984.  
  985.            sprintf(Buffer2, "+OK All changes was lost\x0D\x0A");
  986.            sRes=write(Socket, Buffer2, strlen(Buffer2));
  987.            if(sRes<0)
  988.              { free(Buffer);
  989.                free(Buffer2);
  990.                if(fBox) fclose(fBox);
  991.                PackBox(UserName, 0);
  992.                return(-1);
  993.              }
  994.            continue;
  995.          }
  996.  
  997.  
  998.  
  999. /*QUIT*/
  1000.        if(memicmp(Buffer, QUITCMD, strlen(QUITCMD))==0)
  1001.          { break;
  1002.          }
  1003.        sprintf(Buffer2, "-ERR Don't know how to do \"%s\"\x0D\x0A", Buffer);
  1004.        sRes=write(Socket, Buffer2, strlen(Buffer2));
  1005.        if(sRes<0)
  1006.          { free(Buffer);
  1007.            free(Buffer2);
  1008.            if(fBox) fclose(fBox);
  1009.            PackBox(UserName, 0);
  1010.            return(-1);
  1011.          }
  1012.      } while(1);
  1013.  
  1014.   free(Buffer);
  1015.   free(Buffer2);
  1016.  
  1017.   if(fBox!=NULL) fclose(fBox);
  1018.   if(PackBox(UserName, 1)==0)
  1019.     { sprintf(Buffer2, "+OK %lu messages (%lu octets) remains\x0D\x0A", uMsgCount, uTotalLen);
  1020.       sRes=write(Socket, Buffer2, strlen(Buffer2));
  1021.       if(sRes<0)
  1022.         { free(Buffer);
  1023.           free(Buffer2);
  1024.           if(fBox) fclose(fBox);
  1025.           return(-1);
  1026.         }
  1027.     }
  1028.    else
  1029.     { sprintf(Buffer2, "-ERR All changes has been discarded :(\x0D\x0A");
  1030.       sRes=write(Socket, Buffer2, strlen(Buffer2));
  1031.       if(sRes<0)
  1032.         { free(Buffer);
  1033.           free(Buffer2);
  1034.           if(fBox) fclose(fBox);
  1035.           return(-1);
  1036.         }
  1037.     }
  1038.  
  1039.   for(i=0;i<msgCount;i++)
  1040.    { free(mBox[i].msgID);
  1041.    }
  1042.   if(mBox!=NULL) free(mBox);
  1043.  
  1044.   return(Res);
  1045. }
  1046.  
  1047.  
  1048.  
  1049.  
  1050.  
  1051.