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

#ifndef WIN32
#include <unistd.h>
#endif

#include <fstream.h>

#include <folder.h>
#include <dboxpath.h>
#include <config.h>
#include <userdb.h>

// **********************************************************************
// *                                                                    *
// *                                                                    *
// *                                                                    *
// **********************************************************************

void folderpt::setfilename()
 {
  if(name[0]=='/') // News
   {
    //snprintf(path, DIRLEN, BOXBRETTERDIR "%s" DIRCHAR, 
    //  pconfig->boxdir, name+1);
   }
  else // Mail
   {
    char *tptr, subfolder[TEXTLEN];
    char username[TEXTLEN];

    strmaxcpy(subfolder, name, TEXTLEN-1);
    tptr=strchr(subfolder, '@');

    if(tptr==(char *)NULL)
     {
      strmaxcpy(username, name, TEXTLEN-1);
      strmaxcpy(subfolder, "0", TEXTLEN-1);
      snprintf(name, TEXTLEN, "%s@%s", subfolder, username);
     }
    else
     {
      *(tptr++)=0;
      strmaxcpy(username, tptr, TEXTLEN-1);
     }

    std::string p;
    getboxusermaildir(p, pconfig->boxdir, username, subfolder);
    strmaxcpy(path, p.c_str(), DIRLEN-1);
   }

  strmaxcpy(locktype, "folder", TEXTLEN-1);
  snprintf(filename, DIRLEN, "%sprofile", path);
 }
 
bool folderpt::add()
 {
  return TRUE;
 }

bool folderpt::del()
 {
  return TRUE;
 }

// **********************************************************************
// *                                                                    *
// *                                                                    *
// *                                                                    *
// **********************************************************************

bool mailfolderalias(std::string &folder_owner, std::string &subfolder)
 {
  std::string folder_name;
  folderpt fp;

  folder_name=subfolder+"@"+folder_owner;

  fp.setname(folder_name);
  fp.read();

  std::string alias_user=(fp|"alias.user");
  std::string alias_mailbox=(fp|"alias.mailbox");
  if(alias_user=="") return FALSE;

  if(get_subfolder(alias_user, alias_mailbox, subfolder))
    return TRUE;

  folder_name=subfolder+"@"+folder_owner;

  fp.setname(folder_name);

  return FALSE;
 }
 
// **********************************************************************
// *                                                                    *
// *                                                                    *
// *                                                                    *
// **********************************************************************

bool get_subfolder(const std::string &folder_owner,
                   const std::string &mailbox_name,
                   std::string &subfolder)
 {
  subfolder="";

  if(mailbox_name=="") return TRUE;

  std::string filename;
  getboxuserdir(filename, config.boxdir, folder_owner);
  filename+="folders";

  ifstream in(filename.c_str());

  if(in==NULL)
   { 
    if(mailbox_name=="INBOX")
     {
      subfolder="0";
      return FALSE;
     }
    return TRUE;
   }

  char line[TEXTLEN], *tptr, ch;

  for(unsigned i=0; in.get(line, TEXTLEN-1); i++)
   {
    in.get(ch); // read \n
    tptr=strchr(line, '\n'); if(tptr!=NULL) *tptr=0;
    tptr=strchr(line, '\r'); if(tptr!=NULL) *tptr=0;
    if(mailbox_name==line)
     {
      char tempstr[TEXTLEN];
      snprintf(tempstr, TEXTLEN, "%u", i);
      subfolder=tempstr;
      return FALSE;
     }
   }

  return TRUE;
 }

// **********************************************************************
// *                                                                    *
// *                                                                    *
// *                                                                    *
// **********************************************************************

bool checkreserved(const char *name)
 {
  return stricmp(name, "profile")==0 ||
         stricmp(name, "profile.tmp")==0 ||
         stricmp(name, "konto")==0 ||
         stricmp(name, "auszug")==0 ||
         stricmp(name, "logfile")==0 ||
         stricmp(name, "index")==0 ||
         stricmp(name, "index.tmp")==0 ||
         stricmp(name, "grants")==0 ||
         stricmp(name, "grants.tmp")==0 ||
         stricmp(name, "index.html")==0 ||
         stricmp(name, "INDEX")==0 ||
         stricmp(name, "header")==0 ||
         stricmp(name, "header.tmp")==0;
 }

// **********************************************************************
// *                                                                    *
// *                                                                    *
// *                                                                    *
// **********************************************************************

