const char * stristr(const char * str1, const char * str2) { if (!*str2) return str1; for (const char * cp = str1; *cp; cp++) { const char * s2 = str2; for (const char * s1 = cp; *s1 && *s2 && (IS_ALPHA(*s1) && IS_ALPHA(*s2)) ? !(TO_UPPER(*s1) - TO_UPPER(*s2)) : !(*s1 - *s2); s1++) ++s2; if (!*s2) return cp; } return nullptr; }
NLM_EXTERN size_t Nlm_stream2text(const Nlm_Char FAR PNTR str, size_t max_col, int PNTR dash) { const Nlm_Char FAR PNTR s; const Nlm_Char FAR PNTR sb; /* the nearest breakable position */ size_t n_lead = 0; size_t n_tail = 0; size_t len = Nlm_StringLen( str ); len = max_col < len ? max_col : len; *dash = 0; if (len == 0 || can_break(str[len-1], str[len])) return len; /* go to the beginning of the last completely fit word */ for (sb = &str[len-1]; sb != str && !IS_WHITESP(*sb) && !can_break(*sb, *(sb+1)); sb--) continue; while (sb != str && IS_WHITESP(*sb)) sb--; if (sb == str) { /* the first word is longer than "max_col" */ if (len > MAX_NO_DASH && IS_ALPHA(str[len-1]) && IS_ALPHA(str[len])) *dash = 1; /* recommend use dash in the place of last symbol */ return len; } /* decide of whether and how to break the last alphabet word */ /* count the lead and the tail of the last non-fit word */ for (s = &str[len]; *s != '\0' && IS_ALPHA(*s); s++, n_tail++) continue; for (s = &str[len-1]; IS_ALPHA(*s); s--, n_lead++) continue; ASSERT ( s > str ); /* try to "move" symbols from lead in the sake of tail */ while (n_lead > MIN_LEAD && n_tail < MIN_TAIL) { n_lead--; n_tail++; } if (n_lead < MIN_LEAD || n_tail < MIN_TAIL) { /* no luck this time -- move the whole non-fit word to the next line */ return (sb - str + 1); } else { *dash = 1; return (s - str + n_lead + 1); } }
static char * dir_ConvertDescriptionToPrefName(DIR_Server * server) { #define MAX_PREF_NAME_SIZE 25 char * fileName = nsnull; char fileNameBuf[MAX_PREF_NAME_SIZE]; PRInt32 srcIndex = 0; PRInt32 destIndex = 0; PRInt32 numSrcBytes = 0; const char * descr = nsnull; if (server && server->description) { descr = server->description; numSrcBytes = PL_strlen(descr); while (srcIndex < numSrcBytes && destIndex < MAX_PREF_NAME_SIZE-1) { if (IS_DIGIT(descr[srcIndex]) || IS_ALPHA(descr[srcIndex])) { fileNameBuf[destIndex] = descr[srcIndex]; destIndex++; } srcIndex++; } fileNameBuf[destIndex] = '\0'; /* zero out the last character */ } if (destIndex) /* have at least one character in the file name? */ fileName = strdup(fileNameBuf); return fileName; }
/* * [RFC4871] * hyphenated-word = ALPHA [ *(ALPHA / DIGIT / "-") (ALPHA / DIGIT) ] */ int XSkip_hyphenatedWord(const char *head, const char *tail, const char **nextp) { const char *p = head; *nextp = p; // 先頭の文字は ALPHA if (tail <= p || !IS_ALPHA(*p)) { return *nextp - head; } // end if for (++p; p < tail; ++p) { if (IS_LET_DIG(*p)) { *nextp = p; continue; } // end if if ('-' == *p) { // '-' は終端にならない continue; } // end if break; } // end for ++(*nextp); return *nextp - head; } // end function : XSkip_hyphenatedWord
static int match_range_longchar(longchar * a, longchar * b, longchar * c, int ignore) { #ifdef USE_M17N if (a->type != b->type || a->type != c->type) return 0; if (a->type == RE_TYPE_WCHAR_T) { if (a->wch.ccs != c->wch.ccs || c->wch.ccs != b->wch.ccs) return 0; #ifdef USE_UNICODE if (ignore) { wc_uint32 uc = wc_any_to_ucs(c->wch); if (wc_is_ucs_alpha(uc)) { wc_uint32 ua = wc_any_to_ucs(a->wch); wc_uint32 ub = wc_any_to_ucs(b->wch); wc_uint32 upper = wc_ucs_toupper(uc); wc_uint32 lower = wc_ucs_tolower(uc); wc_uint32 title = wc_ucs_totitle(uc); return ((ua <= upper && upper <= ub) || (ua <= lower && lower <= ub) || (ua <= title && title <= ub)); } } #endif return (a->wch.code <= c->wch.code && c->wch.code <= b->wch.code); } #endif if (ignore && IS_ALPHA(c->ch)) return ((a->ch <= TOLOWER(c->ch) && TOLOWER(c->ch) <= b->ch) || (a->ch <= TOUPPER(c->ch) && TOUPPER(c->ch) <= b->ch)); else return (a->ch <= c->ch && c->ch <= b->ch); }
static BioseqPtr DOT_GetBspFromGIOrAcc(CharPtr str) { BioseqPtr bsp; Int4 gi; Char ptr; SeqIdPtr sip; ValNode vn; LinkSetPtr lsp; Int4 uid; str = TrimSpacesAroundString(str); ptr = *str; if (IS_ALPHA(ptr)) /* accession */ { sip = SeqIdFromAccessionDotVersion(str); bsp = BioseqLockById(sip); } else /* it's a GI */ { gi = atoi(str); vn.choice = SEQID_GI; vn.data.intvalue = gi; vn.next = NULL; bsp = BioseqLockById(&vn); } return bsp; }
/***************************************************************************** * CkLabelType: * checks /label=,feature_label> or /label=<base_range> * -Tatiana 1/28/95 ******************************************************************************/ NLM_EXTERN CharPtr CkLabelType(CharPtr str) { Boolean range = TRUE, label = TRUE; CharPtr bptr; if (IS_DIGIT(*str)) { for (; IS_DIGIT(*str); str++) continue; if (*str == '.' && *(str+1) == '.') { str += 2; if (!IS_DIGIT(*str)) { range = FALSE; } else { while (IS_DIGIT(*str)) { str++; } } if (*str != '\0') { range = FALSE; } } else { range = FALSE; } } if (!range) { bptr = str; for (; *str != '\0' && !IS_ALPHA(*str); str++) continue; if (*str == '\0') { label = FALSE; /* must be at least one letter */ } for (str = bptr; *str != '\0' && IS_ALPHA(*str) || IS_DIGIT(*str) || *str == '-' || *str == '_' || *str == '\'' || *str == '*'; str++) continue; if (*str != '\0') { label = FALSE; } } if (range || label) { return NULL; } else { return str; } }
/* * Convert a string into a valid C identifier by replacing invalid * characters with '_'. Also makes sure the string is nul-terminated * and takes up at most n bytes. */ void strident_canon(char *s, size_t n) { char c; char *end = s + n - 1; if ((c = *s) == 0) return; if (!IS_ALPHA(c) && c != '_') *s = '_'; while (s < end && ((c = *(++s)) != 0)) { if (!IS_ALPHA(c) && !IS_DIGIT(c) && c != '_') *s = '_'; } *s = 0; }
/*************************************************************************** * * SPI_ReadFeatureTable reads in a tab-delimited file and converts it * to feature information: * * sequence id name of feature start stop * NM_004377.1 repetitive_region 12 40 * * Masking and other feature information for all mRNAs should be in the * same file; ids not in the mRNA list or unknown feature names will be * ignored. * ***************************************************************************/ static void SPI_ReadFeatureTable(FILE *ifp, SPI_bsinfoPtr spim_head) { Char c; CharPtr fields[5]; Boolean found; Char line[60]; Int4 i; CharPtr ptr; SeqIdPtr sip; SeqLocPtr slp; SPI_bsinfoPtr spim; CharPtr str; ValNode vn; str = ReadALine(line, sizeof(line), ifp); while (str != NULL) { ptr = strtok(str, " \t"); for (i=0; i<4; i++) { fields[i] = StringSave(ptr); ptr = strtok(NULL, " \t"); } if (fields[1] != NULL && !StrCmp(fields[1], "repetitive_region")) { c = *fields[0]; if (IS_ALPHA(c)) sip = SeqIdFromAccessionDotVersion(fields[0]); else { vn.choice = SEQID_GI; vn.data.intvalue = atoi(fields[0]); vn.next = NULL; sip = &vn; } spim = spim_head; found = FALSE; while (!found && spim != NULL) { if (SeqIdIn(sip, spim->bsp->id) == TRUE) found = TRUE; else spim = spim->next; } if (found) { slp = SeqLocIntNew(atoi(fields[2]), atoi(fields[3]), Seq_strand_both, spim->bsp->id); slp->next = spim->lcaseloc; spim->lcaseloc = slp; } } str = ReadALine(line, sizeof(line), ifp); } }
static int is_valid_ident(const char *s, const char *e, int allowdot) { char c; if (s >= e) return (0); /* name is empty */ c = *s++; if (!IS_ALPHA(c)) return (0); /* does not start with letter */ while (s < e && (c = *s++) != 0) { if (IS_ALPHA(c) || IS_DIGIT(c) || c == '-' || c == '_' || (allowdot && c == '.')) continue; return (0); /* invalid character */ } return (1); }
/************************************************************************* *** * gb_id_make(): make the Seq-id for Genbank with tsip->name = name * tsip->acc. * ************************************************************************* ***/ NLM_EXTERN SeqIdPtr gb_id_make(CharPtr name, CharPtr acc) { SeqIdPtr new_id; TextSeqIdPtr tsip; new_id= (SeqIdPtr)ValNodeNew(NULL); new_id->choice = SEQID_GENBANK; tsip = TextSeqIdNew(); if(name) { if(StringLen(name) >3 && IS_ALPHA(name[0])) tsip->name = StringSave(name); } if(acc) { if(StringLen(acc) >3 && IS_ALPHA(acc[0])) tsip->accession = StringSave(acc); } new_id->data.ptrvalue = tsip; return new_id; }
/* * [RFC4408] * name = ALPHA *( ALPHA / DIGIT / "-" / "_" / "." ) */ int XSkip_spfName(const char *head, const char *tail, const char **nextp) { const char *p = head; // 先頭の文字は ALPHA if (tail <= p || !IS_ALPHA(*p)) { *nextp = p; return *nextp - head; } // end if for (++p; p < tail && IS_SPF_NAME(*p); ++p); *nextp = p; return *nextp - head; } // end function : XSkip_spfName
/* * [RFC4871] * x-sig-a-tag-k = ALPHA *(ALPHA / DIGIT) ; for later extension * x-sig-a-tag-h = ALPHA *(ALPHA / DIGIT) ; for later extension */ int XSkip_alphaAlnum(const char *head, const char *tail, const char **nextp) { const char *p = head; // 先頭の文字は ALPHA if (tail <= p || !IS_ALPHA(*p)) { *nextp = p; return *nextp - head; } // end if for (++p; p < tail && IS_ALNUM(*p); ++p); *nextp = p; return *nextp - head; } // end function : XSkip_alphaAlnum
NLM_EXTERN Nlm_CharPtr LIBCALL Nlm_text2stream(const Nlm_Char FAR PNTR str) { int on_space = 0; Nlm_CharPtr line, s; if ( !str ) return NULL; while (*str && IS_WHITESP( *str )) str++; if ( !*str ) return NULL; s = line = (Nlm_CharPtr) Nlm_MemNew(Nlm_StringLen(str) + 1); for ( ; *str; str++) { if ( IS_WHITESP(*str) ) { if (*str == '\n') *s = '\n'; on_space = 1; } else { if ( on_space ) { if (*s == '\n' && s - line > 1 && *(s-1) == '-' && IS_ALPHA(*(s-2))) { *s = '\0'; s--; /* eat dash before end-of-line, merge the broken word */ } else *s++ = SPACE; *s++ = *str; on_space = 0; } else *s++ = *str; } } *s = '\0'; return (Nlm_CharPtr) realloc(line, Nlm_StringLen(line) + 1); }
/** * Reads a name from the cache * * Description: * Name ::= NameStartChar (NameChar)* * NameStartChar ::= ":" | [A-Z] | "_" | [a-z] //add "?" * NameChar ::= NameStartChar | "-" | "." | [0-9] * @param var * @return RES_OK if the char was skipped, RES_EOF if no more tags, errors.. */ RES_CODE CCache::get_name(CSTRING& var) { char ch; RES_CODE res; res = get_pc(ch); if (res == RES_OK) { if (ch == ':' || ch == '_' || ch == '?' || IS_ALPHA(ch)) { var += ch; while (!var.empty()) { res = getc(ch); switch (res) { case RES_OK: if (ch == ':' || ch == '_' || ch == '-' || ch == '.' || IS_ALPHANUM(ch)) { var += ch; } else { ungetc(); return RES_OK; } break; case RES_EOF: return RES_OK; default: return (res); } } return RES_OUT_OF_MEMORY; } ungetc(); res = RES_INVALID_DATA; } return (res); }
static int match_longchar(longchar * a, longchar * b, int ignore) { #ifdef USE_M17N if (a->type != b->type) return 0; if (a->type == RE_TYPE_WCHAR_T) { #ifdef USE_UNICODE if (ignore) { wc_uint32 ua = wc_any_to_ucs(a->wch), ub = wc_any_to_ucs(b->wch); return (ua == ub || ua == wc_ucs_tolower(ub) || ua == wc_ucs_toupper(ub) || ua == wc_ucs_totitle(ub)); } #endif return (a->wch.ccs == b->wch.ccs) && (a->wch.code == b->wch.code); } #endif if (ignore && IS_ALPHA(b->ch)) return (a->ch == TOLOWER(b->ch) || a->ch == TOUPPER(b->ch)); else return a->ch == b->ch; }
/* * [RFC5234] * ALPHA = %x41-5A / %x61-7A ; A-Z / a-z */ int XSkip_alpha(const char *head, const char *tail, const char **nextp) { *nextp = (head < tail && IS_ALPHA(*head)) ? head + 1 : head; return *nextp - head; } // end function : XSkip_alpha
Int4 BE_ReadIds(BEDataPtr pBdata, Uint4 **ids_out) { Uint4 *uids, *giptr; Int4 length, NumNotValid = 0, gi; Int4 i, j, k, allocated, count = 0; Char TmpBuff[16]; CharPtr buffer; if((buffer = pBdata->uids) == NULL || *buffer == NULLB) { *ids_out = NULL; return 0; } length = StringLen(buffer); allocated = UID_BUFF_SIZE; uids = (Uint4 *)MemNew(allocated * sizeof(Uint4)); for(i = 0; i < length; i++) { if(isspace(buffer[i]) || buffer[i] == ',') /* Rolling spaces */ continue; /* This is defence from badly formatted requests */ if(NumNotValid > 10) { printf("**** ERROR: Too many invalid Gis/Accessions, " "parsing aborted\n"); *ids_out = NULL; return 0; } /* Rolling spaces */ j= 0; while (!isspace(buffer[i]) && j < 10 && i < length) { TmpBuff[j] = buffer[i]; j++; i++; if(buffer[i] == ',') /* Comma is valid delimiter */ break; } TmpBuff[j] = NULLB; /* Ignore strings like ">Protein" */ if(j > 0 && TmpBuff[0] == '>' && IS_ALPHA(TmpBuff[1])) continue; /* Is gi/accession too long ??? */ if(j == 10) { NumNotValid++; while(!isspace(buffer[i]) || buffer[i] == ',' || buffer[i] == NULLB) /* Rolling until spaces */ i++; continue; /* Next may be valid ... who knows...?? */ } /* Now validating accession/gi */ for(k =0; k < j; k++) { if(!isdigit(TmpBuff[k])) { break; } } if(k != j) { if(!IS_ntdb_accession(TmpBuff) && !IS_protdb_accession(TmpBuff)) { NumNotValid++; printf("**** WARNING: Gi/Accession \"%s\" is not valid\n", TmpBuff); continue; } } /* If this is valid Accession check and tranfer it to gi */ giptr = NULL; if((gi = BEAccessionToGi (TmpBuff)) < 0) { printf("**** WARNING: Gi/Accession %s is not found " "in database----\r\n", TmpBuff); /* NumNotValid++; */ continue; } else { if(count == allocated) { allocated += UID_BUFF_SIZE; uids = (Uint4*)Realloc(uids, allocated * sizeof(Uint4)); } uids[count] = gi; count++; } } if(NumNotValid) { printf("**** %d invalid Gi%s/Accession%s present in Entrez-batch " "request\r\n", (int)NumNotValid, NumNotValid == 1 ? "" : "s", NumNotValid == 1 ? "" : "s" ); } *ids_out = uids; return count; }
/** * Identifies the next token in the input stream. When the function starts, the * cursor points to the beginning of the token to identify. When the function * returns, the cursor points to the beginning of the next token, one character * past the end of the current token. The return value is an enum indicating * the identified token's type. Since this function also identifies non-syntax * elements such as whitespace and comments, additional filtering may be useful. */ Token lex(char const **p, char const *end) { if (end <= *p) { return LEX_END; /* Whitespace: */ } else if (IS_SPACE(**p)) { do { ++*p; } while (*p < end && IS_SPACE(**p)); return LEX_WHITESPACE; /* Newline: */ } else if (**p == '\n' || **p == '\f') { ++*p; return LEX_NEWLINE; } else if (**p == '\r') { ++*p; if (*p < end && **p == '\n') ++*p; return LEX_NEWLINE; /* Comments: */ } else if (**p == '/') { ++*p; if (end <= *p) return LEX_SLASH; /* C++ style comments: */ if (**p == '/') { do { ++*p; } while (*p < end && !IS_NEWLINE(**p)); return LEX_COMMENT; /* C style comments: */ } else if (**p == '*') { do { do { ++*p; if (end <= *p) return LEX_ERROR_END; } while (**p != '*'); do { ++*p; if (end <= *p) return LEX_ERROR_END; } while (**p == '*'); } while (**p != '/'); ++*p; return LEX_COMMENT; /* Lone slash: */ } else { return LEX_SLASH; } /* Double-quoted string literal: */ } else if (**p == '\"') { do { ++*p; if (end <= *p) return LEX_ERROR_END; if (**p == '\\') { ++*p; if (end <= *p) return LEX_ERROR_END; ++*p; if (end <= *p) return LEX_ERROR_END; } } while (**p != '\"'); ++*p; return LEX_STRING; /* Single-quoted character literal: */ } else if (**p == '\'') { do { ++*p; if (end <= *p) return LEX_ERROR_END; if (**p == '\\') { ++*p; if (end <= *p) return LEX_ERROR_END; ++*p; if (end <= *p) return LEX_ERROR_END; } } while (**p != '\''); ++*p; return LEX_CHAR; /* Numeric literals (including malformed ones, which are ignored): */ } else if ('0' <= **p && **p <= '9') { do { ++*p; } while (*p < end && IS_ALPHANUM(**p)); return LEX_NUMBER; /* Identifiers: */ } else if (IS_ALPHA(**p)) { do { ++*p; } while (*p < end && IS_ALPHANUM(**p)); return LEX_IDENTIFIER; /* Token-pasting: */ } else if (**p == '\\') { ++*p; if (end <= *p) return LEX_BACKSLASH; if (**p == '\\') { ++*p; return LEX_PASTE; } else if (**p == 'o') { ++*p; if (*p < end && **p == 'l') { ++*p; return LEX_ESCAPE; } else { --*p; return LEX_BACKSLASH; } } return LEX_BACKSLASH; /* Symbols: */ } else if (**p == '!') { ++*p; return LEX_BANG; } else if (**p == '&') { ++*p; return LEX_AMP; } else if (**p == '(') { ++*p; return LEX_PAREN_L; } else if (**p == ')') { ++*p; return LEX_PAREN_R; } else if (**p == '*') { ++*p; return LEX_STAR; } else if (**p == ',') { ++*p; return LEX_COMMA; } else if (**p == '.') { ++*p; return LEX_DOT; /* LEX_SLASH was recognized earlier. */ } else if (**p == ';') { ++*p; return LEX_SEMICOLON; } else if (**p == '<') { ++*p; return LEX_LT; } else if (**p == '=') { ++*p; return LEX_EQUALS; } else if (**p == '>') { ++*p; return LEX_GT; /* LEX_BACKSLASH was recognized earlier. */ } else if (**p == '{') { ++*p; return LEX_BRACE_L; } else if (**p == '|') { ++*p; return LEX_PIPE; } else if (**p == '}') { ++*p; return LEX_BRACE_R; /* Any other character: */ } else { ++*p; return LEX_ERROR; } }
/* Initialise: Open the Android NVM device and find the partitions on it. Save them in a list along with the "PartitionName" fields for their GPT entries. We will use these partition names as the key in ArmFastbootPlatformFlashPartition. */ EFI_STATUS ArmFastbootPlatformInit ( VOID ) { EFI_STATUS Status; EFI_DEVICE_PATH_PROTOCOL *FlashDevicePath; EFI_DEVICE_PATH_PROTOCOL *FlashDevicePathDup; EFI_DEVICE_PATH_PROTOCOL *DevicePath; EFI_DEVICE_PATH_PROTOCOL *NextNode; HARDDRIVE_DEVICE_PATH *PartitionNode; UINTN NumHandles; EFI_HANDLE *AllHandles; UINTN LoopIndex; EFI_HANDLE FlashHandle; EFI_BLOCK_IO_PROTOCOL *FlashBlockIo; EFI_PARTITION_ENTRY *PartitionEntries; FASTBOOT_PARTITION_LIST *Entry; InitializeListHead (&mPartitionListHead); // // Get EFI_HANDLES for all the partitions on the block devices pointed to by // PcdFastbootFlashDevicePath, also saving their GPT partition labels. // There's no way to find all of a device's children, so we get every handle // in the system supporting EFI_BLOCK_IO_PROTOCOL and then filter out ones // that don't represent partitions on the flash device. // FlashDevicePath = ConvertTextToDevicePath ((CHAR16*)FixedPcdGetPtr (PcdAndroidFastbootNvmDevicePath)); // // Open the Disk IO protocol on the flash device - this will be used to read // partition names out of the GPT entries // // Create another device path pointer because LocateDevicePath will modify it. FlashDevicePathDup = FlashDevicePath; Status = gBS->LocateDevicePath (&gEfiBlockIoProtocolGuid, &FlashDevicePathDup, &FlashHandle); if (EFI_ERROR (Status)) { DEBUG ((EFI_D_ERROR, "Warning: Couldn't locate Android NVM device (status: %r)\n", Status)); // Failing to locate partitions should not prevent to do other Android FastBoot actions return EFI_SUCCESS; } Status = gBS->OpenProtocol ( FlashHandle, &gEfiBlockIoProtocolGuid, (VOID **) &FlashBlockIo, gImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL ); if (EFI_ERROR (Status)) { DEBUG ((EFI_D_ERROR, "Fastboot platform: Couldn't open Android NVM device (status: %r)\n", Status)); return EFI_DEVICE_ERROR; } // Read the GPT partition entry array into memory so we can get the partition names Status = ReadPartitionEntries (FlashBlockIo, &PartitionEntries); if (EFI_ERROR (Status)) { DEBUG ((EFI_D_ERROR, "Warning: Failed to read partitions from Android NVM device (status: %r)\n", Status)); // Failing to locate partitions should not prevent to do other Android FastBoot actions return EFI_SUCCESS; } // Get every Block IO protocol instance installed in the system Status = gBS->LocateHandleBuffer ( ByProtocol, &gEfiBlockIoProtocolGuid, NULL, &NumHandles, &AllHandles ); ASSERT_EFI_ERROR (Status); // Filter out handles that aren't children of the flash device for (LoopIndex = 0; LoopIndex < NumHandles; LoopIndex++) { // Get the device path for the handle Status = gBS->OpenProtocol ( AllHandles[LoopIndex], &gEfiDevicePathProtocolGuid, (VOID **) &DevicePath, gImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL ); ASSERT_EFI_ERROR (Status); // Check if it is a sub-device of the flash device if (!CompareMem (DevicePath, FlashDevicePath, FLASH_DEVICE_PATH_SIZE (FlashDevicePath))) { // Device path starts with path of flash device. Check it isn't the flash // device itself. NextNode = NextDevicePathNode (DevicePath); if (IsDevicePathEndType (NextNode)) { continue; } // Assert that this device path node represents a partition. ASSERT (NextNode->Type == MEDIA_DEVICE_PATH && NextNode->SubType == MEDIA_HARDDRIVE_DP); PartitionNode = (HARDDRIVE_DEVICE_PATH *) NextNode; // Assert that the partition type is GPT. ReadPartitionEntries checks for // presence of a GPT, so we should never find MBR partitions. // ("MBRType" is a misnomer - this field is actually called "Partition // Format") ASSERT (PartitionNode->MBRType == MBR_TYPE_EFI_PARTITION_TABLE_HEADER); // The firmware may install a handle for "partition 0", representing the // whole device. Ignore it. if (PartitionNode->PartitionNumber == 0) { continue; } // // Add the partition handle to the list // // Create entry Entry = AllocatePool (sizeof (FASTBOOT_PARTITION_LIST)); if (Entry == NULL) { Status = EFI_OUT_OF_RESOURCES; FreePartitionList (); goto Exit; } // Copy handle and partition name Entry->PartitionHandle = AllHandles[LoopIndex]; StrnCpy ( Entry->PartitionName, PartitionEntries[PartitionNode->PartitionNumber - 1].PartitionName, // Partition numbers start from 1. PARTITION_NAME_MAX_LENGTH ); InsertTailList (&mPartitionListHead, &Entry->Link); // Print a debug message if the partition label is empty or looks like // garbage. if (!IS_ALPHA (Entry->PartitionName[0])) { DEBUG ((EFI_D_ERROR, "Warning: Partition %d doesn't seem to have a GPT partition label. " "You won't be able to flash it with Fastboot.\n", PartitionNode->PartitionNumber )); } } } Exit: FreePool (PartitionEntries); FreePool (FlashDevicePath); FreePool (AllHandles); return Status; }
NLM_EXTERN Int4 print_protein_for_cds(SeqFeatPtr sfp, CharPtr buf, SeqLocPtr loc, Boolean reverse_minus) { CdRegionPtr crp; Int4 frame_offset, start_offset; Uint1 f_strand; Boolean reverse; Int4 cd_len; GatherRange gr; Int2 p_pos, buf_len; Int4 a_left, a_right; Int4 aa, val; SeqLocPtr slp; SeqPortPtr spp; ByteStorePtr p_data; Int4 end_pos, start_pos = -1; Uint1 residue; Boolean seal_ends = FALSE; Boolean reverse_order; if(sfp == NULL || sfp->data.choice != 3) return -1; if(buf == NULL || loc == NULL) return -1; crp = sfp->data.value.ptrvalue; if(crp == NULL) return -1; if(buf[0] == '\0') seal_ends = TRUE; spp = NULL; p_data = NULL; if(sfp->product !=NULL && !IS_BOGO_Product(sfp->ext)) { spp = SeqPortNewByLoc(sfp->product, Seq_code_ncbieaa); if(spp !=NULL) { SeqPortSeek(spp, 0, SEEK_SET); end_pos = spp->totlen-1; } } if(spp == NULL) { p_data = ProteinFromCdRegion(sfp, TRUE); /* p_data = ProteinFromCdRegion(sfp, FALSE); */ if(p_data !=NULL) { BSSeek(p_data, 0, SEEK_SET); end_pos = BSLen(p_data)-1; } } if(spp == NULL && p_data == NULL) return -1; if(crp->frame == 0) frame_offset = 0; else frame_offset = (Int4)crp->frame-1; start_offset = frame_offset; f_strand = SeqLocStrand(sfp->location); reverse = ck_reverse(f_strand, SeqLocStrand(loc)); /*if reverse == TRUE, the translated protein is written backwards*/ if(reverse && reverse_minus) reverse_order = TRUE; else reverse_order = FALSE; slp = NULL; cd_len = 0; aa = 0; buf_len = SeqLocLen(loc); if(reverse_order) { p_pos = buf_len -1; if(seal_ends) { buf[p_pos+1] = '\0'; seal_ends = FALSE; } } else p_pos = 0; while((slp = SeqLocFindNext(sfp->location, slp))!=NULL) { if(SeqLocOffset(loc, slp, &gr, 0)) { if(reverse_order) { if(gr.right < p_pos) p_pos = (Int2)(gr.right); } else { if(p_pos < gr.left) p_pos = (Int2)(gr.left); } SeqLocOffset(slp, loc, &gr, 0); a_left = gr.left + cd_len; a_right = gr.right + cd_len; /* if(reverse_order) { temp = a_right; a_right = -a_left; a_left = -temp; } */ for(; a_left<=a_right; ++a_left) { val = ABS(a_left) - start_offset; aa = val/3; if(aa < 0 || aa > end_pos)/*stop & partial codon*/ { buf[p_pos] = '^'; } else { if(val%3==1)/*label aa in the middle of 3-bp codon*/ { if(start_pos == -1) start_pos = aa; if(spp !=NULL) { SeqPortSeek(spp, aa, SEEK_SET); residue = SeqPortGetResidue(spp); } else { BSSeek(p_data, aa, SEEK_SET); residue = (Uint1)BSGetByte(p_data); } if(IS_ALPHA(residue) || residue == '*' || residue == '-') buf[p_pos] = residue; else buf[p_pos] = '?'; } else buf[p_pos] = ' '; } if(reverse_order) -- p_pos; else { ++p_pos; if (p_pos > buf_len) break; } } } cd_len += SeqLocLen(slp); /*frame_offset = (cd_len - start_offset)%3; if(frame_offset > 0) --frame_offset;*/ } if(spp != NULL) SeqPortFree(spp); if(p_data != NULL) BSFree(p_data); if(p_pos == 0) /*all the residues are introns*/ { if(seal_ends) { end_pos = buf_len; MemSet((Pointer)buf, '~', (size_t)(end_pos) * sizeof(Char)); buf[end_pos] = '\0'; } } else { if(seal_ends) { buf[p_pos] = '\0'; } if(start_pos == -1) start_pos = aa; } return start_pos; }
int cfg_get_token(cfg_token_t* token, cfg_parser_t* st, unsigned int flags) { static int look_ahead = EOF; int c; enum st state; state = ST_S; token->val.s = token->buf; token->val.len = 0; if (look_ahead != EOF) { c = look_ahead; look_ahead = EOF; } else { READ_CHAR; } while(c != EOF) { switch(state) { case ST_S: if (flags & CFG_EXTENDED_ALPHA) { if (IS_WHITESPACE(c)) { /* Do nothing */ } else if (IS_ALPHA(c) || IS_ESCAPE(c) || IS_DELIM(c)) { PUSH(c); state = ST_A; } else if (IS_QUOTE(c)) { state = ST_Q; } else if (IS_COMMENT(c)) { state = ST_C; } else if (IS_EOL(c)) { PUSH(c); RETURN(c); } else { ERR("%s:%d:%d: Invalid character 0x%x\n", st->file, st->line, st->col, c); return -1; } } else { if (IS_WHITESPACE(c)) { /* Do nothing */ } else if (IS_ALPHA(c)) { PUSH(c); state = ST_A; } else if (IS_QUOTE(c)) { state = ST_Q; } else if (IS_COMMENT(c)) { state = ST_C; } else if (IS_ESCAPE(c)) { state = ST_E; } else if (IS_DELIM(c) || IS_EOL(c)) { PUSH(c); RETURN(c); } else { ERR("%s:%d:%d: Invalid character 0x%x\n", st->file, st->line, st->col, c); return -1; } } break; case ST_A: if (flags & CFG_EXTENDED_ALPHA) { if (IS_ALPHA(c) || IS_DELIM(c) || IS_QUOTE(c)) { PUSH(c); } else if (IS_ESCAPE(c)) { state = ST_AE; } else if (IS_COMMENT(c) || IS_EOL(c) || IS_WHITESPACE(c)) { look_ahead = c; RETURN(CFG_TOKEN_ALPHA); } else { ERR("%s:%d:%d: Invalid character 0x%x\n", st->file, st->line, st->col, c); return -1; } } else { if (IS_ALPHA(c)) { PUSH(c); } else if (IS_ESCAPE(c)) { state = ST_AE; } else if (IS_WHITESPACE(c) || IS_DELIM(c) || IS_QUOTE(c) || IS_COMMENT(c) || IS_EOL(c)) { look_ahead = c; RETURN(CFG_TOKEN_ALPHA); } else { ERR("%s:%d:%d: Invalid character 0x%x\n", st->file, st->line, st->col, c); return -1; } } break; case ST_AE: if (IS_COMMENT(c) || IS_QUOTE(c) || IS_ESCAPE(c)) { PUSH(c); } else if (c == 'r') { PUSH('\r'); } else if (c == 'n') { PUSH('\n'); } else if (c == 't') { PUSH('\t'); } else if (c == ' ') { PUSH(' '); } else if (IS_EOL(c)) { /* Do nothing */ } else { ERR("%s:%d:%d: Unsupported escape character 0x%x\n", st->file, st->line, st->col, c); return -1; } state = ST_A; break; case ST_Q: if (IS_QUOTE(c)) { RETURN(CFG_TOKEN_STRING); } else if (IS_ESCAPE(c)) { state = ST_QE; break; } else { PUSH(c); } break; case ST_QE: if (IS_ESCAPE(c) || IS_QUOTE(c)) { PUSH(c); } else if (c == 'n') { PUSH('\n'); } else if (c == 'r') { PUSH('\r'); } else if (c == 't') { PUSH('\t'); } else if (IS_EOL(c)) { /* Do nothing */ } else { ERR("%s:%d:%d: Unsupported escape character 0x%x\n", st->file, st->line, st->col, c); return -1; } state = ST_Q; break; case ST_C: if (IS_ESCAPE(c)) { state = ST_CE; } else if (IS_EOL(c)) { state = ST_S; continue; /* Do not read a new char, return EOL */ } else { /* Do nothing */ } break; case ST_CE: state = ST_C; break; case ST_E: if (IS_COMMENT(c) || IS_QUOTE(c) || IS_ESCAPE(c)) { PUSH(c); RETURN(c); } else if (c == 'r') { PUSH('\r'); RETURN('\r'); } else if (c == 'n') { PUSH('\n'); RETURN('\n'); } else if (c == 't') { PUSH('\t'); RETURN('\t'); } else if (c == ' ') { PUSH(' '); RETURN(' '); } else if (IS_EOL(c)) { /* Escped eol means no eol */ state = ST_S; } else { ERR("%s:%d:%d: Unsupported escape character 0x%x\n", st->file, st->line, st->col, c); return -1; } break; } READ_CHAR; }; switch(state) { case ST_S: case ST_C: case ST_CE: return 1; case ST_A: RETURN(CFG_TOKEN_ALPHA); case ST_Q: ERR("%s:%d:%d: Premature end of file, missing closing quote in" " string constant\n", st->file, st->line, st->col); return -1; case ST_QE: case ST_E: case ST_AE: ERR("%s:%d:%d: Premature end of file, missing escaped character\n", st->file, st->line, st->col); return -1; } BUG("%s:%d:%d: Invalid state %d\n", st->file, st->line, st->col, state); return -1; }
size_t http_parser_execute (http_parser *parser, const http_parser_settings *settings, const char *data, size_t len) { char c, ch; int8_t unhex_val; const char *p = data, *pe; int64_t to_read; enum state state; enum header_states header_state; uint64_t index = parser->index; uint64_t nread = parser->nread; /* We're in an error state. Don't bother doing anything. */ if (HTTP_PARSER_ERRNO(parser) != HPE_OK) { return 0; } state = (enum state) parser->state; header_state = (enum header_states) parser->header_state; if (len == 0) { switch (state) { case s_body_identity_eof: CALLBACK2(message_complete); return 0; case s_dead: case s_start_req_or_res: case s_start_res: case s_start_req: return 0; default: SET_ERRNO(HPE_INVALID_EOF_STATE); return 1; } } /* technically we could combine all of these (except for url_mark) into one variable, saving stack space, but it seems more clear to have them separated. */ const char *header_field_mark = 0; const char *header_value_mark = 0; const char *url_mark = 0; if (state == s_header_field) header_field_mark = data; if (state == s_header_value) header_value_mark = data; if (state == s_req_path || state == s_req_schema || state == s_req_schema_slash || state == s_req_schema_slash_slash || state == s_req_port || state == s_req_query_string_start || state == s_req_query_string || state == s_req_host || state == s_req_fragment_start || state == s_req_fragment) url_mark = data; for (p=data, pe=data+len; p != pe; p++) { ch = *p; if (PARSING_HEADER(state)) { ++nread; /* Buffer overflow attack */ if (nread > HTTP_MAX_HEADER_SIZE) { SET_ERRNO(HPE_HEADER_OVERFLOW); goto error; } } switch (state) { case s_dead: /* this state is used after a 'Connection: close' message * the parser will error out if it reads another message */ SET_ERRNO(HPE_CLOSED_CONNECTION); goto error; case s_start_req_or_res: { if (ch == CR || ch == LF) break; parser->flags = 0; parser->content_length = -1; CALLBACK2(message_begin); if (ch == 'H') state = s_res_or_resp_H; else { parser->type = HTTP_REQUEST; goto start_req_method_assign; } break; } case s_res_or_resp_H: if (ch == 'T') { parser->type = HTTP_RESPONSE; state = s_res_HT; } else { if (ch != 'E') { SET_ERRNO(HPE_INVALID_CONSTANT); goto error; } parser->type = HTTP_REQUEST; parser->method = HTTP_HEAD; index = 2; state = s_req_method; } break; case s_start_res: { parser->flags = 0; parser->content_length = -1; CALLBACK2(message_begin); switch (ch) { case 'H': state = s_res_H; break; case CR: case LF: break; default: SET_ERRNO(HPE_INVALID_CONSTANT); goto error; } break; } case s_res_H: STRICT_CHECK(ch != 'T'); state = s_res_HT; break; case s_res_HT: STRICT_CHECK(ch != 'T'); state = s_res_HTT; break; case s_res_HTT: STRICT_CHECK(ch != 'P'); state = s_res_HTTP; break; case s_res_HTTP: STRICT_CHECK(ch != '/'); state = s_res_first_http_major; break; case s_res_first_http_major: if (ch < '1' || ch > '9') { SET_ERRNO(HPE_INVALID_VERSION); goto error; } parser->http_major = ch - '0'; state = s_res_http_major; break; /* major HTTP version or dot */ case s_res_http_major: { if (ch == '.') { state = s_res_first_http_minor; break; } if (!IS_NUM(ch)) { SET_ERRNO(HPE_INVALID_VERSION); goto error; } parser->http_major *= 10; parser->http_major += ch - '0'; if (parser->http_major > 999) { SET_ERRNO(HPE_INVALID_VERSION); goto error; } break; } /* first digit of minor HTTP version */ case s_res_first_http_minor: if (!IS_NUM(ch)) { SET_ERRNO(HPE_INVALID_VERSION); goto error; } parser->http_minor = ch - '0'; state = s_res_http_minor; break; /* minor HTTP version or end of request line */ case s_res_http_minor: { if (ch == ' ') { state = s_res_first_status_code; break; } if (!IS_NUM(ch)) { SET_ERRNO(HPE_INVALID_VERSION); goto error; } parser->http_minor *= 10; parser->http_minor += ch - '0'; if (parser->http_minor > 999) { SET_ERRNO(HPE_INVALID_VERSION); goto error; } break; } case s_res_first_status_code: { if (!IS_NUM(ch)) { if (ch == ' ') { break; } SET_ERRNO(HPE_INVALID_STATUS); goto error; } parser->status_code = ch - '0'; state = s_res_status_code; break; } case s_res_status_code: { if (!IS_NUM(ch)) { switch (ch) { case ' ': state = s_res_status; break; case CR: state = s_res_line_almost_done; break; case LF: state = s_header_field_start; break; default: SET_ERRNO(HPE_INVALID_STATUS); goto error; } break; } parser->status_code *= 10; parser->status_code += ch - '0'; if (parser->status_code > 999) { SET_ERRNO(HPE_INVALID_STATUS); goto error; } break; } case s_res_status: /* the human readable status. e.g. "NOT FOUND" * we are not humans so just ignore this */ if (ch == CR) { state = s_res_line_almost_done; break; } if (ch == LF) { state = s_header_field_start; break; } break; case s_res_line_almost_done: STRICT_CHECK(ch != LF); state = s_header_field_start; break; case s_start_req: { if (ch == CR || ch == LF) break; parser->flags = 0; parser->content_length = -1; CALLBACK2(message_begin); if (!IS_ALPHA(ch)) { SET_ERRNO(HPE_INVALID_METHOD); goto error; } start_req_method_assign: parser->method = (enum http_method) 0; index = 1; switch (ch) { case 'C': parser->method = HTTP_CONNECT; /* or COPY, CHECKOUT */ break; case 'D': parser->method = HTTP_DELETE; break; case 'G': parser->method = HTTP_GET; break; case 'H': parser->method = HTTP_HEAD; break; case 'L': parser->method = HTTP_LOCK; break; case 'M': parser->method = HTTP_MKCOL; /* or MOVE, MKACTIVITY, MERGE, M-SEARCH */ break; case 'N': parser->method = HTTP_NOTIFY; break; case 'O': parser->method = HTTP_OPTIONS; break; case 'P': parser->method = HTTP_POST; /* or PROPFIND or PROPPATCH or PUT or PATCH */ break; case 'R': parser->method = HTTP_REPORT; break; case 'S': parser->method = HTTP_SUBSCRIBE; break; case 'T': parser->method = HTTP_TRACE; break; case 'U': parser->method = HTTP_UNLOCK; /* or UNSUBSCRIBE */ break; default: SET_ERRNO(HPE_INVALID_METHOD); goto error; } state = s_req_method; break; } case s_req_method: { if (ch == '\0') { SET_ERRNO(HPE_INVALID_METHOD); goto error; } const char *matcher = method_strings[parser->method]; if (ch == ' ' && matcher[index] == '\0') { state = s_req_spaces_before_url; } else if (ch == matcher[index]) { ; /* nada */ } else if (parser->method == HTTP_CONNECT) { if (index == 1 && ch == 'H') { parser->method = HTTP_CHECKOUT; } else if (index == 2 && ch == 'P') { parser->method = HTTP_COPY; } else { goto error; } } else if (parser->method == HTTP_MKCOL) { if (index == 1 && ch == 'O') { parser->method = HTTP_MOVE; } else if (index == 1 && ch == 'E') { parser->method = HTTP_MERGE; } else if (index == 1 && ch == '-') { parser->method = HTTP_MSEARCH; } else if (index == 2 && ch == 'A') { parser->method = HTTP_MKACTIVITY; } else { goto error; } } else if (index == 1 && parser->method == HTTP_POST) { if (ch == 'R') { parser->method = HTTP_PROPFIND; /* or HTTP_PROPPATCH */ } else if (ch == 'U') { parser->method = HTTP_PUT; } else if (ch == 'A') { parser->method = HTTP_PATCH; } else { goto error; } } else if (index == 2 && parser->method == HTTP_UNLOCK && ch == 'S') { parser->method = HTTP_UNSUBSCRIBE; } else if (index == 4 && parser->method == HTTP_PROPFIND && ch == 'P') { parser->method = HTTP_PROPPATCH; } else { SET_ERRNO(HPE_INVALID_METHOD); goto error; } ++index; break; } case s_req_spaces_before_url: { if (ch == ' ') break; if (ch == '/' || ch == '*') { MARK(url); state = s_req_path; break; } /* Proxied requests are followed by scheme of an absolute URI (alpha). * CONNECT is followed by a hostname, which begins with alphanum. * All other methods are followed by '/' or '*' (handled above). */ if (IS_ALPHA(ch) || (parser->method == HTTP_CONNECT && IS_NUM(ch))) { MARK(url); state = (parser->method == HTTP_CONNECT) ? s_req_host : s_req_schema; break; } SET_ERRNO(HPE_INVALID_URL); goto error; } case s_req_schema: { if (IS_ALPHA(ch)) break; if (ch == ':') { state = s_req_schema_slash; break; } SET_ERRNO(HPE_INVALID_URL); goto error; } case s_req_schema_slash: STRICT_CHECK(ch != '/'); state = s_req_schema_slash_slash; break; case s_req_schema_slash_slash: STRICT_CHECK(ch != '/'); state = s_req_host; break; case s_req_host: { if (IS_HOST_CHAR(ch)) break; switch (ch) { case ':': state = s_req_port; break; case '/': state = s_req_path; break; case ' ': /* The request line looks like: * "GET http://foo.bar.com HTTP/1.1" * That is, there is no path. */ CALLBACK(url); state = s_req_http_start; break; case '?': state = s_req_query_string_start; break; default: SET_ERRNO(HPE_INVALID_HOST); goto error; } break; } case s_req_port: { if (IS_NUM(ch)) break; switch (ch) { case '/': state = s_req_path; break; case ' ': /* The request line looks like: * "GET http://foo.bar.com:1234 HTTP/1.1" * That is, there is no path. */ CALLBACK(url); state = s_req_http_start; break; case '?': state = s_req_query_string_start; break; default: SET_ERRNO(HPE_INVALID_PORT); goto error; } break; } case s_req_path: { if (IS_URL_CHAR(ch)) break; switch (ch) { case ' ': CALLBACK(url); state = s_req_http_start; break; case CR: CALLBACK(url); parser->http_major = 0; parser->http_minor = 9; state = s_req_line_almost_done; break; case LF: CALLBACK(url); parser->http_major = 0; parser->http_minor = 9; state = s_header_field_start; break; case '?': state = s_req_query_string_start; break; case '#': state = s_req_fragment_start; break; default: SET_ERRNO(HPE_INVALID_PATH); goto error; } break; } case s_req_query_string_start: { if (IS_URL_CHAR(ch)) { state = s_req_query_string; break; } switch (ch) { case '?': break; /* XXX ignore extra '?' ... is this right? */ case ' ': CALLBACK(url); state = s_req_http_start; break; case CR: CALLBACK(url); parser->http_major = 0; parser->http_minor = 9; state = s_req_line_almost_done; break; case LF: CALLBACK(url); parser->http_major = 0; parser->http_minor = 9; state = s_header_field_start; break; case '#': state = s_req_fragment_start; break; default: SET_ERRNO(HPE_INVALID_QUERY_STRING); goto error; } break; } case s_req_query_string: { if (IS_URL_CHAR(ch)) break; switch (ch) { case '?': /* allow extra '?' in query string */ break; case ' ': CALLBACK(url); state = s_req_http_start; break; case CR: CALLBACK(url); parser->http_major = 0; parser->http_minor = 9; state = s_req_line_almost_done; break; case LF: CALLBACK(url); parser->http_major = 0; parser->http_minor = 9; state = s_header_field_start; break; case '#': state = s_req_fragment_start; break; default: SET_ERRNO(HPE_INVALID_QUERY_STRING); goto error; } break; } case s_req_fragment_start: { if (IS_URL_CHAR(ch)) { state = s_req_fragment; break; } switch (ch) { case ' ': CALLBACK(url); state = s_req_http_start; break; case CR: CALLBACK(url); parser->http_major = 0; parser->http_minor = 9; state = s_req_line_almost_done; break; case LF: CALLBACK(url); parser->http_major = 0; parser->http_minor = 9; state = s_header_field_start; break; case '?': state = s_req_fragment; break; case '#': break; default: SET_ERRNO(HPE_INVALID_FRAGMENT); goto error; } break; } case s_req_fragment: { if (IS_URL_CHAR(ch)) break; switch (ch) { case ' ': CALLBACK(url); state = s_req_http_start; break; case CR: CALLBACK(url); parser->http_major = 0; parser->http_minor = 9; state = s_req_line_almost_done; break; case LF: CALLBACK(url); parser->http_major = 0; parser->http_minor = 9; state = s_header_field_start; break; case '?': case '#': break; default: SET_ERRNO(HPE_INVALID_FRAGMENT); goto error; } break; } case s_req_http_start: switch (ch) { case 'H': state = s_req_http_H; break; case ' ': break; default: SET_ERRNO(HPE_INVALID_CONSTANT); goto error; } break; case s_req_http_H: STRICT_CHECK(ch != 'T'); state = s_req_http_HT; break; case s_req_http_HT: STRICT_CHECK(ch != 'T'); state = s_req_http_HTT; break; case s_req_http_HTT: STRICT_CHECK(ch != 'P'); state = s_req_http_HTTP; break; case s_req_http_HTTP: STRICT_CHECK(ch != '/'); state = s_req_first_http_major; break; /* first digit of major HTTP version */ case s_req_first_http_major: if (ch < '1' || ch > '9') { SET_ERRNO(HPE_INVALID_VERSION); goto error; } parser->http_major = ch - '0'; state = s_req_http_major; break; /* major HTTP version or dot */ case s_req_http_major: { if (ch == '.') { state = s_req_first_http_minor; break; } if (!IS_NUM(ch)) { SET_ERRNO(HPE_INVALID_VERSION); goto error; } parser->http_major *= 10; parser->http_major += ch - '0'; if (parser->http_major > 999) { SET_ERRNO(HPE_INVALID_VERSION); goto error; } break; } /* first digit of minor HTTP version */ case s_req_first_http_minor: if (!IS_NUM(ch)) { SET_ERRNO(HPE_INVALID_VERSION); goto error; } parser->http_minor = ch - '0'; state = s_req_http_minor; break; /* minor HTTP version or end of request line */ case s_req_http_minor: { if (ch == CR) { state = s_req_line_almost_done; break; } if (ch == LF) { state = s_header_field_start; break; } /* XXX allow spaces after digit? */ if (!IS_NUM(ch)) { SET_ERRNO(HPE_INVALID_VERSION); goto error; } parser->http_minor *= 10; parser->http_minor += ch - '0'; if (parser->http_minor > 999) { SET_ERRNO(HPE_INVALID_VERSION); goto error; } break; } /* end of request line */ case s_req_line_almost_done: { if (ch != LF) { SET_ERRNO(HPE_LF_EXPECTED); goto error; } state = s_header_field_start; break; } case s_header_field_start: header_field_start: { if (ch == CR) { state = s_headers_almost_done; break; } if (ch == LF) { /* they might be just sending \n instead of \r\n so this would be * the second \n to denote the end of headers*/ state = s_headers_almost_done; goto headers_almost_done; } c = TOKEN(ch); if (!c) { SET_ERRNO(HPE_INVALID_HEADER_TOKEN); goto error; } MARK(header_field); index = 0; state = s_header_field; switch (c) { case 'c': header_state = h_C; break; case 'p': header_state = h_matching_proxy_connection; break; case 't': header_state = h_matching_transfer_encoding; break; case 'u': header_state = h_matching_upgrade; break; default: header_state = h_general; break; } break; } case s_header_field: { c = TOKEN(ch); if (c) { switch (header_state) { case h_general: break; case h_C: index++; header_state = (c == 'o' ? h_CO : h_general); break; case h_CO: index++; header_state = (c == 'n' ? h_CON : h_general); break; case h_CON: index++; switch (c) { case 'n': header_state = h_matching_connection; break; case 't': header_state = h_matching_content_length; break; default: header_state = h_general; break; } break; /* connection */ case h_matching_connection: index++; if (index > sizeof(CONNECTION)-1 || c != CONNECTION[index]) { header_state = h_general; } else if (index == sizeof(CONNECTION)-2) { header_state = h_connection; } break; /* proxy-connection */ case h_matching_proxy_connection: index++; if (index > sizeof(PROXY_CONNECTION)-1 || c != PROXY_CONNECTION[index]) { header_state = h_general; } else if (index == sizeof(PROXY_CONNECTION)-2) { header_state = h_connection; } break; /* content-length */ case h_matching_content_length: index++; if (index > sizeof(CONTENT_LENGTH)-1 || c != CONTENT_LENGTH[index]) { header_state = h_general; } else if (index == sizeof(CONTENT_LENGTH)-2) { header_state = h_content_length; } break; /* transfer-encoding */ case h_matching_transfer_encoding: index++; if (index > sizeof(TRANSFER_ENCODING)-1 || c != TRANSFER_ENCODING[index]) { header_state = h_general; } else if (index == sizeof(TRANSFER_ENCODING)-2) { header_state = h_transfer_encoding; } break; /* upgrade */ case h_matching_upgrade: index++; if (index > sizeof(UPGRADE)-1 || c != UPGRADE[index]) { header_state = h_general; } else if (index == sizeof(UPGRADE)-2) { header_state = h_upgrade; } break; case h_connection: case h_content_length: case h_transfer_encoding: case h_upgrade: if (ch != ' ') header_state = h_general; break; default: assert(0 && "Unknown header_state"); break; } break; } if (ch == ':') { CALLBACK(header_field); state = s_header_value_start; break; } if (ch == CR) { state = s_header_almost_done; CALLBACK(header_field); break; } if (ch == LF) { CALLBACK(header_field); state = s_header_field_start; break; } SET_ERRNO(HPE_INVALID_HEADER_TOKEN); goto error; } case s_header_value_start: { if (ch == ' ' || ch == '\t') break; MARK(header_value); state = s_header_value; index = 0; if (ch == CR) { CALLBACK(header_value); header_state = h_general; state = s_header_almost_done; break; } if (ch == LF) { CALLBACK(header_value); state = s_header_field_start; break; } c = LOWER(ch); switch (header_state) { case h_upgrade: parser->flags |= F_UPGRADE; header_state = h_general; break; case h_transfer_encoding: /* looking for 'Transfer-Encoding: chunked' */ if ('c' == c) { header_state = h_matching_transfer_encoding_chunked; } else { header_state = h_general; } break; case h_content_length: if (!IS_NUM(ch)) { SET_ERRNO(HPE_INVALID_CONTENT_LENGTH); goto error; } parser->content_length = ch - '0'; break; case h_connection: /* looking for 'Connection: keep-alive' */ if (c == 'k') { header_state = h_matching_connection_keep_alive; /* looking for 'Connection: close' */ } else if (c == 'c') { header_state = h_matching_connection_close; } else { header_state = h_general; } break; default: header_state = h_general; break; } break; } case s_header_value: { if (ch == CR) { CALLBACK(header_value); state = s_header_almost_done; break; } if (ch == LF) { CALLBACK(header_value); goto header_almost_done; } c = LOWER(ch); switch (header_state) { case h_general: break; case h_connection: case h_transfer_encoding: assert(0 && "Shouldn't get here."); break; case h_content_length: if (ch == ' ') break; if (!IS_NUM(ch)) { SET_ERRNO(HPE_INVALID_CONTENT_LENGTH); goto error; } parser->content_length *= 10; parser->content_length += ch - '0'; break; /* Transfer-Encoding: chunked */ case h_matching_transfer_encoding_chunked: index++; if (index > sizeof(CHUNKED)-1 || c != CHUNKED[index]) { header_state = h_general; } else if (index == sizeof(CHUNKED)-2) { header_state = h_transfer_encoding_chunked; } break; /* looking for 'Connection: keep-alive' */ case h_matching_connection_keep_alive: index++; if (index > sizeof(KEEP_ALIVE)-1 || c != KEEP_ALIVE[index]) { header_state = h_general; } else if (index == sizeof(KEEP_ALIVE)-2) { header_state = h_connection_keep_alive; } break; /* looking for 'Connection: close' */ case h_matching_connection_close: index++; if (index > sizeof(CLOSE)-1 || c != CLOSE[index]) { header_state = h_general; } else if (index == sizeof(CLOSE)-2) { header_state = h_connection_close; } break; case h_transfer_encoding_chunked: case h_connection_keep_alive: case h_connection_close: if (ch != ' ') header_state = h_general; break; default: state = s_header_value; header_state = h_general; break; } break; } case s_header_almost_done: header_almost_done: { STRICT_CHECK(ch != LF); state = s_header_value_lws; switch (header_state) { case h_connection_keep_alive: parser->flags |= F_CONNECTION_KEEP_ALIVE; break; case h_connection_close: parser->flags |= F_CONNECTION_CLOSE; break; case h_transfer_encoding_chunked: parser->flags |= F_CHUNKED; break; default: break; } break; } case s_header_value_lws: { if (ch == ' ' || ch == '\t') state = s_header_value_start; else { state = s_header_field_start; goto header_field_start; } break; } case s_headers_almost_done: headers_almost_done: { STRICT_CHECK(ch != LF); if (parser->flags & F_TRAILING) { /* End of a chunked request */ CALLBACK2(message_complete); state = NEW_MESSAGE(); break; } nread = 0; if (parser->flags & F_UPGRADE || parser->method == HTTP_CONNECT) { parser->upgrade = 1; } /* Here we call the headers_complete callback. This is somewhat * different than other callbacks because if the user returns 1, we * will interpret that as saying that this message has no body. This * is needed for the annoying case of recieving a response to a HEAD * request. */ if (settings->on_headers_complete) { switch (settings->on_headers_complete(parser)) { case 0: break; case 1: parser->flags |= F_SKIPBODY; break; default: parser->state = state; SET_ERRNO(HPE_CB_headers_complete); return p - data; /* Error */ } } /* Exit, the rest of the connect is in a different protocol. */ if (parser->upgrade) { CALLBACK2(message_complete); return (p - data) + 1; } if (parser->flags & F_SKIPBODY) { CALLBACK2(message_complete); state = NEW_MESSAGE(); } else if (parser->flags & F_CHUNKED) { /* chunked encoding - ignore Content-Length header */ state = s_chunk_size_start; } else { if (parser->content_length == 0) { /* Content-Length header given but zero: Content-Length: 0\r\n */ CALLBACK2(message_complete); state = NEW_MESSAGE(); } else if (parser->content_length > 0) { /* Content-Length header given and non-zero */ state = s_body_identity; } else { if (parser->type == HTTP_REQUEST || http_should_keep_alive(parser)) { /* Assume content-length 0 - read the next */ CALLBACK2(message_complete); state = NEW_MESSAGE(); } else { /* Read body until EOF */ state = s_body_identity_eof; } } } break; } case s_body_identity: to_read = MIN(pe - p, (int64_t)parser->content_length); if (to_read > 0) { if (settings->on_body) settings->on_body(parser, p, to_read); p += to_read - 1; parser->content_length -= to_read; if (parser->content_length == 0) { CALLBACK2(message_complete); state = NEW_MESSAGE(); } } break; /* read until EOF */ case s_body_identity_eof: to_read = pe - p; if (to_read > 0) { if (settings->on_body) settings->on_body(parser, p, to_read); p += to_read - 1; } break; case s_chunk_size_start: { assert(nread == 1); assert(parser->flags & F_CHUNKED); unhex_val = unhex[(unsigned char)ch]; if (unhex_val == -1) { SET_ERRNO(HPE_INVALID_CHUNK_SIZE); goto error; } parser->content_length = unhex_val; state = s_chunk_size; break; } case s_chunk_size: { assert(parser->flags & F_CHUNKED); if (ch == CR) { state = s_chunk_size_almost_done; break; } unhex_val = unhex[(unsigned char)ch]; if (unhex_val == -1) { if (ch == ';' || ch == ' ') { state = s_chunk_parameters; break; } SET_ERRNO(HPE_INVALID_CHUNK_SIZE); goto error; } parser->content_length *= 16; parser->content_length += unhex_val; break; } case s_chunk_parameters: { assert(parser->flags & F_CHUNKED); /* just ignore this shit. TODO check for overflow */ if (ch == CR) { state = s_chunk_size_almost_done; break; } break; } case s_chunk_size_almost_done: { assert(parser->flags & F_CHUNKED); STRICT_CHECK(ch != LF); nread = 0; if (parser->content_length == 0) { parser->flags |= F_TRAILING; state = s_header_field_start; } else { state = s_chunk_data; } break; } case s_chunk_data: { assert(parser->flags & F_CHUNKED); to_read = MIN(pe - p, (int64_t)(parser->content_length)); if (to_read > 0) { if (settings->on_body) settings->on_body(parser, p, to_read); p += to_read - 1; } if (to_read == parser->content_length) { state = s_chunk_data_almost_done; } parser->content_length -= to_read; break; } case s_chunk_data_almost_done: assert(parser->flags & F_CHUNKED); STRICT_CHECK(ch != CR); state = s_chunk_data_done; break; case s_chunk_data_done: assert(parser->flags & F_CHUNKED); STRICT_CHECK(ch != LF); state = s_chunk_size_start; break; default: assert(0 && "unhandled state"); SET_ERRNO(HPE_INVALID_INTERNAL_STATE); goto error; } } CALLBACK(header_field); CALLBACK(header_value); CALLBACK(url); parser->state = state; parser->header_state = header_state; parser->index = index; parser->nread = nread; return len; error: if (HTTP_PARSER_ERRNO(parser) == HPE_OK) { SET_ERRNO(HPE_UNKNOWN); } return (p - data); }
int webc_font_family_index ( const WEBC_CHAR* name, const WEBC_CHAR* genericName, const WEBC_CHAR** fontNames, const WEBC_CHAR** fontGenericNames, int numFonts ) { if (!name) { name = genericName; genericName = 0; } while (name) { const WEBC_CHAR* pos = name; const WEBC_CHAR* last; WEBC_CHAR quoteChar; while (*pos) { while (*pos && !IS_ALPHA(*pos) && *pos != '\'' && *pos != '\"') { pos++; } if (!*pos) { break; } if (*pos == '\'' || *pos == '\"') { quoteChar = *pos; pos++; } else { quoteChar = 0; } last = pos; while (*last && (quoteChar || (!IS_WHITESPACE(*last) && *last != ',')) && (!quoteChar || *last != quoteChar)) { last++; } if (!*last) { int n; for (n=0; n<numFonts; n++) { if (fontNames[n]) { if (!webc_stricmp(fontNames[n], pos) || (fontGenericNames[n] && !webc_stricmp(fontGenericNames[n], pos))) { return (n); } } } } else { int len = last - pos; int n; for (n=0; n<numFonts; n++) { if (fontNames[n]) { if (!webc_strnicmp(fontNames[n], pos, len) || (fontGenericNames[n] && !webc_strnicmp(fontGenericNames[n], pos, len))) { return (n); } } } } if (quoteChar && *last == quoteChar) { last++; } pos = last; } name = genericName; genericName = 0; } return (-1); }
Str Sprintf(char *fmt, ...) { int len = 0; int status = SP_NORMAL; int p = 0; char *f; Str s; va_list ap; va_start(ap, fmt); for (f = fmt; *f; f++) { redo: switch (status) { case SP_NORMAL: if (*f == '%') { status = SP_PREC; p = 0; } else len++; break; case SP_PREC: if (IS_ALPHA(*f)) { /* conversion char. */ double vd; int vi; char *vs; void *vp; switch (*f) { case 'l': case 'h': case 'L': case 'w': continue; case 'd': case 'i': case 'o': case 'x': case 'X': case 'u': vi = va_arg(ap, int); len += (p > 0) ? p : 10; break; case 'f': case 'g': case 'e': case 'G': case 'E': vd = va_arg(ap, double); len += (p > 0) ? p : 15; break; case 'c': len += 1; vi = va_arg(ap, int); break; case 's': vs = va_arg(ap, char *); vi = strlen(vs); len += (p > vi) ? p : vi; break; case 'p': vp = va_arg(ap, void *); len += 10; break; case 'n': vp = va_arg(ap, void *); break; } status = SP_NORMAL; } else if (IS_DIGIT(*f)) p = p * 10 + *f - '0'; else if (*f == '.') status = SP_PREC2; else if (*f == '%') { status = SP_NORMAL; len++; } break; case SP_PREC2: if (IS_ALPHA(*f)) { status = SP_PREC; goto redo; } break; }
static Str unquote_mailcap_loop(char *qstr, char *type, char *name, char *attr, int *mc_stat, int flag0) { Str str, tmp, test, then; char *p; int status = MC_NORMAL, prev_status = MC_NORMAL, sp = 0, flag; if (mc_stat) *mc_stat = 0; if (qstr == NULL) return NULL; str = Strnew(); tmp = test = then = NULL; for (flag = flag0, p = qstr; *p; p++) { if (status == MC_QUOTED) { if (prev_status == MC_PREC2) Strcat_char(tmp, *p); else Strcat_char(str, *p); status = prev_status; continue; } else if (*p == '\\') { prev_status = status; status = MC_QUOTED; continue; } switch (status) { case MC_NORMAL: if (*p == '%') { status = MC_PREC; } else { if (*p == '\'') { if (!flag0 && flag & MCF_SQUOTED) flag &= ~MCF_SQUOTED; else if (!flag) flag |= MCF_SQUOTED; } else if (*p == '"') { if (!flag0 && flag & MCF_DQUOTED) flag &= ~MCF_DQUOTED; else if (!flag) flag |= MCF_DQUOTED; } Strcat_char(str, *p); } break; case MC_PREC: if (IS_ALPHA(*p)) { switch (*p) { case 's': if (name) { Strcat_charp(str, quote_mailcap(name, flag)->ptr); if (mc_stat) *mc_stat |= MCSTAT_REPNAME; } break; case 't': if (type) { Strcat_charp(str, quote_mailcap(type, flag)->ptr); if (mc_stat) *mc_stat |= MCSTAT_REPTYPE; } break; } status = MC_NORMAL; } else if (*p == '{') { status = MC_PREC2; test = then = NULL; tmp = Strnew(); } else if (*p == '%') { Strcat_char(str, *p); } break; case MC_PREC2: if (sp > 0 || *p == '{') { Strcat_char(tmp, *p); switch (*p) { case '{': ++sp; break; case '}': --sp; break; default: break; } } else if (*p == '}') { char *q; if (attr && (q = strcasestr(attr, tmp->ptr)) != NULL && (q == attr || IS_SPACE(*(q - 1)) || *(q - 1) == ';') && matchattr(q, tmp->ptr, tmp->length, &tmp)) { Strcat_charp(str, quote_mailcap(tmp->ptr, flag)->ptr); if (mc_stat) *mc_stat |= MCSTAT_REPPARAM; } status = MC_NORMAL; } else { Strcat_char(tmp, *p); } break; } } return str; }
int configuration_load (configuration_t *conf, const char *filename) { FILE *file; char buffer[20 * 1024]; char *ptr, *ptrEnd; off_t state = 0; size_t bytes; char key_name[CONF_KEY_NAME_MAXLEN + 1]; char value[CONF_VALUE_MAXLEN + 1]; off_t nline = 1; size_t len; char c; conf_key_t *key = NULL; conf_key_list_t *current_list = NULL, *parent_list = NULL; configuration_free (conf); /* Open file for reading. */ file = fopen (filename, "rb"); if (!file) { fprintf (stderr, "Couldn't open [%s] for reading.\n", filename); return -1; } current_list = &conf->root; len = 0; do { bytes = fread (buffer, 1, sizeof (buffer), file); if (bytes <= 0) { *buffer = '\n'; ptrEnd = buffer + 1; } else { ptrEnd = buffer + bytes; } ptr = buffer; while (ptr < ptrEnd) { switch (state) { case 0: /* No keys/values found yet. */ if (*ptr == '{') { if ((!key) || (!current_list)) { /* No parent key present. */ fprintf (stderr, "[%s:%lu] No parent key present.\n", filename, nline); fclose (file); return -1; } parent_list = current_list; current_list = NULL; } else if (*ptr == '}') { if (!parent_list) { /* No parent list present. */ fprintf (stderr, "[%s:%lu] No parent list present.\n", filename, nline); fclose (file); return -1; } current_list = parent_list; parent_list = current_list->parent; key = NULL; } else if (*ptr == COMMENT) { state = 8; } else if (*ptr == '\n') { nline++; } else if ((IS_ALPHA (*ptr)) || (IS_DIGIT (*ptr)) || (strchr (SAFE, *ptr))) { if (current_list) { key = NULL; } *key_name = *ptr; len = 1; state = 1; } else if ((*ptr != '\r') && (*ptr != ' ') && (*ptr != '\t')) { /* Wrong character. */ fprintf (stderr, "[%s:%lu] Wrong character found: [%c].\n", filename, nline, *ptr); fclose (file); return -1; } break; case 1: /* Reading key. */ if ((IS_ALPHA (*ptr)) || (IS_DIGIT (*ptr)) || (strchr (SAFE, *ptr))) { if (len >= CONF_KEY_NAME_MAXLEN) { /* Key name too long. */ fprintf (stderr, "[%s:%lu] Key name too long (> %d).\n", filename, nline, CONF_KEY_NAME_MAXLEN); fclose (file); return -1; } key_name[len++] = *ptr; } else if ((*ptr == '\r') || (*ptr == ' ') || (*ptr == '\t')) { key_name[len] = 0; if ((key = add_key (conf, parent_list, key, ¤t_list, key_name, len)) == NULL) { /* Couldn't allocate memory. */ fprintf (stderr, "[%s:%lu] Couldn't allocate memory.\n", filename, nline); fclose (file); return -1; } state = 2; } else if (*ptr == '\n') { key_name[len] = 0; if ((key = add_key (conf, parent_list, key, ¤t_list, key_name, len)) == NULL) { /* Couldn't allocate memory. */ fprintf (stderr, "[%s:%lu] Couldn't allocate memory.\n", filename, nline); fclose (file); return -1; } key->type = KEY_MIGHT_HAVE_CHILDREN; nline++; state = 0; } else if (*ptr == '=') { key_name[len] = 0; if ((key = add_key (conf, parent_list, key, ¤t_list, key_name, len)) == NULL) { /* Couldn't allocate memory. */ fprintf (stderr, "[%s:%lu] Couldn't allocate memory.\n", filename, nline); fclose (file); return -1; } state = 3; } else if (*ptr == '{') { key_name[len] = 0; if ((key = add_key (conf, parent_list, key, ¤t_list, key_name, len)) == NULL) { /* Couldn't allocate memory. */ fprintf (stderr, "[%s:%lu] Couldn't allocate memory.\n", filename, nline); fclose (file); return -1; } key->type = KEY_MIGHT_HAVE_CHILDREN; parent_list = current_list; current_list = NULL; state = 0; } else if (*ptr == '}') { if (!parent_list) { /* No parent list present. */ fprintf (stderr, "[%s:%lu] No parent list present.\n", filename, nline); fclose (file); return -1; } key_name[len] = 0; if ((key = add_key (conf, parent_list, key, ¤t_list, key_name, len)) == NULL) { /* Couldn't allocate memory. */ fprintf (stderr, "[%s:%lu] Couldn't allocate memory.\n", filename, nline); fclose (file); return -1; } key->type = KEY_MIGHT_HAVE_CHILDREN; current_list = parent_list; parent_list = current_list->parent; key = NULL; state = 0; } else { /* Wrong character. */ fprintf (stderr, "[%s:%lu] Wrong character found: [%c].\n", filename, nline, *ptr); fclose (file); return -1; } break; case 2: /* Space after key. */ if (*ptr == '\n') { key->type = KEY_MIGHT_HAVE_CHILDREN; nline++; state = 0; } else if (*ptr == COMMENT) { key->type = KEY_MIGHT_HAVE_CHILDREN; state = 8; } else if (*ptr == '=') { state = 3; } else if (*ptr == '{') { key->type = KEY_MIGHT_HAVE_CHILDREN; parent_list = current_list; current_list = NULL; state = 0; } else if (*ptr == '}') { if (!parent_list) { /* No parent list present. */ fprintf (stderr, "[%s:%lu] No parent list present.\n", filename, nline); fclose (file); return -1; } key->type = KEY_MIGHT_HAVE_CHILDREN; current_list = parent_list; parent_list = current_list->parent; key = NULL; state = 0; } else if ((*ptr != '\r') && (*ptr != ' ') && (*ptr != '\t')) { /* Wrong character. */ fprintf (stderr, "[%s:%lu] Wrong character found: [%c].\n", filename, nline, *ptr); fclose (file); return -1; } break; case 3: /* After '='. */ if ((IS_ALPHA (*ptr)) || (IS_DIGIT (*ptr)) || (strchr (SAFE, *ptr))) { *value = *ptr; len = 1; state = 4; } else if (*ptr == '}') { if (!parent_list) { /* No parent list present. */ fprintf (stderr, "[%s:%lu] No parent list present.\n", filename, nline); fclose (file); return -1; } /* The key has no value. */ if (set_value (conf, key, "", 0) < 0) { /* Couldn't allocate memory. */ fprintf (stderr, "[%s:%lu] Couldn't allocate memory.\n", filename, nline); fclose (file); return -1; } current_list = parent_list; parent_list = current_list->parent; key = NULL; state = 0; } else if (*ptr == '"') { len = 0; state = 6; } else if (*ptr == '\n') { /* The key has no value. */ if (set_value (conf, key, "", 0) < 0) { /* Couldn't allocate memory. */ fprintf (stderr, "[%s:%lu] Couldn't allocate memory.\n", filename, nline); fclose (file); return -1; } key = NULL; nline++; state = 0; } else if ((*ptr != '\r') && (*ptr != ' ') && (*ptr != '\t')) { /* Wrong character. */ fprintf (stderr, "[%s:%lu] Wrong character found: [%c].\n", filename, nline, *ptr); fclose (file); return -1; } break; case 4: /* Reading value. */ if ((IS_ALPHA (*ptr)) || (IS_DIGIT (*ptr)) || (strchr (SAFE, *ptr))) { if (len >= CONF_VALUE_MAXLEN) { /* Value too long. */ fprintf (stderr, "[%s:%lu] Value too long (> %d).\n", filename, nline, CONF_VALUE_MAXLEN); fclose (file); return -1; } value[len++] = *ptr; } else if ((*ptr == '\r') || (*ptr == ' ') || (*ptr == '\t')) { if (set_value (conf, key, value, len) < 0) { /* Couldn't allocate memory. */ fprintf (stderr, "[%s:%lu] Couldn't allocate memory.\n", filename, nline); fclose (file); return -1; } key = NULL; state = 5; } else if (*ptr == '}') { if (!parent_list) { /* No parent list present. */ fprintf (stderr, "[%s:%lu] No parent list present.\n", filename, nline); fclose (file); return -1; } if (set_value (conf, key, value, len) < 0) { /* Couldn't allocate memory. */ fprintf (stderr, "[%s:%lu] Couldn't allocate memory.\n", filename, nline); fclose (file); return -1; } current_list = parent_list; parent_list = current_list->parent; key = NULL; state = 0; } else if (*ptr == '\n') { if (set_value (conf, key, value, len) < 0) { /* Couldn't allocate memory. */ fprintf (stderr, "[%s:%lu] Couldn't allocate memory.\n", filename, nline); fclose (file); return -1; } key = NULL; nline++; state = 0; } else { /* Wrong character. */ fprintf (stderr, "[%s:%lu] Wrong character found: [%c].\n", filename, nline, *ptr); fclose (file); return -1; } break; case 5: /* After having read value. */ if (*ptr == '\n') { nline++; state = 0; } else if (*ptr == '}') { if (!parent_list) { /* No parent list present. */ fprintf (stderr, "[%s:%lu] No parent list present.\n", filename, nline); fclose (file); return -1; } current_list = parent_list; parent_list = current_list->parent; state = 0; } else if (*ptr == COMMENT) { state = 8; } else if ((*ptr != '\r') && (*ptr != ' ') && (*ptr != '\t')) { /* Wrong character. */ fprintf (stderr, "[%s:%lu] Wrong character found: [%c].\n", filename, nline, *ptr); fclose (file); return -1; } break; case 6: /* The value is between quotation marks. */ if (*ptr == '"') { if (set_value (conf, key, value, len) < 0) { /* Couldn't allocate memory. */ fprintf (stderr, "[%s:%lu] Couldn't allocate memory.\n", filename, nline); fclose (file); return -1; } key = NULL; state = 5; } else if (*ptr == '\\') { state = 7; } else if (*ptr == '\n') { if (len >= CONF_VALUE_MAXLEN) { /* Value too long. */ fprintf (stderr, "[%s:%lu] Value too long (> %d).\n", filename, nline, CONF_VALUE_MAXLEN); fclose (file); return -1; } value[len++] = *ptr; nline++; } else { if (len >= CONF_VALUE_MAXLEN) { /* Value too long. */ fprintf (stderr, "[%s:%lu] Value too long (> %d).\n", filename, nline, CONF_VALUE_MAXLEN); fclose (file); return -1; } value[len++] = *ptr; } break; case 7: /* Escape character. */ if (*ptr == 'r') { c = '\r'; } else if (*ptr == 'n') { c = '\n'; } else if (*ptr == 't') { c = '\t'; } else { c = *ptr; } if (len >= CONF_VALUE_MAXLEN) { /* Value too long. */ fprintf (stderr, "[%s:%lu] Value too long (> %d).\n", filename, nline, CONF_VALUE_MAXLEN); fclose (file); return -1; } value[len++] = c; state = 6; break; case 8: /* Comment. */ if (*ptr == '\n') { nline++; state = 0; } break; } ptr++; } } while (bytes > 0); fclose (file); return (((state == 0) && (!parent_list))?0:-1); }
token_type next_token (token_data *td, read_type expansion, boolean in_string) { int ch; token_type type = TOKEN_NONE; int quote_level; if (TOKEN_DATA_TYPE (&token_read) != TOKEN_VOID) { type = TOKEN_STRING; obstack_grow (&token_stack, TOKEN_DATA_TEXT (&token_read), strlen (TOKEN_DATA_TEXT (&token_read))); xfree ((voidstar) TOKEN_DATA_TEXT (&token_read)); TOKEN_DATA_TYPE (&token_read) = TOKEN_VOID; } while (type == TOKEN_NONE) { obstack_free (&token_stack, token_bottom); obstack_1grow (&token_stack, '\0'); token_bottom = obstack_finish (&token_stack); ch = peek_input (); if (ch == CHAR_EOF) /* EOF */ { #ifdef DEBUG_INPUT fprintf (stderr, "next_token -> EOF\n"); #endif return TOKEN_EOF; } if (ch == CHAR_MACRO) /* MACRO TOKEN */ { init_macro_token (td); (void) next_char (); #ifdef DEBUG_INPUT print_token("next_token", TOKEN_MACDEF, td); #endif return TOKEN_MACDEF; } (void) next_char (); if (IS_TAG(ch)) /* ESCAPED WORD */ { if (lquote.length > 0 && MATCH (ch, lquote.string)) { if (visible_quotes || expansion == READ_ATTR_VERB || expansion == READ_ATTR_ASIS || expansion == READ_BODY) obstack_grow (&token_stack, lquote.string, lquote.length); while ((ch = next_char ()) != CHAR_EOF) { if (rquote.length > 0 && MATCH (ch, rquote.string)) break; obstack_1grow (&token_stack, ch); } if (visible_quotes || expansion == READ_ATTR_VERB || expansion == READ_ATTR_ASIS || expansion == READ_BODY) { obstack_grow (&token_stack, rquote.string, rquote.length); type = TOKEN_STRING; } else type = TOKEN_QUOTED; } else { obstack_1grow (&token_stack, ch); if ((ch = peek_input ()) != CHAR_EOF) { if (ch == '/') { obstack_1grow (&token_stack, '/'); (void) next_char (); ch = peek_input (); } if (IS_ALPHA(ch)) { ch = next_char (); obstack_1grow (&token_stack, ch); while ((ch = next_char ()) != CHAR_EOF && IS_ALNUM(ch)) { obstack_1grow (&token_stack, ch); } if (ch == '*') { obstack_1grow (&token_stack, ch); ch = peek_input (); } else unget_input(ch); if (IS_SPACE(ch) || IS_CLOSE(ch) || IS_SLASH (ch)) type = TOKEN_WORD; else type = TOKEN_STRING; } else type = TOKEN_STRING; } else type = TOKEN_SIMPLE; /* escape before eof */ } } else if (IS_CLOSE(ch)) { obstack_1grow (&token_stack, ch); type = TOKEN_SIMPLE; } else if (IS_ENTITY(ch)) /* entity */ { obstack_1grow (&token_stack, ch); if ((ch = peek_input ()) != CHAR_EOF) { if (IS_ALPHA(ch)) { ch = next_char (); obstack_1grow (&token_stack, ch); while ((ch = next_char ()) != CHAR_EOF && IS_ALNUM(ch)) { obstack_1grow (&token_stack, ch); } if (ch == ';') { obstack_1grow (&token_stack, ch); type = TOKEN_ENTITY; } else { type = TOKEN_STRING; unget_input(ch); } } else type = TOKEN_STRING; } else type = TOKEN_SIMPLE; /* escape before eof */ } else if (eolcomm.length > 0 && MATCH (ch, eolcomm.string)) skip_line (); else if (expansion == READ_BODY) { if (ch == '"') obstack_1grow (&token_stack, CHAR_QUOTE); else obstack_1grow (&token_stack, ch); while ((ch = next_char ()) != CHAR_EOF && ! IS_TAG(ch) && ! IS_CLOSE (ch)) { if (eolcomm.length > 0 && MATCH (ch, eolcomm.string)) { skip_line (); ch = CHAR_EOF; break; } if (ch == '"') obstack_1grow (&token_stack, CHAR_QUOTE); else obstack_1grow (&token_stack, ch); } unget_input(ch); type = TOKEN_STRING; } /* Below we know that expansion != READ_BODY */ else if (IS_ALPHA(ch)) { obstack_1grow (&token_stack, ch); while ((ch = next_char ()) != CHAR_EOF && (IS_ALNUM(ch))) { obstack_1grow (&token_stack, ch); } if (ch == '*') { obstack_1grow (&token_stack, ch); ch = peek_input (); } else unget_input(ch); type = TOKEN_STRING; } else if (IS_RQUOTE(ch)) { MP4HERROR ((EXIT_FAILURE, 0, "INTERNAL ERROR: CHAR_RQUOTE found.")); } else if (IS_LQUOTE(ch)) /* QUOTED STRING */ { quote_level = 1; while (1) { ch = next_char (); if (ch == CHAR_EOF) MP4HERROR ((EXIT_FAILURE, 0, "INTERNAL ERROR: EOF in string")); if (IS_BGROUP(ch) || IS_EGROUP(ch)) continue; else if (IS_RQUOTE(ch)) { quote_level--; if (quote_level == 0) break; } else if (IS_LQUOTE(ch)) quote_level++; else obstack_1grow (&token_stack, ch); } type = TOKEN_QUOTED; } else if (IS_BGROUP(ch)) /* BEGIN GROUP */ type = TOKEN_BGROUP; else if (IS_EGROUP(ch)) /* END GROUP */ type = TOKEN_EGROUP; else if (ch == '"') /* QUOTED STRING */ { switch (expansion) { case READ_NORMAL: obstack_1grow (&token_stack, CHAR_QUOTE); type = TOKEN_SIMPLE; break; case READ_ATTRIBUTE: case READ_ATTR_VERB: type = TOKEN_QUOTE; break; case READ_ATTR_ASIS: case READ_ATTR_QUOT: obstack_1grow (&token_stack, '"'); type = TOKEN_QUOTE; break; default: MP4HERROR ((warning_status, 0, "INTERNAL ERROR: Unknown expansion type")); exit (1); } } else if (ch == '\\') { switch (expansion) { case READ_NORMAL: obstack_1grow (&token_stack, ch); type = TOKEN_SIMPLE; break; case READ_ATTRIBUTE: case READ_ATTR_QUOT: ch = next_char(); if (ch == 'n') obstack_1grow (&token_stack, '\n'); else if (ch == 't') obstack_1grow (&token_stack, '\t'); else if (ch == 'r') obstack_1grow (&token_stack, '\r'); else if (ch == '\\') obstack_1grow (&token_stack, ch); else if (ch == '"' && in_string) obstack_1grow (&token_stack, CHAR_QUOTE); else { if (!(exp_flags & EXP_STD_BSLASH)) obstack_1grow (&token_stack, '\\'); obstack_1grow (&token_stack, ch); } type = TOKEN_STRING; break; case READ_ATTR_VERB: ch = next_char(); if (ch == '"' && in_string) obstack_1grow (&token_stack, CHAR_QUOTE); else { obstack_1grow (&token_stack, '\\'); obstack_1grow (&token_stack, ch); } type = TOKEN_STRING; break; case READ_ATTR_ASIS: obstack_1grow (&token_stack, ch); ch = next_char(); obstack_1grow (&token_stack, ch); type = TOKEN_STRING; break; default: MP4HERROR ((warning_status, 0, "INTERNAL ERROR: Unknown expansion type")); exit (1); } } else /* EVERYTHING ELSE */ { obstack_1grow (&token_stack, ch); if (IS_OTHER(ch) || IS_NUM(ch)) type = TOKEN_STRING; else if (IS_SPACE(ch)) { while ((ch = next_char ()) != CHAR_EOF && IS_SPACE(ch)) obstack_1grow (&token_stack, ch); unget_input(ch); type = TOKEN_SPACE; } else type = TOKEN_SIMPLE; } } obstack_1grow (&token_stack, '\0'); TOKEN_DATA_TYPE (td) = TOKEN_TEXT; TOKEN_DATA_TEXT (td) = obstack_finish (&token_stack); #ifdef DEBUG_INPUT print_token("next_token", type, td); #endif return type; }
static void find_and_change (char* in, int len) { // just to avoid underflows.. len can't be < then len(padding). if (!in || len < 1) { return; } char *end; RFindCTX ctx = {0}; end = in + len; // type = TYPE_NONE; for (ctx.linebegin = in; in < end; ++in) { if (*in == '\n' || !*in) { if (ctx.type == TYPE_SYM && ctx.linecount < 1) { ctx.linecount++; ctx.linebegin = in + 1; continue; } if (ctx.type != TYPE_NONE && ctx.right && ctx.left && ctx.rightlen > 0 && ctx.leftlen > 0) { char* copy = NULL; if (ctx.leftlen > ctx.rightlen) { copy = (char*) malloc (ctx.leftlen); if (copy) { memcpy (copy, ctx.left, ctx.leftlen); memcpy (ctx.left, ctx.right, ctx.rightlen); memmove (ctx.comment - ctx.leftlen + ctx.rightlen, ctx.comment, ctx.right - ctx.comment); memcpy (ctx.right - ctx.leftlen + ctx.rightlen, copy, ctx.leftlen); } } else if (ctx.leftlen < ctx.rightlen) { if (ctx.linecount < 1) { copy = (char*) malloc (ctx.rightlen); if (copy) { memcpy (copy, ctx.right, ctx.rightlen); memcpy (ctx.right + ctx.rightlen - ctx.leftlen, ctx.left, ctx.leftlen); memmove (ctx.comment + ctx.rightlen - ctx.leftlen, ctx.comment, ctx.right - ctx.comment); memcpy (ctx.left + ctx.rightlen - ctx.leftlen, copy, ctx.rightlen); } } else { // copy = (char*) malloc (ctx.linebegin - ctx.left); // if (copy) { // memcpy (copy, ctx.left, ctx.linebegin - ctx.left); memset (ctx.right - ctx.leftpos, ' ', ctx.leftpos); *(ctx.right - ctx.leftpos - 1) = '\n'; // memcpy (ctx.comment + 3, copy, ctx.linebegin - ctx.left); memset (ctx.left, ' ', ctx.leftlen); memset (ctx.linebegin - ctx.leftlen, ' ', ctx.leftlen); // } } } else if (ctx.leftlen == ctx.rightlen) { copy = (char*) malloc (ctx.leftlen); if (copy) { memcpy (copy, ctx.right, ctx.leftlen); memcpy (ctx.right, ctx.left, ctx.leftlen); memcpy (ctx.left, copy, ctx.leftlen); } } free (copy); } memset (&ctx, 0, sizeof (ctx)); ctx.linebegin = in + 1; } else if (!ctx.comment && *in == ';' && in[1] == ' ') { ctx.comment = in - 1; ctx.comment[1] = '/'; ctx.comment[2] = '/'; while (!IS_WHITESPACE (*(ctx.comment - ctx.commentcolor))) { ctx.commentcolor++; } ctx.commentcolor--; } else if (!ctx.comment && ctx.type == TYPE_NONE) { if (IS_STRING (in, ctx)) { ctx.type = TYPE_STR; ctx.left = in; while (!IS_WHITESPACE (*(ctx.left - ctx.leftcolor))) { ctx.leftcolor++; } ctx.leftcolor--; ctx.leftpos = ctx.left - ctx.linebegin; } else if (IS_SYMBOL (in, ctx)) { ctx.type = TYPE_SYM; ctx.left = in; while (!IS_WHITESPACE (*(ctx.left - ctx.leftcolor))) { ctx.leftcolor++; } ctx.leftcolor--; ctx.leftpos = ctx.left - ctx.linebegin; } } else if (ctx.type == TYPE_STR) { if (!ctx.leftlen && ctx.left && IS_WHITESPACE (*in)) { ctx.leftlen = in - ctx.left; } else if (ctx.comment && *in == '"' && in[-1] != '\\') { if (!ctx.right) { ctx.right = in; while (!IS_WHITESPACE (*(ctx.right - ctx.rightcolor))) { ctx.rightcolor++; } ctx.rightcolor--; } else { ctx.rightlen = in - ctx.right + 1; } } } else if (ctx.type == TYPE_SYM) { if (!ctx.leftlen && ctx.left && IS_WHITESPACE (*in)) { ctx.leftlen = in - ctx.left + 3; } else if (ctx.comment && *in == '(' && IS_ALPHA (in[-1]) && !ctx.right) { // ok so i've found a function written in this way: // type = [const|void|int|float|double|short|long] // type fcn_name (type arg1, type arg2, ...) // right now 'in' points at '(', but the function name is before, so i'll go back // till a space is found // 'int print(const char*, ...)' // ^ ctx.right = in - 1; while (IS_ALPHA (*ctx.right) || *ctx.right == '_' || *ctx.right == '*') { ctx.right--; } // 'int print(const char*, ...)' // ^ // right now 'in' points at ' ' before 'p' , but there can be a return value // like 'int' in 'int print(const char*, ...)'. // so to find for example 'int' we have to go back till a space is found. // if a non alpha is found, then we can cut from the function name if (*ctx.right == ' ') { ctx.right--; while (IS_ALPHA (*ctx.right) || *ctx.right == '_' || *ctx.right == '*') { ctx.right--; } // moving forward since it points now to non alpha. ctx.right++; } while (!IS_WHITESPACE (*(ctx.right - ctx.rightcolor))) { ctx.rightcolor++; } ctx.rightcolor--; } else if (ctx.comment && *in == ')' && in[1] != '\'') { ctx.rightlen = in - ctx.right + 1; } } } }
bool resolver::fill_question(const char* name, size_t namelen, rr_type type, unsigned char* buf, size_t& size) { const char* ptr = name; const char* end = name + namelen; size_t l = 1; // Zero length octect for the null label of the root. size_t labellen = 0; int state = 0; while (ptr < end) { unsigned char c = (unsigned char) *ptr++; switch (state) { case 0: if ((l += 2) > NAME_MAX_LEN) { return false; } if (!IS_ALPHA(c)) { return false; } buf++; // Skip length octect. *buf++ = c; labellen = 1; state = 1; break; case 1: if (c == '.') { buf[-(1 + labellen)] = (unsigned char) labellen; state = 0; } else if ((IS_ALPHA(c)) || (IS_DIGIT(c))) { if (++l > NAME_MAX_LEN) { return false; } if (++labellen > LABEL_MAX_LEN) { return false; } *buf++ = c; } else if (c == '-') { if (++l > NAME_MAX_LEN) { return false; } if (++labellen > LABEL_MAX_LEN) { return false; } *buf++ = c; state = 2; } else { return false; } break; case 2: if ((IS_ALPHA(c)) || (IS_DIGIT(c))) { if (++l > NAME_MAX_LEN) { return false; } if (++labellen > LABEL_MAX_LEN) { return false; } *buf++ = c; state = 1; } else { return false; } break; } } if (state != 1) { return false; } buf[-(1 + labellen)] = (unsigned char) labellen; *buf++ = 0; // Zero length octect for the null label of the root. // QTYPE. *buf++ = (unsigned char) ((type >> 8) & 0xff); *buf++ = (unsigned char) (type & 0xff); // CLASS. *buf++ = 0; *buf = 1; // IN (Internet). size = l + 4; return true; }