#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>

#include <dlg/resman.h>
#include <dlg/file.h>
#include <dlg/msg.h>
#include <dlg/misc.h>

#include <link/io.h>
#include <link/util.h>

#include <proto/dos.h>
#include <proto/dlg.h>

#include <pragmas/dlg.h>

extern struct USER_DATA UserDat;
extern struct Library *DLGBase;
extern char       **SA;

LONG  RawUpload(  char *path,
                  char *src,
                  struct File_Header *header,
                  char *body,
                  char *toname,
                  struct Msg_Area *areainfo,
                  char *pswd,
                  char copyfile)
{
   long                area;
   int                 fp;
   long                bodylen;
   long                high;
   long                low;
   char                msgname[54];
   char                source[256];
   char                dest[256];
   char                qfilename[24];
   char                valname[20];
   char                userstatus;

   struct Group_Def    group;
   struct QuickFile    QF;


   if (header->Filename) UnderScore(header->Filename);

   if (!Stricmp(header->Filename + (strlen(header->Filename) - 3), ".fd"))
      strcat(header->Filename, "_");

   if (!Stricmp(header->Filename, "Batch.File"))
      strcat(header->Filename, "_");

   if (!Stricmp(header->Filename, "WaitingMail.dat"))
      strcat(header->Filename, "_");

   /* Find the message pointers of area we are writing to */
   if (toname)
      area = -1;
   else
      area = areainfo->Number;

   if (toname)
   {
      userstatus = CheckUser(toname);

      switch (userstatus)
      {
         case 0:
            return (-3);
            break;

         case 1:
            break;

         case 2:
            strcpy(group.name, toname);

            if (GetStruct("DLGCONFIG:Group/Group.bbs", (char *) &group, sizeof(group), 36) == -1)
               return (-3);

            strcpy(toname, group.gop);
            Upper(toname);
            break;
      }
   }

   GetHiLowFPointers(area, toname, &low, &high, pswd);

   /* Set the filename of the destination .fd and file and
 * UnderScore it */
   strcpy(source,path);
   AddPart(source,src,255);
   UnderScore(source);
   FileSize(source, (ULONG *) & header->Size);

   if (!toname)
   {
      BorrowArea(area, pswd, "Writing description", 64, FILELOCK | WRITELOCK);
      ASPrintf(NULL, msgname, "FILE:%ld/%ld.fd", area, ++high);

//      if (areainfo->path[0] != '\0')
//         if (areainfo->path[strlen(areainfo->path) - 1] != ':' && areainfo->path[strlen(areainfo->path) - 1] != '/')
//      strcat(areainfo->path, "/");

      if (areainfo->path[0] == '\0')
      {
         ASPrintf(NULL, dest, "FILE:%ld/%s", area, header->Filename);
      }
      else
      {
         strcpy(dest,areainfo->path);
         AddPart(dest,header->Filename,255);
//         ASPrintf(NULL, dest, "%s%s", areainfo->path, header->Filename);
      }

      ASPrintf(NULL, qfilename, "FILE:%d/File.dat", area);
   }
   else
   {
      ASPrintf(NULL, msgname, "USER:%s/%ld.fd", toname, ++high);
      ASPrintf(NULL, dest, "USER:%s/%s", toname, header->Filename);

      UnderScore(msgname);
      UnderScore(dest);
   }

   if (Exists(msgname)) DeleteFile(msgname);

   if (!toname)
   {
      strcpy(QF.filename, header->Filename);

      if (GetStruct(qfilename, (char *) &QF, sizeof(QF), 36) != -1)
      {
         FreeArea(area, pswd, FILELOCK | WRITELOCK);
         return (-1);
      }
   }

   if (copyfile && SmartRename(source, dest))
   {
      FreeArea(area, pswd, FILELOCK | WRITELOCK);
      AFPrintf(NULL, Output(), "Can't rename %s -> %s\n\n", source, dest);
      return (-1);
   }

   if ((fp = open(msgname, O_WRONLY + O_CREAT)) == EOF)
   {
      FreeArea(area, pswd, FILELOCK | WRITELOCK);
      if (copyfile)
      SmartRename(dest, source);
      return (-2);
   }

   if (toname) header->Attribute |= NORATIO;

   if (header->Attribute & UNVALIDATED)
   {
      ASPrintf(NULL, valname, "FILE:%d/%ld.val", areainfo->Number, high);
      AddStruct(valname, (char *) &(header->Times_Downloaded), 2, 2);
      header->Times_Downloaded = 0;
   }

   write(fp, header, sizeof(*header));
   bodylen = strlen(body);

   if (write(fp, body, bodylen) != bodylen)
   {
      close(fp);
      FreeArea(area, pswd, FILELOCK | WRITELOCK);
      if (copyfile) SmartRename(dest, source);
      DeleteFile(msgname);
      return (-2);
   }

   close(fp);

   if (copyfile)
      SetComment(dest, msgname);
   else
      SetComment(source, msgname);

   if (!toname)
   {
      StringToDate(header->Date, &(QF.date));
      QF.number = (int) high;
      QF.size = header->Size;
      strcpy(QF.filename, header->Filename);
      strncpy(QF.desc, body, 58);
      QF.desc[59] = '\0';
      AddStruct(qfilename, (char *) &QF, sizeof(QF), 36);
   }

   FreeArea(area, pswd, FILELOCK | WRITELOCK);

   if (!PutHiLowFPointers(area, toname, low, high, pswd))
      AFPrintf(&UserDat, Output(), SA[3626]);

   return ((long) high);
}
