/* input rtcm 2 message from stream -------------------------------------------- * fetch next rtcm 2 message and input a message from byte stream * args : rtcm_t *rtcm IO rtcm control struct * unsigned char data I stream data (1 byte) * return : status (-1: error message, 0: no message, 1: input observation data, * 2: input ephemeris, 5: input station pos/ant parameters, * 6: input time parameter, 7: input dgps corrections, * 9: input special message) * notes : before firstly calling the function, time in rtcm control struct has * to be set to the approximate time within 1/2 hour in order to resolve * ambiguity of time in rtcm messages. * supported msgs RTCM ver.2: 1,3,9,14,16,17,18,19,22 * refer [1] for RTCM ver.2 *-----------------------------------------------------------------------------*/ extern int input_rtcm2(rtcm_t *rtcm, unsigned char data) { unsigned char preamb; int i; trace(5,"input_rtcm2: data=%02x\n",data); if ((data&0xC0)!=0x40) return 0; /* ignore if upper 2bit != 01 */ for (i=0;i<6;i++,data>>=1) { /* decode 6-of-8 form */ rtcm->word=(rtcm->word<<1)+(data&1); /* synchronize frame */ if (rtcm->nbyte==0) { preamb=(unsigned char)(rtcm->word>>22); if (rtcm->word&0x40000000) preamb^=0xFF; /* decode preamble */ if (preamb!=RTCM2PREAMB) continue; /* check parity */ if (!decode_word(rtcm->word,rtcm->buff)) continue; rtcm->nbyte=3; rtcm->nbit=0; continue; } if (++rtcm->nbit<30) continue; else rtcm->nbit=0; /* check parity */ if (!decode_word(rtcm->word,rtcm->buff+rtcm->nbyte)) { trace(2,"rtcm2 partity error: i=%d word=%08x\n",i,rtcm->word); rtcm->nbyte=0; rtcm->word&=0x3; continue; } rtcm->nbyte+=3; if (rtcm->nbyte==6) rtcm->len=(rtcm->buff[5]>>3)*3+6; if (rtcm->nbyte<rtcm->len) continue; rtcm->nbyte=0; rtcm->word&=0x3; /* decode rtcm2 message */ return decode_rtcm2(rtcm); }
static InternetAddress * decode_address (const char **in) { const char *inptr, *start, *word, *comment = NULL; InternetAddress *addr = NULL; gboolean has_lwsp = FALSE; gboolean is_word; GString *name; decode_lwsp (in); start = inptr = *in; name = g_string_new (""); /* Both groups and mailboxes can begin with a phrase (denoting * the display name for the address). Collect all of the * tokens that make up this name phrase. */ while (*inptr) { if ((word = decode_word (&inptr))) { g_string_append_len (name, word, (size_t) (inptr - word)); check_lwsp: word = inptr; skip_lwsp (&inptr); /* is the next token a word token? */ is_word = *inptr == '"' || is_atom (*inptr); if (inptr > word && is_word) { g_string_append_c (name, ' '); has_lwsp = TRUE; } if (is_word) continue; } /* specials = "(" / ")" / "<" / ">" / "@" ; Must be in quoted- * / "," / ";" / ":" / "\" / <"> ; string, to use * / "." / "[" / "]" ; within a word. */ if (*inptr == ':') { /* rfc2822 group */ inptr++; addr = decode_group (&inptr); decode_lwsp (&inptr); if (*inptr != ';') w(g_warning ("Invalid group spec, missing closing ';': %.*s", inptr - start, start)); else inptr++; break; } else if (*inptr == '<') { /* rfc2822 angle-addr */ inptr++; /* check for obsolete routing... */ if (*inptr != '@' || decode_route (&inptr)) { /* rfc2822 addr-spec */ addr = decode_addrspec (&inptr); } decode_lwsp (&inptr); if (*inptr != '>') { w(g_warning ("Invalid rfc2822 angle-addr, missing closing '>': %.*s", inptr - start, start)); while (*inptr && *inptr != '>' && *inptr != ',') inptr++; if (*inptr == '>') inptr++; } else { inptr++; } /* if comment is non-NULL, we can check for a comment containing a name */ comment = inptr; break; } else if (*inptr == '(') { /* beginning of a comment, use decode_lwsp() to skip past it */ decode_lwsp (&inptr); } else if (*inptr && strchr ("@,;", *inptr)) { if (name->len == 0) { if (*inptr == '@') { GString *domain; w(g_warning ("Unexpected address: %s: skipping.", start)); /* skip over @domain? */ inptr++; domain = g_string_new (""); decode_domain (&inptr, domain); g_string_free (domain, TRUE); } else { /* empty address */ } break; } else if (has_lwsp) { /* assume this is just an unquoted special that we should treat as part of the name */ w(g_warning ("Unquoted '%c' in address name: %s: ignoring.", *inptr, start)); g_string_append_c (name, *inptr); inptr++; goto check_lwsp; } addrspec: /* what we thought was a name was actually an addrspec? */ g_string_truncate (name, 0); inptr = start; addr = decode_addrspec (&inptr); /* if comment is non-NULL, we can check for a comment containing a name */ comment = inptr; break; } else if (*inptr == '.') { /* This would normally signify that we are * decoding the local-part of an addr-spec, * but sadly, it is common for broken mailers * to forget to quote/encode .'s in the name * phrase. */ g_string_append_c (name, *inptr); inptr++; goto check_lwsp; } else if (*inptr) { /* Technically, these are all invalid tokens * but in the interest of being liberal in * what we accept, we'll ignore them. */ w(g_warning ("Unexpected char '%c' in address: %s: ignoring.", *inptr, start)); g_string_append_c (name, *inptr); inptr++; goto check_lwsp; } else { goto addrspec; } } /* Note: will also skip over any comments */ decode_lwsp (&inptr); if (name->len == 0 && comment && inptr > comment) { /* missing a name, look for a trailing comment */ if ((comment = memchr (comment, '(', inptr - comment))) { const char *cend; /* find the end of the comment */ cend = inptr - 1; while (cend > comment && is_lwsp (*cend)) cend--; if (*cend == ')') cend--; g_string_append_len (name, comment + 1, (size_t) (cend - comment)); } } if (addr && name->len > 0) _internet_address_decode_name (addr, name); g_string_free (name, TRUE); *in = inptr; return addr; }
static InternetAddress * decode_addrspec (const char **in) { InternetAddress *mailbox = NULL; const char *start, *inptr, *word; gboolean got_local = FALSE; GString *addr; size_t len; addr = g_string_new (""); inptr = *in; decode_lwsp (&inptr); /* some spam bots set their addresses to stuff like: )[email protected] */ while (*inptr && !(*inptr == '"' || is_atom (*inptr))) inptr++; start = inptr; /* extract the first word of the local-part */ if ((word = decode_word (&inptr))) { g_string_append_len (addr, word, (size_t) (inptr - word)); decode_lwsp (&inptr); got_local = TRUE; } /* extract the rest of the local-part */ while (word && *inptr == '.') { /* Note: According to the spec, only a single '.' is * allowed between word tokens in the local-part of an * addr-spec token, but according to Evolution bug * #547969, some Japanese cellphones have email * addresses that look like [email protected] */ do { inptr++; decode_lwsp (&inptr); g_string_append_c (addr, '.'); } while (*inptr == '.'); if ((word = decode_word (&inptr))) g_string_append_len (addr, word, (size_t) (inptr - word)); decode_lwsp (&inptr); } if (*inptr == '@') { len = addr->len; g_string_append_c (addr, '@'); inptr++; if (!decode_domain (&inptr, addr)) { /* drop the @domain and continue as if it weren't there */ w(g_warning ("Missing domain in addr-spec: %.*s", inptr - start, start)); g_string_truncate (addr, len); } } else if (got_local) { w(g_warning ("Missing '@' and domain in addr-spec: %.*s", inptr - start, start)); } *in = inptr; if (!got_local) { w(g_warning ("Invalid addr-spec, missing local-part: %.*s", inptr - start, start)); g_string_free (addr, TRUE); return NULL; } mailbox = g_object_newv (INTERNET_ADDRESS_TYPE_MAILBOX, 0, NULL); ((InternetAddressMailbox *) mailbox)->addr = addr->str; g_string_free (addr, FALSE); return mailbox; }