Platon Technologies
not logged in Login Registration
EnglishSlovak
open source software development celebrating 10 years of open source development! Friday, April 19, 2024

File: [Platon] / libplaton / utils / getmails / getmails.c (download)

Revision 1.10, Fri Dec 26 18:08:18 2008 UTC (15 years, 3 months ago) by nepto


Changes since 1.9: +1 -1 lines

Fixed typo: agains -> against

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

#include <platon/str/strplus.h>
#include <platon/str/strctype.h>
#include <platon/misc/fileplus.h>

/* Compilation against libplaton library:
   gcc -pedantic -L ../../platon/ -I ../../ -o getmails getmails.c -lplaton
*/

#define BUFSIZE 301

#define INPUT_FMODE  "rt"
#define OUTPUT_FMODE "at"

#ifndef isemail
  #include<ctype.h>
  #define isemail(__c)\
    (isalpha(__c)||isdigit(__c)||(__c)=='-'||(__c)=='_'||(__c)=='@'||(__c)=='.')
#endif

/* Function prototypes */
int isvalidemail(const char*s);
int extract(const char*fin_name,const char*fout_name);
int sort(const char*filename);

int main(int argc,char*argv[])
{
  /* Information and help */
  printf("GETMAILS - MS-Dos/Unix e-mail address extractor v1.2 / %s %s\n",__DATE__,__TIME__);
  if (argc<3) {
    puts("Programmed by Ondrej Jombik, e-mail: nepto@platon.sk, web: http://nepto.sk/");
    puts("Copyright (c) 2000 Condy software inc., All rights reserved.");
    puts("\nUsage: GETMAILS <input_file> <output_file>");
    return(1);
  }

  /* Files check */
  if (0) {
    FILE*f;
    if ((f=fopen(argv[1],INPUT_FMODE))==NULL) {
      printf("Can't open input file. [%s]\n",argv[1]);
      return(1);
    }
    fclose(f);

    if ((f=fopen(argv[2],OUTPUT_FMODE))==NULL) {
      printf("Can't open output file. [%s]\n",argv[2]);
      return(1);
    }
    fclose(f);
  }
  printf("Appending data from '%s' to '%s'.\n",argv[1],argv[2]);

  /* E-mail addresses extracting */
  printf("Extracting... ");
  if (extract(argv[1],argv[2])) {
    puts("fail.");
    return(1);
  }
  else puts("OK.");

  /* Sorting */
  printf("Sorting... ");
  if (sort(argv[2])) {
    puts("fail.");
    return(1);
  }
  else puts("OK.");

  /* Removing multiple items */
  printf("Optimalization... ");
  if (frmsort(argv[2],strrcmp)) {
    puts("fail.");
    return(1);
  }
  else puts("OK.");

  puts("All done.");
  return(0);
}

/* Function checks valid e-mail address constraints

   1. Address must contain just one '@' character
   2. On the right side of '@' there must be at least one '.' character
   3. On the left side of '@' there can be no more than one '.' character
   4. Behind the last point '.' there can be 2, 3 or 4 characters

*/

int isvalidemail(const char *s)
{
  char*ms;
  if ((ms=strchr(s,'@'))==NULL)return(0);
  if (strchr(ms+1,'@')!=NULL)return(0);
  if (strchr(ms+1,'.')==NULL)return(0);
  if (strchr(s,'.')<ms)if (strchr(strchr(s,'.')+1,'.')<ms)return(0);
  if (strlen(strrchr(s,'.')+1)>4||strlen(strrchr(s,'.')+1)<2)return(0);
  return(1);
}

int extract(const char *fin_name, const char *fout_name)
{
  char buf[BUFSIZE],*xbuf;
  FILE*fin,*fout;

  if (! strcmp(fin_name, "-") || ! strcmp(fin_name, "stdin")) {
      fin = stdin;
  } else {
      if ((fin=fopen(fin_name,INPUT_FMODE))==NULL)return(1);
  }
  if (! strcmp(fout_name, "-") || ! strcmp(fout_name, "stdout")) {
      fout = stdout;
  } else {
      if ((fout=fopen(fout_name,OUTPUT_FMODE))==NULL)return(1);
  }

  memset((void*)buf,'\0',sizeof(buf));
  while (fscanf(fin,"%300s",buf)!=EOF) {
    strlwr(buf);
    while ((xbuf=strchr(buf,'@'))!=NULL) {
      while (xbuf>buf&&isemail(xbuf[-1]))xbuf--;
      while (xbuf>buf) {
    strdel(buf);
    xbuf--;
      }
      xbuf=strchr(buf,'@');
      while (isemail(xbuf[0]))xbuf++;
      if (xbuf[0]=='\0')xbuf[1]='\0';
      else xbuf[0]='\0';

      while (buf[0]=='.')strdel(buf);
      while (buf[strlen(buf)-1]=='.')strdel(buf+strlen(buf)-1);

      if (isvalidemail(buf)) {
    fputs(buf,fout);
    fputc('\n',fout);
      }
      strcpy(buf,xbuf+1);
    }
    memset((void*)buf,'\0',sizeof(buf));
  }

  if (fin != stdin) {
      fclose(fin);
  }
  if (fout != stdout) {
      fclose(fout);
  }

  return(0);
}

int sort(const char*filename)
{
  char buf[BUFSIZE];
  FILE*f,*ftmp;

#ifdef __MSDOS__
  char ftmpname[L_tmpnam + 1];
  tmpnam(ftmpname);
#else
  /* This case is not possible for MS-DOS systems
     because maximum length of filename is 12 (8 + 3 + 1) */
  char ftmpname[] = "_libplaton_utils_getmails_getmails_c_XXXXXX";
  close(mkstemp(ftmpname));
#endif

  if ((f=fopen(filename,"rt"))==NULL)return(-1);
  if ((ftmp=fopen(ftmpname,"wt"))==NULL)return(-1);

  /* We will write e-mail adresses reversed, thus they can be easily sorted */
  while (fgets(buf,sizeof(buf),f)!=NULL) {
    if (fputs(strrev(strrmeol(buf)),ftmp)==EOF)return(-1);
    if (fputc('\n',ftmp)==EOF)return(-1);
  }

  if (fclose(ftmp)==EOF)return(-1);
  if (fclose(f)==EOF)return(-1);

  /* Sorting using operating system call */
  #ifdef __MSDOS__
    sprintf(buf,"type %s | sort > %s",ftmpname,ftmpname);
  #else
    sprintf(buf,"cat %s | sort > %s",ftmpname,ftmpname);
  #endif
  if (system(buf) < 0) {
    #if DEBUG
      fprintf(stderr,"sort() WARNING: System call failed. [ftmpname=%s]\n",ftmpname);
    #endif
  }

  if ((f=fopen(filename,"wt"))==NULL)return(-1);
  if ((ftmp=fopen(ftmpname,"rt"))==NULL)return(-1);

  /* Reverting back */
  while (fgets(buf,sizeof(buf),ftmp)!=NULL) {
    if (fputs(strrev(strrmeol(buf)),f)==EOF)return(-1);
    if (fputc('\n',f)==EOF)return(-1);
  }

  if (fclose(ftmp)==EOF)return(-1);
  if (fclose(f)==EOF)return(-1);

  if (remove(ftmpname))return(-1);

  return(0);
}


Platon Group <platon@platon.org> http://platon.org/
Copyright © 2002-2006 Platon Group
Site powered by Metafox CMS
Go to Top