📄 loc_29.c
字号:
/* * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. *//* $Id: loc_29.c,v 1.30.2.3.2.6 2004/03/06 08:14:06 marka Exp $ *//* Reviewed: Wed Mar 15 18:13:09 PST 2000 by explorer *//* RFC 1876 */#ifndef RDATA_GENERIC_LOC_29_C#define RDATA_GENERIC_LOC_29_C#define RRTYPE_LOC_ATTRIBUTES (0)static inline isc_result_tfromtext_loc(ARGS_FROMTEXT) { isc_token_t token; int d1, m1, s1; int d2, m2, s2; unsigned char size; unsigned char hp; unsigned char vp; unsigned char version; isc_boolean_t east = ISC_FALSE; isc_boolean_t north = ISC_FALSE; long tmp; long m; long cm; long poweroften[8] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000 }; int man; int exp; char *e; int i; unsigned long latitude; unsigned long longitude; unsigned long altitude; REQUIRE(type == 29); UNUSED(type); UNUSED(rdclass); UNUSED(origin); UNUSED(options); /* * Defaults. */ m1 = s1 = 0; m2 = s2 = 0; size = 0x12; /* 1.00m */ hp = 0x16; /* 10000.00 m */ vp = 0x13; /* 10.00 m */ version = 0; /* * Degrees. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, ISC_FALSE)); if (token.value.as_ulong > 90U) RETTOK(ISC_R_RANGE); d1 = (int)token.value.as_ulong; /* * Minutes. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); if (strcasecmp(DNS_AS_STR(token), "N") == 0) north = ISC_TRUE; if (north || strcasecmp(DNS_AS_STR(token), "S") == 0) goto getlong; m1 = strtol(DNS_AS_STR(token), &e, 10); if (*e != 0) RETTOK(DNS_R_SYNTAX); if (m1 < 0 || m1 > 59) RETTOK(ISC_R_RANGE); if (d1 == 90 && m1 != 0) RETTOK(ISC_R_RANGE); /* * Seconds. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); if (strcasecmp(DNS_AS_STR(token), "N") == 0) north = ISC_TRUE; if (north || strcasecmp(DNS_AS_STR(token), "S") == 0) goto getlong; s1 = strtol(DNS_AS_STR(token), &e, 10); if (*e != 0 && *e != '.') RETTOK(DNS_R_SYNTAX); if (s1 < 0 || s1 > 59) RETTOK(ISC_R_RANGE); if (*e == '.') { const char *l; e++; for (i = 0; i < 3; i++) { if (*e == 0) break; if ((tmp = decvalue(*e++)) < 0) RETTOK(DNS_R_SYNTAX); s1 *= 10; s1 += tmp; } for (; i < 3; i++) s1 *= 10; l = e; while (*e != 0) { if (decvalue(*e++) < 0) RETTOK(DNS_R_SYNTAX); } if (*l != '\0' && callbacks != NULL) { const char *file = isc_lex_getsourcename(lexer); unsigned long line = isc_lex_getsourceline(lexer); if (file == NULL) file = "UNKNOWN"; (*callbacks->warn)(callbacks, "%s: %s:%u: '%s' extra " "precision digits ignored", "dns_rdata_fromtext", file, line, DNS_AS_STR(token)); } } else s1 *= 1000; if (d1 == 90 && s1 != 0) RETTOK(ISC_R_RANGE); /* * Direction. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); if (strcasecmp(DNS_AS_STR(token), "N") == 0) north = ISC_TRUE; if (!north && strcasecmp(DNS_AS_STR(token), "S") != 0) RETTOK(DNS_R_SYNTAX); getlong: /* * Degrees. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, ISC_FALSE)); if (token.value.as_ulong > 180U) RETTOK(ISC_R_RANGE); d2 = (int)token.value.as_ulong; /* * Minutes. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); if (strcasecmp(DNS_AS_STR(token), "E") == 0) east = ISC_TRUE; if (east || strcasecmp(DNS_AS_STR(token), "W") == 0) goto getalt; m2 = strtol(DNS_AS_STR(token), &e, 10); if (*e != 0) RETTOK(DNS_R_SYNTAX); if (m2 < 0 || m2 > 59) RETTOK(ISC_R_RANGE); if (d2 == 180 && m2 != 0) RETTOK(ISC_R_RANGE); /* * Seconds. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); if (strcasecmp(DNS_AS_STR(token), "E") == 0) east = ISC_TRUE; if (east || strcasecmp(DNS_AS_STR(token), "W") == 0) goto getalt; s2 = strtol(DNS_AS_STR(token), &e, 10); if (*e != 0 && *e != '.') RETTOK(DNS_R_SYNTAX); if (s2 < 0 || s2 > 59) RETTOK(ISC_R_RANGE); if (*e == '.') { const char *l; e++; for (i = 0; i < 3; i++) { if (*e == 0) break; if ((tmp = decvalue(*e++)) < 0) RETTOK(DNS_R_SYNTAX); s2 *= 10; s2 += tmp; } for (; i < 3; i++) s2 *= 10; l = e; while (*e != 0) { if (decvalue(*e++) < 0) RETTOK(DNS_R_SYNTAX); } if (*l != '\0' && callbacks != NULL) { const char *file = isc_lex_getsourcename(lexer); unsigned long line = isc_lex_getsourceline(lexer); if (file == NULL) file = "UNKNOWN"; (*callbacks->warn)(callbacks, "%s: %s:%u: '%s' extra " "precision digits ignored", "dns_rdata_fromtext", file, line, DNS_AS_STR(token)); } } else s2 *= 1000; if (d2 == 180 && s2 != 0) RETTOK(ISC_R_RANGE); /* * Direction. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); if (strcasecmp(DNS_AS_STR(token), "E") == 0) east = ISC_TRUE; if (!east && strcasecmp(DNS_AS_STR(token), "W") != 0) RETTOK(DNS_R_SYNTAX); getalt: /* * Altitude. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); m = strtol(DNS_AS_STR(token), &e, 10); if (*e != 0 && *e != '.' && *e != 'm') RETTOK(DNS_R_SYNTAX); if (m < -100000 || m > 42849672) RETTOK(ISC_R_RANGE); cm = 0; if (*e == '.') { e++; for (i = 0; i < 2; i++) { if (*e == 0 || *e == 'm') break; if ((tmp = decvalue(*e++)) < 0) return (DNS_R_SYNTAX); cm *= 10; if (m < 0) cm -= tmp; else cm += tmp; } for (; i < 2; i++) cm *= 10; } if (*e == 'm') e++; if (*e != 0) RETTOK(DNS_R_SYNTAX); if (m == -100000 && cm != 0) RETTOK(ISC_R_RANGE); if (m == 42849672 && cm > 95) RETTOK(ISC_R_RANGE); /* * Adjust base. */ altitude = m + 100000; altitude *= 100; altitude += cm; /* * Size: optional. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_TRUE)); if (token.type == isc_tokentype_eol || token.type == isc_tokentype_eof) { isc_lex_ungettoken(lexer, &token); goto encode; } m = strtol(DNS_AS_STR(token), &e, 10); if (*e != 0 && *e != '.' && *e != 'm') RETTOK(DNS_R_SYNTAX); if (m < 0 || m > 90000000) RETTOK(ISC_R_RANGE); cm = 0; if (*e == '.') { e++; for (i = 0; i < 2; i++) { if (*e == 0 || *e == 'm') break; if ((tmp = decvalue(*e++)) < 0) RETTOK(DNS_R_SYNTAX); cm *= 10; cm += tmp; } for (; i < 2; i++) cm *= 10; } if (*e == 'm') e++; if (*e != 0) RETTOK(DNS_R_SYNTAX); /* * We don't just multiply out as we will overflow. */ if (m > 0) { for (exp = 0; exp < 7; exp++) if (m < poweroften[exp+1]) break; man = m / poweroften[exp]; exp += 2; } else { if (cm >= 10) { man = cm / 10; exp = 1; } else { man = cm; exp = 0; } } size = (man << 4) + exp; /* * Horizontal precision: optional. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_TRUE)); if (token.type == isc_tokentype_eol || token.type == isc_tokentype_eof) { isc_lex_ungettoken(lexer, &token); goto encode; } m = strtol(DNS_AS_STR(token), &e, 10); if (*e != 0 && *e != '.' && *e != 'm') RETTOK(DNS_R_SYNTAX); if (m < 0 || m > 90000000) RETTOK(ISC_R_RANGE); cm = 0; if (*e == '.') { e++; for (i = 0; i < 2; i++) { if (*e == 0 || *e == 'm') break; if ((tmp = decvalue(*e++)) < 0) RETTOK(DNS_R_SYNTAX); cm *= 10; cm += tmp; } for (; i < 2; i++) cm *= 10; } if (*e == 'm') e++; if (*e != 0) RETTOK(DNS_R_SYNTAX); /* * We don't just multiply out as we will overflow. */ if (m > 0) { for (exp = 0; exp < 7; exp++) if (m < poweroften[exp+1]) break; man = m / poweroften[exp]; exp += 2; } else if (cm >= 10) { man = cm / 10; exp = 1; } else { man = cm; exp = 0; } hp = (man << 4) + exp; /* * Vertical precision: optional. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_TRUE)); if (token.type == isc_tokentype_eol || token.type == isc_tokentype_eof) { isc_lex_ungettoken(lexer, &token); goto encode; } m = strtol(DNS_AS_STR(token), &e, 10); if (*e != 0 && *e != '.' && *e != 'm') RETTOK(DNS_R_SYNTAX); if (m < 0 || m > 90000000)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -