/*
 * send to remote
 */

#include <stdio.h>
#include "mail.h"

extern char *Mailpgm;
char *cuserid(), *resolve(), *smarthost(), *strchr(), *getenv();
long sizefile();
int letnum, local;
/* char User[10]; */
/* char Rmtname[]; */

sendrmt(n, name)
char *name;
{
   FILE *rmf, *mypopen();
   register char *p;
   int mypclose();
   char rsys[256], cmd[256], dir[256], namesave[512];
   char *ropt;

   local = 0;
   letnum = n; /* make it global */

   if((ropt=getenv("MAILDEFER")) != (char *)EOF)
   {
      if(*ropt == 'n' || *ropt == 'N') ropt = "";
      else ropt = "-r";
   }
   else ropt = "-r"; /* default is to defer mail delivery */
   /*
    * try to resolve user@host.  host may be user.whatever (which may not
    * be in the PATHALIAS database).  If it is, and it's not in the database,
    * try again with just the name without the domain.  If that fails,
    * tack on smart-host (from PATHS) and pass to uuxqt.
    */

   strcpy(cmd, name);
   strcpy(namesave, name);
   if(strchr(name, '@') != (char *)NULL)
   {
      if((p=resolve(name)) == (char *)NULL)
      {
         name = cmd;
         if(strchr(name, '.') != (char *)NULL)
         {
            p = strchr(name, '.');
            *p = NULL;
            p = name;
         }
         else p = name;
         if((p=resolve(p)) == (char *)NULL)
         {
            p = smarthost(namesave);
            if (p == (char *)NULL) return(0);
         }
      }
      name = p;
   }

   /* escape character can persist */
   /* from alias, ~t, or Cc:   */
   if (*name=='\\')
      name++;
   if (*name=='!')
      name++;
   for (p=rsys; *name!='!'; *p++ = *name++) {
      if (*name == '\\') {
         name++;
         continue;
      }
      if (*name=='\0') {
         local++;
         break;
      }
   }
   *p = '\0';
   if ((!local && *name=='\0') || (local && *rsys=='\0')) {
      fprintf(stdout, "null name\n");
      return(0);
   }
   chdir("/tmp"); /* change to /tmp before running uux, else it might fail */
   if (local)
      sprintf(cmd, "%s %s", Mailpgm, rsys);
   else {
      if (strchr(name+1, '!'))
      {
         sprintf(cmd, "uux - -z %s %s!rmail \\(%s\\)", ropt, rsys, name+1);
/*
strcpy(cmd, "uux - -z ");
strcat(cmd, ropt);
strcat(cmd, " ");
strcat(cmd, rsys);
strcat(cmd, "!rmail \\(");
strcat(cmd, name+1);
strcat(cmd, "\\)");
*/
      }
      else
      {
         sprintf(cmd, "uux - -z %s %s!rmail %s", ropt, rsys, name+1);
/*
strcpy(cmd, "uux - -z ");
strcat(cmd, ropt);
strcat(cmd, " ");
strcat(cmd, rsys);
strcat(cmd, "!rmail ");
strcat(cmd, name+1);
*/
      }
   }
   if ((rmf=mypopen(cmd, "w")) == NULL)
      return(0);
   copylet(n, rmf, local? FORWARD: REMOTE, "");
   return(mypclose(rmf)==0 ? 1 : 0);
}
int cleanup(stat)
{
   exit(stat);
}

/*
* resolve - resolve name in PATHALIAS file.  If we can't, return (char *)NULL.
*           name is of the form user@name
*/

#ifndef NULL
#include <stdio.h>
#endif

#ifndef S_IFMT
#include <sys/types.h>
#include <sys/stat.h>
#endif

