URI:
       pubsub_gethub.c - pubsubhubbubblub - pubsubhubbub client implementation
  HTML git clone git://git.codemadness.org/pubsubhubbubblub
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       pubsub_gethub.c (2944B)
       ---
            1 #include <err.h>
            2 #include <stdio.h>
            3 #include <strings.h>
            4 #include <unistd.h>
            5 
            6 #undef strlcat
            7 size_t strlcat(char *, const char *, size_t);
            8 
            9 #include "xml.h"
           10 
           11 #define ISCNTRL(c) ((c) < ' ' || (c) == 0x7f)
           12 #define TOLOWER(c) ((((unsigned)c) - 'A' < 26) ? ((c) | 32) : (c))
           13 
           14 /* string and size */
           15 #define STRP(s) s,sizeof(s)-1
           16 
           17 static XMLParser parser;
           18 static int islinktag, ishrefattr, isrelattr;
           19 static char linkhref[4096], linkrel[256];
           20 
           21 /* strcasestr() included for portability */
           22 char *
           23 strcasestr(const char *h, const char *n)
           24 {
           25         size_t i;
           26 
           27         if (!n[0])
           28                 return (char *)h;
           29 
           30         for (; *h; ++h) {
           31                 for (i = 0; n[i] && TOLOWER((unsigned char)n[i]) ==
           32                             TOLOWER((unsigned char)h[i]); ++i)
           33                         ;
           34                 if (n[i] == '\0')
           35                         return (char *)h;
           36         }
           37 
           38         return NULL;
           39 }
           40 
           41 static void
           42 printvalue(const char *s)
           43 {
           44         for (; *s; s++)
           45                 if (!ISCNTRL((unsigned char)*s))
           46                         putchar(*s);
           47 }
           48 
           49 static void
           50 xmltagstart(XMLParser *p, const char *t, size_t tl)
           51 {
           52         islinktag = 0;
           53         char *l;
           54 
           55         if (((l = strcasestr(t, ":link")) && !strcasecmp(l, ":link")) ||
           56             !strcasecmp(t, "link")) {
           57                 islinktag = 1;
           58                 linkhref[0] = '\0';
           59                 linkrel[0] = '\0';
           60         }
           61 }
           62 
           63 static void
           64 xmltagstartparsed(XMLParser *p, const char *t, size_t tl, int isshort)
           65 {
           66         if (!islinktag)
           67                 return;
           68 
           69         if (strncasecmp(linkrel, STRP("hub")) &&
           70             strncasecmp(linkrel, STRP("self")))
           71                 return;
           72 
           73         printvalue(linkhref);
           74         putchar('\t');
           75         printvalue(linkrel);
           76         putchar('\n');
           77 }
           78 
           79 static void
           80 xmlattrstart(XMLParser *p, const char *t, size_t tl, const char *a, size_t al)
           81 {
           82         ishrefattr = isrelattr = 0;
           83 
           84         if (!islinktag)
           85                 return;
           86 
           87         if (!strcasecmp(a, "href")) {
           88                 ishrefattr = 1;
           89                 linkhref[0] = '\0';
           90         } else if (!strcasecmp(a, "rel")) {
           91                 isrelattr = 1;
           92                 linkrel[0] = '\0';
           93         }
           94 }
           95 
           96 static void
           97 xmlattr(XMLParser *p, const char *t, size_t tl, const char *n, size_t nl,
           98         const char *v, size_t vl)
           99 {
          100         if (islinktag) {
          101                 if (ishrefattr)
          102                         strlcat(linkhref, v, sizeof(linkhref));
          103                 else if (isrelattr)
          104                         strlcat(linkrel, v, sizeof(linkrel));
          105         }
          106 }
          107 
          108 static void
          109 xmlattrentity(XMLParser *p, const char *t, size_t tl, const char *a, size_t al,
          110               const char *v, size_t vl)
          111 {
          112         char buf[16];
          113         int len;
          114 
          115         if (!ishrefattr && !isrelattr)
          116                 return;
          117 
          118         /* try to translate entity, else just pass as data to
          119          * xmlattr handler. */
          120         if ((len = xml_entitytostr(v, buf, sizeof(buf))) > 0)
          121                 xmlattr(p, t, tl, a, al, buf, (size_t)len);
          122         else
          123                 xmlattr(p, t, tl, a, al, v, vl);
          124 }
          125 
          126 int
          127 main(void)
          128 {
          129 #ifdef __OpenBSD__
          130         if (pledge("stdio", NULL) == -1)
          131                 err(1, "pledge");
          132 #endif
          133 
          134         parser.xmlattr = xmlattr;
          135         parser.xmlattrentity = xmlattrentity;
          136         parser.xmlattrstart = xmlattrstart;
          137         parser.xmltagstart = xmltagstart;
          138         parser.xmltagstartparsed = xmltagstartparsed;
          139 
          140         /* NOTE: getnext is defined in xml.h for inline optimization */
          141         xml_parse(&parser);
          142 
          143         if (ferror(stdin))
          144                 fputs("read error: <stdin>\n", stderr);;
          145         if (fflush(stdout) || ferror(stdout))
          146                 fputs("write error: <stdout>\n", stderr);
          147 
          148         return 0;
          149 }