#include #include #include #include #include #include /* 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 #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 "); 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,'.')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); }