char *resolve(addr)
char *addr;
{
   long lower, higher, here;
   int found=0, pass, i, j, ret, nflag=1;
   char *paths, line[512], *tptr, *lineptr, temp[64], ch, user[64];
   static char addrout[512];
   FILE *in;

   if(strchr(addr, '@') == (char *)NULL) return((char *)NULL);
#ifdef DEBUG
      printf("DEBUG: resolving addr: %s\n", addr);
      fflush(stdout);
#endif
   if((paths=getenv("PATHALIAS")) == (char *)NULL) paths = DEFPATHS;
   for(j=0; j<2; j++)
   {
      if(nflag == 1 && j == 1) break;
      switch(j)
      {
      case 1:
         paths = ALTPATHS;
         break;
      }
      if((in=fopen(paths, "r")) == (FILE *)NULL)
      {
         if(j == 0) perror(paths);
         continue;
      }
      if((tptr=strchr(addr, '@')) != (char *)NULL)
      {
         *tptr = NULL;
         strcpy(user, addr);
         strcat(user, "\n");
         addr = 1+tptr;
      }
      else *user = NULL;
      lower = 0L;
      higher = sizefile(paths);
      pass = 0;
      *temp = *line = NULL;
      found = 0;
      while(found == 0)
      {
         pass++;
         here = lower + (higher-lower)/2L;
         if(here == lower || here == higher) break;
         fseek(in, here, 0);
         while(fread(&ch, sizeof(char), 1, in) == 1)
            if(ch == '\n') break;
         if(ch != '\n') break; /* end of file */
         fgets(line, 510, in);
         line[strlen(line)-1] = NULL;
         tptr = temp;
         lineptr = line;
         while(*lineptr != '\t') *tptr++ = *lineptr++;
         *tptr = NULL;
         lineptr++;
#ifdef DEBUG
         printf(
             "DEBUG: Pass %d:  found=%d, lower=%ld, higher=%ld, here=%ld\n",
             pass, found, lower, higher, here);
         printf("DEBUG: lineptr = %s\n", lineptr);
         fflush(stdout);
#endif
         ret = strcmp(addr, temp);
         if(ret < 0)
         {
            higher = here;
            continue;
         }
         if(ret > 0)
         {
            lower = here;
            continue;
         }
         if(ret == 0)
         {
            found = 1;
            break;
         }
      }
#ifdef DEBUG
      printf("DEBUG: Pass %d:  found=%d, lower=%ld, higher=%ld, here=%ld\n",
          pass, found, lower, higher, here);
      printf("DEBUG: lineptr = %s\n", lineptr);
      fflush(stdout);
#endif
      if(found == 1)
      {
         lineptr[strlen(lineptr)-3] = NULL; /* get rid of "!%s" */
         if(*user != NULL)
         {
            if(user[strlen(user)-1] == '\n')
               user[strlen(user)-1] = NULL;
            sprintf(addrout, "%s!%s", lineptr, user);
         }
         else
            strcpy(addrout, lineptr);
         return(addrout);
      }
      else return((char *)NULL); /* name not found */
   }
   fclose(in);
}

char *smarthost(addr)
char *addr;
{
   /* prepend addr with smart-host from paths database. */
   char *paths, *lineptr, sender[64], line[512], cmd[256];
   static char addrout[512];
   FILE *in;

   if((paths=getenv("PATHALIAS")) == (char *)NULL) paths = DEFPATHS;
   /*
    * We never check for machine!user irregularities here - uux is
    * supposed to do that for us.
    */
   cuserid(sender);
   if((in=fopen(paths, "r")) == (FILE *)NULL)
   {
      sprintf(cmd, "mail -s 'Returned mail: %s unknown address' %s",
         addr, sender);
      if ((in=mypopen(cmd, "w")) == NULL)
         return((char *)NULL);
      fprintf(in, "The following letter is being returned because the address\n");
      fprintf(in, "'%s' is unknown to this machine (no pathalias database).  Sorry for the inconvenience.\n\n", addr);
      fprintf(in, "-- Returned mail follows --\n\n");
      copylet(letnum, in, local? FORWARD: REMOTE, "");
      mypclose(in);
      return((char *)NULL);
   }
   while(fgets(line, 510, in) != (char *)NULL)
   {
      if(strncmp(line, "smart-host", 10) != 0) continue;
      line[strlen(line)-1] = NULL;
      lineptr = line;
      while(*lineptr != '\t') lineptr++;
      lineptr++;
      sprintf(addrout, "%s!%s", lineptr, addr);
#ifdef DEBUG
      printf("DEBUG: smarthost: forwarding mail to %s\n", addrout);
      fflush(stdout);
#endif
      return(addrout);
   }
   fclose(in);

   sprintf(cmd, "mail -s 'Returned mail: %s unknown address' %s",
      addr, sender);
   if ((in=mypopen(cmd, "w")) == NULL)
      return((char *)NULL);
   fprintf(in, "The following letter is being returned because the address\n");
   fprintf(in, "'%s' is unknown to this machine (the address wasn't in the\n", addr);
   fprintf(in, "pathalias database and smart-host wasn't defined).  Sorry for\n");
   fprintf(in, "the inconvenience.\n\n");
   fprintf(in, "-- Returned mail follows --\n\n");
   copylet(letnum, in, local? FORWARD: REMOTE, "");
   mypclose(in);
   return((char *)NULL);
}


long sizefile(s)
char *s;
{
   struct stat buf;

   if(EOF == stat(s, &buf)) return((long)EOF);
   return(buf.st_size);
}

long fsizefile(f)
FILE *f;
{
   struct stat buf;

   if(EOF == fstat(fileno(f), &buf)) return((long)EOF);
   return(buf.st_size);
}
