#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/
|