void makeexternfilename(std::string &filename,
                        const std::string &hint,
                        const std::string &directory)
 {
  char tempstr[DIRLEN], *tptr;
  char _filename[DIRLEN];
  bool alluppercase=TRUE;
  dword i;

  if(hint=="")
    strmaxcpy(tempstr, "mail", DIRLEN-1);
  else
    strmaxcpy(tempstr, hint.c_str(), DIRLEN-1);

  tempstr[70]=0;

  if(tempstr[0]=='-') tempstr[0]='_';

  tptr=tempstr;
  while(*tptr!=0)
   {
    if(isascii(*tptr) &&
       (isalpha(*tptr) || isdigit(*tptr) || *tptr=='.' || 
        *tptr=='-' || *tptr=='_'))
     {
      if(*tptr>='a' && *tptr<='z') alluppercase=FALSE;
     }
    else
      *tptr='_';

    tptr++;
   }

  if(alluppercase)
   {
    tptr=tempstr;
    while(*tptr!=0)
     {
      *tptr=dncase(*tptr);
      tptr++;
     }
   }

  snprintf(_filename, DIRLEN, "%s%s", directory.c_str(), tempstr);

  tptr=_filename+strlen(_filename);
  i=1;
  while(access(_filename, 00)==0)
   {
    sprintf(tptr, "_%lu", i);
    i++;
   }

  filename=_filename;
 }

// **********************************************************************
// *                                                                    *
// *                                                                    *
// *                                                                    *
// **********************************************************************

void folder_grantst::clear()
 {
  del=lookup=read=write=insert=create=administer=keepseen=FALSE;
 }

// **********************************************************************
// *                                                                    *
// *                                                                    *
// *                                                                    *
// **********************************************************************

bool parse_folder_grants_line(const char *line, std::string &name, std::string &flags)
 {
  char tmp_name[TEXTLEN];
  if(line[1]!=':') return TRUE;
  strmaxcpy(tmp_name, line+2, TEXTLEN-1);
  char *tptr=strchr(tmp_name, ' ');
  if(tptr!=NULL) *tptr=0;
  name=tmp_name;

  tptr=strchr(line, ' ');
  if(tptr==NULL) return TRUE;
  while(tptr[0]==' ') tptr++;
  flags=tptr;

  return FALSE;
 }

bool parse_folder_grants(const std::string &grants_string, folder_grantst &grants)
 {
  for(unsigned i=0; i<grants_string.size(); i++)
    switch(grants_string[i])
     {
     case 'd': grants.del=TRUE; break;
     case 'l': grants.lookup=TRUE; break;
     case 's': grants.keepseen=TRUE; break;
     case 'r': grants.read=TRUE; break;
     case 'w': grants.write=TRUE; break;
     case 'i': grants.insert=TRUE; break;
     case 'c': grants.create=TRUE; break;
     case 'a': grants.administer=TRUE; break;
     case '*': grants.del=TRUE; 
               grants.lookup=TRUE;
               grants.keepseen=TRUE;
               grants.read=TRUE;
               grants.write=TRUE;
               grants.insert=TRUE;
               grants.create=TRUE;
               grants.administer=TRUE;
               break;
     default:;
     }

  return FALSE;
 }

void get_folder_grants(const std::string &folder_owner,
                       const std::string &subfolder,
                       userpt &who_up,
                       grouppt &who_gp,
                       folder_grantst &grants)
 {
  std::string folder_name=subfolder+"@"+folder_owner;

  grants.clear();

  folderpt fp;
  fp.setname(folder_name);
  if(fp.read()) return;

  std::string infilename;

  infilename=fp.getpath();
  infilename+="grants";

  ifstream infile(infilename.c_str());

  if(!infile)
   {
    if(stricmp(who_up.name, folder_owner.c_str())==0)
     {
      grants.del=grants.lookup=grants.read=
      grants.write=grants.insert=grants.create=
      grants.administer=grants.keepseen=TRUE;
     }

    return;
   }

  char line[TEXTLEN*10], *tptr, ch;

  while(infile.get(line, (TEXTLEN*10)-1))
   {
    std::string name, flags;

    infile.get(ch); // read \n
    tptr=strchr(line, '\n'); if(tptr!=NULL) *tptr=0;
    tptr=strchr(line, '\r'); if(tptr!=NULL) *tptr=0;

    switch(line[0])
     {
     case 'U':
      if(!parse_folder_grants_line(line, name, flags) &&
         checkjoker(name.c_str(), who_up.name, TRUE))
       {
        parse_folder_grants(flags, grants);
        return;
       }
      break;

     case 'F':
      #if 0
      if(!parse_folder_grants_line(line, name, flags) &&
         getuserflag(&who_up, &who_gp, name.c_str()))
       {
        parse_folder_grants(flags, grants);
        return;
       }
      #endif
      break;
     }
   }
 }




syntax highlighted by Code2HTML, v. 0.9.1