URI: 
       linkbrother.c - annna - Annna the nice friendly bot.
  HTML git clone git://bitreich.org/annna/ git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/annna/
   DIR Log
   DIR Files
   DIR Refs
   DIR Tags
   DIR README
       ---
       linkbrother.c (4118B)
       ---
            1 // cc linkbrother.c -o linkbrother
            2 //
            3 // Use: ./linkbrother LINKSFILE USER MESSAGE
            4 
            5 #define _GNU_SOURCE // sorry
            6 
            7 #include <stdlib.h>
            8 #include <stdio.h>
            9 #include <string.h>
           10 #include <ctype.h>
           11 #include <sys/types.h>
           12 #include <sys/stat.h>
           13 #include <sys/mman.h>
           14 #include <sys/time.h>
           15 #include <unistd.h>
           16 #include <fcntl.h>
           17 #include <time.h>
           18 #include <assert.h>
           19 
           20 FILE* linksf;
           21 char* links;
           22 int linkslength;
           23 time_t now;
           24 int userlength;
           25 
           26 void checklink(const char* user, const char* link) {
           27   int l = strlen(link);
           28   char* foundlink = (char*)memmem(links, linkslength, link, l);
           29   if (foundlink != NULL) {
           30     char* end = foundlink;
           31     while (!isspace(*end) && *end != 0) {
           32       end++;
           33     }
           34     end = 0;
           35     if (*(foundlink + l) == ' ') {
           36       char* nstart = foundlink + l + 1;
           37       char* whostart = strstr(nstart + 1, " ") + 1;
           38       char* whoend = strstr(whostart, "\n");
           39       time_t then = atoi(nstart);
           40       *whoend = 0;
           41 
           42       time_t diff = now - then;
           43       char* unit;
           44       int unit_number;
           45 
           46       if (diff < 60) {
           47         if (diff == 1) {
           48           unit = "second";
           49         } else {
           50           unit = "seconds";
           51         }
           52         unit_number = diff;
           53       } else if (diff < 60 * 60) {
           54         unit_number = diff / 60;
           55         if (unit_number == 1) {
           56           unit = "minute";
           57         } else {
           58           unit = "minutes";
           59         }
           60       } else if (diff < 60 * 60 * 24) {
           61         unit_number = diff / 60 / 60;
           62         if (unit_number == 1) {
           63           unit = "hour";
           64         } else {
           65           unit = "hours";
           66         }
           67       } else if (diff < 60 * 60 * 24 * 365) {
           68         unit_number = diff / 60 / 60 / 24;
           69         if (unit_number == 1) {
           70           unit = "day";
           71         } else {
           72           unit = "days";
           73         }
           74       } else {
           75         unit_number = diff / 60 / 60 / 24 / 365;
           76         unit = "year";
           77       }
           78 
           79       if (strcmp(user, whostart) == 0) {
           80         switch (rand()%3) {
           81         case 0:
           82           printf("%s: You first posted that link %d %s ago!\n",
           83                  user, unit_number, unit);
           84           break;
           85         case 1:
           86           printf("%s: We heard you the first time (%d %s ago).\n",
           87                  user, unit_number, unit);
           88           break;
           89         case 2:
           90           printf("%s: %d %s ago you posted something similar.  How about something new?\n",
           91                  user, unit_number, unit);
           92           break;
           93         }
           94       } else {
           95         switch (rand()%3) {
           96         case 0:
           97           printf("%s: %s already linked that %d %s ago.\n",
           98                  user, whostart, unit_number, unit);
           99           break;
          100         case 1:
          101           printf("%s: Comrade!  That link was first seen %d %s ago!\n",
          102                  user, unit_number, unit);
          103           break;
          104         case 2:
          105           printf("%s: How nostalgic!  Just like %s a whole %d %s ago!\n",
          106                  user, whostart, unit_number, unit);
          107           break;
          108         }
          109       }
          110     }
          111   }
          112   /* Always log */
          113   fprintf(linksf, "%s %ld %s\n", link, (long int)now, user);
          114 }
          115 
          116 int main(int argc, char** argv) {
          117   assert(argc == 4);
          118   char* dbfile = argv[1];
          119   char* user = argv[2];
          120   char* message = argv[3];
          121 
          122   now = time(NULL);
          123   srand(now);
          124 
          125   if (message != NULL && user != NULL) {
          126     struct stat fs;
          127 
          128     userlength = strlen(user);
          129     linksf = fopen(dbfile, "a+");
          130     assert(linksf != NULL);
          131     fstat(fileno(linksf), &fs);
          132     linkslength = fs.st_size;
          133     links = mmap(NULL, linkslength, PROT_WRITE | PROT_READ, MAP_PRIVATE, fileno(linksf), 0);
          134     while (1) {
          135       char* start, *end;
          136       int atend;
          137 
          138       start = strstr(message, "http://");
          139 
          140       if (start == NULL) {
          141         start = strstr(message, "https://");
          142       }
          143 
          144       if (start == NULL) {
          145         start = strstr(message, "gopher://");
          146       }
          147 
          148       if (start == NULL) {
          149         start = strstr(message, "gophers://");
          150       }
          151 
          152       if (start == NULL) {
          153         return 0;
          154       }
          155 
          156       end = start;
          157 
          158       while (*end != ' ' && *end != 0) {
          159         end++;
          160       }
          161 
          162       atend = *end == 0;
          163       *end = 0;
          164 
          165       checklink(user, start);
          166 
          167       if (atend) {
          168         return 0;
          169       }
          170 
          171       message = end+1;
          172     }
          173     return 0;
          174   } else {
          175     return 1;
          176   }
          177 }