static void DNSSD_API enum_reply(DNSServiceRef client, const DNSServiceFlags flags, uint32_t ifIndex, DNSServiceErrorType errorCode, const char *replyDomain, void *context) { DNSServiceFlags partialflags = flags & ~(kDNSServiceFlagsMoreComing | kDNSServiceFlagsAdd | kDNSServiceFlagsDefault); int labels = 0, depth = 0, i, initial = 0; char text[64]; const char *label[128]; (void)client; // Unused (void)ifIndex; // Unused (void)context; // Unused // 1. Print the header if (num_printed++ == 0) printf("Timestamp Recommended %s domain\n", operation == 'E' ? "Registration" : "Browsing"); printtimestamp(); if (errorCode) printf("Error code %d\n", errorCode); else if (!*replyDomain) printf("Error: No reply domain\n"); else { printf("%-10s", DomainMsg(flags)); printf("%-8s", (flags & kDNSServiceFlagsMoreComing) ? "(More)" : ""); if (partialflags) printf("Flags: %4X ", partialflags); else printf(" "); // 2. Count the labels while (*replyDomain) { label[labels++] = replyDomain; replyDomain = GetNextLabel(replyDomain, text); } // 3. Decide if we're going to clump the last two or three labels (e.g. "apple.com", or "nicta.com.au") if (labels >= 3 && replyDomain - label[labels-1] <= 3 && label[labels-1] - label[labels-2] <= 4) initial = 3; else if (labels >= 2 && replyDomain - label[labels-1] <= 4) initial = 2; else initial = 1; labels -= initial; // 4. Print the initial one-, two- or three-label clump for (i=0; i<initial; i++) { GetNextLabel(label[labels+i], text); if (i>0) printf("."); printf("%s", text); } printf("\n"); // 5. Print the remainder of the hierarchy for (depth=0; depth<labels; depth++) { printf(" "); for (i=0; i<=depth; i++) printf("- "); GetNextLabel(label[labels-1-depth], text); printf("> %s\n", text); } } if (!(flags & kDNSServiceFlagsMoreComing)) fflush(stdout); }
static void DNSSD_API resolve_reply(DNSServiceRef client, const DNSServiceFlags flags, uint32_t ifIndex, DNSServiceErrorType errorCode, const char *fullname, const char *hosttarget, uint16_t opaqueport, uint16_t txtLen, const unsigned char *txtRecord, void *context) { union { uint16_t s; u_char b[2]; } port = { opaqueport }; uint16_t PortAsNumber = ((uint16_t)port.b[0]) << 8 | port.b[1]; (void)client; // Unused (void)ifIndex; // Unused (void)context; // Unused printtimestamp(); if (errorCode) printf("Error code %d\n", errorCode); else { printf("%s can be reached at %s:%u", fullname, hosttarget, PortAsNumber); if (flags) printf(" Flags: %X", flags); // Don't show degenerate TXT records containing nothing but a single empty string if (txtLen > 1) { printf("\n"); ShowTXTRecord(txtLen, txtRecord); } printf("\n"); } if (!(flags & kDNSServiceFlagsMoreComing)) fflush(stdout); }
static void myTimerCallBack(void) { DNSServiceErrorType err = kDNSServiceErr_Unknown; switch (operation) { case 'A': { switch (addtest) { case 0: printf("Adding Test HINFO record\n"); err = DNSServiceAddRecord(client, &record, 0, kDNSServiceType_HINFO, sizeof(myhinfoW), &myhinfoW[0], 0); addtest = 1; break; case 1: printf("Updating Test HINFO record\n"); err = DNSServiceUpdateRecord(client, record, 0, sizeof(myhinfoX), &myhinfoX[0], 0); addtest = 2; break; case 2: printf("Removing Test HINFO record\n"); err = DNSServiceRemoveRecord(client, record, 0); addtest = 0; break; } } break; case 'U': { if (updatetest[1] != 'Z') updatetest[1]++; else updatetest[1] = 'A'; updatetest[0] = 3 - updatetest[0]; updatetest[2] = updatetest[1]; printtimestamp(); printf("Updating Test TXT record to %c\n", updatetest[1]); err = DNSServiceUpdateRecord(client, NULL, 0, 1+updatetest[0], &updatetest[0], 0); } break; case 'N': { printf("Adding big NULL record\n"); err = DNSServiceAddRecord(client, &record, 0, kDNSServiceType_NULL, sizeof(bigNULL), &bigNULL[0], 0); if (err) printf("Failed: %d\n", err); else printf("Succeeded\n"); timeOut = LONG_TIME; } break; } if (err != kDNSServiceErr_NoError) { fprintf(stderr, "DNSService add/update/remove failed %ld\n", (long int)err); stopNow = 1; } }
static void DNSSD_API browse_reply(DNSServiceRef client, const DNSServiceFlags flags, uint32_t ifIndex, DNSServiceErrorType errorCode, const char *replyName, const char *replyType, const char *replyDomain, void *context) { char *op = (flags & kDNSServiceFlagsAdd) ? "Add" : "Rmv"; (void)client; // Unused (void)context; // Unused if (num_printed++ == 0) printf("Timestamp A/R Flags if %-25s %-25s %s\n", "Domain", "Service Type", "Instance Name"); printtimestamp(); if (errorCode) printf("Error code %d\n", errorCode); else printf("%s%6X%3d %-25s %-25s %s\n", op, flags, ifIndex, replyDomain, replyType, replyName); if (!(flags & kDNSServiceFlagsMoreComing)) fflush(stdout); }
static void DNSSD_API qr_reply(DNSServiceRef sdRef, const DNSServiceFlags flags, uint32_t ifIndex, DNSServiceErrorType errorCode, const char *fullname, uint16_t rrtype, uint16_t rrclass, uint16_t rdlen, const void *rdata, uint32_t ttl, void *context) { char *op = (flags & kDNSServiceFlagsAdd) ? "Add" : "Rmv"; const unsigned char *rd = rdata; const unsigned char *end = (const unsigned char *) rdata + rdlen; char rdb[1000]; int unknowntype = 0; (void)sdRef; // Unused (void)flags; // Unused (void)ifIndex; // Unused (void)ttl; // Unused (void)context; // Unused if (num_printed++ == 0) printf("Timestamp A/R Flags if %-30s%4s%4s Rdata\n", "Name", "T", "C"); printtimestamp(); if (errorCode) printf("Error code %d\n", errorCode); else { switch (rrtype) { case kDNSServiceType_A: sprintf(rdb, "%d.%d.%d.%d", rd[0], rd[1], rd[2], rd[3]); break; case kDNSServiceType_AAAA: sprintf(rdb, "%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X", rd[0x0], rd[0x1], rd[0x2], rd[0x3], rd[0x4], rd[0x5], rd[0x6], rd[0x7], rd[0x8], rd[0x9], rd[0xA], rd[0xB], rd[0xC], rd[0xD], rd[0xE], rd[0xF]); break; break; default : sprintf(rdb, "%d bytes%s", rdlen, rdlen ? ":" : ""); unknowntype = 1; break; } printf("%s%6X%3d %-30s%4d%4d %s", op, flags, ifIndex, fullname, rrtype, rrclass, rdb); if (unknowntype) while (rd < end) printf(" %02X", *rd++); printf("\n"); if (operation == 'C') if (flags & kDNSServiceFlagsAdd) DNSServiceReconfirmRecord(flags, ifIndex, fullname, rrtype, rrclass, rdlen, rdata); } if (!(flags & kDNSServiceFlagsMoreComing)) fflush(stdout); }
// DNSXEnableProxy Callback from the Daemon static void dnsproxy_reply(DNSXConnRef connRef, DNSXErrorType errCode) { (void) connRef; printtimestamp(); switch (errCode) { case kDNSX_NoError : printf(" SUCCESS \n"); break; case kDNSX_DictError : printf(" DICT ERROR \n"); break; case kDNSX_DaemonNotRunning : printf(" NO DAEMON \n"); DNSXRefDeAlloc(ClientRef); break; case kDNSX_Engaged : printf(" ENGAGED \n"); DNSXRefDeAlloc(ClientRef); break; case kDNSX_UnknownErr : default : printf("UNKNOWN ERR \n"); DNSXRefDeAlloc(ClientRef); break; } }
static void DNSSD_API port_mapping_create_reply(DNSServiceRef sdref, DNSServiceFlags flags, uint32_t ifIndex, DNSServiceErrorType errorCode, uint32_t publicAddress, uint32_t protocol, uint16_t privatePort, uint16_t publicPort, uint32_t ttl, void *context) { (void)sdref; // Unused (void)context; // Unused (void)flags; // Unused if (num_printed++ == 0) printf("Timestamp if %-20s %-15s %-15s %-15s %-6s\n", "External Address", "Protocol", "Internal Port", "External Port", "TTL"); printtimestamp(); if (errorCode && errorCode != kDNSServiceErr_DoubleNAT) printf("Error code %d\n", errorCode); else { const unsigned char *digits = (const unsigned char *)&publicAddress; char addr[256]; snprintf(addr, sizeof(addr), "%d.%d.%d.%d", digits[0], digits[1], digits[2], digits[3]); printf("%-4d %-20s %-15d %-15d %-15d %-6d%s\n", ifIndex, addr, protocol, ntohs(privatePort), ntohs(publicPort), ttl, errorCode == kDNSServiceErr_DoubleNAT ? " Double NAT" : ""); } fflush(stdout); }
// DNSXEnableProxy Callback from the Daemon static void dnsproxy_reply(DNSXConnRef connRef, DNSXErrorType errCode) { (void) connRef; printtimestamp(); switch (errCode) { case kDNSX_NoError : printf(" SUCCESS \n"); break; case kDNSX_DaemonNotRunning : printf(" NO DAEMON \n"); DNSXRefDeAlloc(ClientRef); break; case kDNSX_BadParam : printf(" BAD PARAMETER \n"); DNSXRefDeAlloc(ClientRef); break; case kDNSX_UnknownErr : default : printf(" UNKNOWN ERR \n"); DNSXRefDeAlloc(ClientRef); break; } fflush(NULL); }
static void DNSSD_API addrinfo_reply(DNSServiceRef sdref, DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType errorCode, const char *hostname, const struct sockaddr *address, uint32_t ttl, void *context) { char *op = (flags & kDNSServiceFlagsAdd) ? "Add" : "Rmv"; char addr[256] = ""; (void) sdref; (void) context; if (num_printed++ == 0) printf("Timestamp A/R Flags if %-25s %-44s %s\n", "Hostname", "Address", "TTL"); printtimestamp(); if (address && address->sa_family == AF_INET) { const unsigned char *b = (const unsigned char *) &((struct sockaddr_in *)address)->sin_addr; snprintf(addr, sizeof(addr), "%d.%d.%d.%d", b[0], b[1], b[2], b[3]); } else if (address && address->sa_family == AF_INET6) { char if_name[IFNAMSIZ]; // Older Linux distributions don't define IF_NAMESIZE const struct sockaddr_in6 *s6 = (const struct sockaddr_in6 *)address; const unsigned char *b = (const unsigned char * )&s6->sin6_addr; if (!if_indextoname(s6->sin6_scope_id, if_name)) snprintf(if_name, sizeof(if_name), "<%d>", s6->sin6_scope_id); snprintf(addr, sizeof(addr), "%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X%%%s", b[0x0], b[0x1], b[0x2], b[0x3], b[0x4], b[0x5], b[0x6], b[0x7], b[0x8], b[0x9], b[0xA], b[0xB], b[0xC], b[0xD], b[0xE], b[0xF], if_name); } printf("%s%6X%3d %-25s %-44s %d", op, flags, interfaceIndex, hostname, addr, ttl); if (errorCode) { if (errorCode == kDNSServiceErr_NoSuchRecord) printf(" No Such Record"); else printf(" Error code %d", errorCode); } printf("\n"); if (!(flags & kDNSServiceFlagsMoreComing)) fflush(stdout); }
int main(int argc, char **argv) { DNSXErrorType err; // Default i/p intf is lo0 and o/p intf is primary interface IfIndex Ipintfs[MaxInputIf] = {1, 0, 0, 0, 0}; IfIndex Opintf = kDNSIfindexAny; // Extract program name from argv[0], which by convention contains the path to this executable const char *a0 = strrchr(argv[0], kFilePathSep) + 1; if (a0 == (const char *)1) a0 = argv[0]; // Must run as root if (0 != geteuid()) { fprintf(stderr, "%s MUST run as root!!\n", a0); exit(-1); } if ((sizeof(argv) == 8)) printf("dnsctl running in 64-bit mode\n"); else if ((sizeof(argv) == 4)) printf("dnsctl running in 32-bit mode\n"); // expects atleast one argument if (argc < 2) goto Usage; if ( !strcmp(argv[1], "-DP") || !strcmp(argv[1], "-dp") ) { if (argc == 2) { printtimestamp(); printf("Proceeding to Enable DNSProxy on mDNSResponder with Default Parameters\n"); dispatch_queue_t my_Q = dispatch_queue_create("com.apple.dnsctl.callback_queue", NULL); err = DNSXEnableProxy(&ClientRef, kDNSProxyEnable, Ipintfs, Opintf, my_Q, dnsproxy_reply); } else if (argc > 2) { argc--; argv++; if (!strcmp(argv[1], "-o")) { Opintf = if_nametoindex(argv[2]); if (!Opintf) Opintf = atoi(argv[2]); if (!Opintf) { fprintf(stderr, "Could not parse o/p interface [%s]: Passing default primary \n", argv[2]); Opintf = kDNSIfindexAny; } argc -= 2; argv += 2; } if (argc > 2 && !strcmp(argv[1], "-i")) { int i; argc--; argv++; for (i = 0; i < MaxInputIf && argc > 1; i++) { Ipintfs[i] = if_nametoindex(argv[1]); if (!Ipintfs[i]) Ipintfs[i] = atoi(argv[1]); if (!Ipintfs[i]) { fprintf(stderr, "Could not parse i/p interface [%s]: Passing default lo0 \n", argv[2]); Ipintfs[i] = 1; } argc--; argv++; } } printtimestamp(); printf("Proceeding to Enable DNSProxy on mDNSResponder \n"); dispatch_queue_t my_Q = dispatch_queue_create("com.apple.dnsctl.callback_queue", NULL); err = DNSXEnableProxy(&ClientRef, kDNSProxyEnable, Ipintfs, Opintf, my_Q, dnsproxy_reply); } } else { goto Usage; } dispatch_main(); Usage: print_usage(a0); return 0; }
static void DNSSD_API qr_reply(DNSServiceRef sdref, const DNSServiceFlags flags, uint32_t ifIndex, DNSServiceErrorType errorCode, const char *fullname, uint16_t rrtype, uint16_t rrclass, uint16_t rdlen, const void *rdata, uint32_t ttl, void *context) { char *op = (flags & kDNSServiceFlagsAdd) ? "Add" : "Rmv"; const unsigned char *rd = rdata; const unsigned char *end = (const unsigned char *) rdata + rdlen; char rdb[1000] = "", *p = rdb; int unknowntype = 0; (void)sdref; // Unused (void)flags; // Unused (void)ifIndex; // Unused (void)ttl; // Unused (void)context; // Unused if (num_printed++ == 0) printf("Timestamp A/R Flags if %-30s%4s%4s Rdata\n", "Name", "T", "C"); printtimestamp(); if (!errorCode) { switch (rrtype) { case kDNSServiceType_A: snprintf(rdb, sizeof(rdb), "%d.%d.%d.%d", rd[0], rd[1], rd[2], rd[3]); break; case kDNSServiceType_NS: case kDNSServiceType_CNAME: case kDNSServiceType_PTR: case kDNSServiceType_DNAME: p += snprintd(p, sizeof(rdb), &rd); break; case kDNSServiceType_SOA: p += snprintd(p, rdb + sizeof(rdb) - p, &rd); // mname p += snprintf(p, rdb + sizeof(rdb) - p, " "); p += snprintd(p, rdb + sizeof(rdb) - p, &rd); // rname p += snprintf(p, rdb + sizeof(rdb) - p, " Ser %d Ref %d Ret %d Exp %d Min %d", ntohl(((uint32_t*)rd)[0]), ntohl(((uint32_t*)rd)[1]), ntohl(((uint32_t*)rd)[2]), ntohl(((uint32_t*)rd)[3]), ntohl(((uint32_t*)rd)[4])); break; case kDNSServiceType_AAAA: snprintf(rdb, sizeof(rdb), "%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X", rd[0x0], rd[0x1], rd[0x2], rd[0x3], rd[0x4], rd[0x5], rd[0x6], rd[0x7], rd[0x8], rd[0x9], rd[0xA], rd[0xB], rd[0xC], rd[0xD], rd[0xE], rd[0xF]); break; case kDNSServiceType_SRV: p += snprintf(p, rdb + sizeof(rdb) - p, "%d %d %d ", // priority, weight, port ntohs(*(unsigned short*)rd), ntohs(*(unsigned short*)(rd+2)), ntohs(*(unsigned short*)(rd+4))); rd += 6; p += snprintd(p, rdb + sizeof(rdb) - p, &rd); // target host break; default : snprintf(rdb, sizeof(rdb), "%d bytes%s", rdlen, rdlen ? ":" : ""); unknowntype = 1; break; } } printf("%s%6X%3d %-30s%4d%4d %s", op, flags, ifIndex, fullname, rrtype, rrclass, rdb); if (unknowntype) while (rd < end) printf(" %02X", *rd++); if (errorCode) { if (errorCode == kDNSServiceErr_NoSuchRecord) printf("No Such Record"); else printf("Error code %d", errorCode); } printf("\n"); if (operation == 'C') if (flags & kDNSServiceFlagsAdd) DNSServiceReconfirmRecord(flags, ifIndex, fullname, rrtype, rrclass, rdlen, rdata); if (!(flags & kDNSServiceFlagsMoreComing)) fflush(stdout); }
int main(int argc, char **argv) { uint32_t length; // length of the BlockHeader message BlockHeader *bhmsg = NULL; // serialized BlockHeader message Blob *bmsg = NULL; // serialized Blob message (size is given in the header) FILE * fd; char lenbuf[4]; unsigned char *buf = NULL; enum { osmheader, osmdata } state = osmheader; if (argc == 2) { fd = fopen(argv[1], "r"); if (fd == NULL) { fprintf(stderr, "Can't open %s", argv[1]); return -1; } } else { fd = stdin; } fputs_unlocked("<?xml version='1.0' encoding='UTF-8'?>\n<osm version=\"0.6\" generator=\"" PACKAGE_STRING "\">""\n", stdout); do { if (!fread(lenbuf, 4, 1, fd)) break; length = ntohl(*((uint32_t *) lenbuf)); // convert the buffer to a value if (verbose) fprintf(stderr, "Length BlockHeader: %d\n", length); if (length == 0 || length > MAX_BLOCK_HEADER_SIZE) { if (feof(fd)) { break; } fprintf(stderr, "Block Header isn't present or exceeds minimum/maximum size\n"); return 1; } /* Since we know the length of the BlockHeader now, we can allocate it */ buf = (unsigned char *) malloc(length * sizeof(unsigned char)); if (buf == NULL) { fprintf (stderr, "Error allocating BlockHeader buffer\n"); return 1; } /* We are reading the BlockHeader */ if(! fread(buf, length, 1, fd)) break; bhmsg = block_header__unpack (NULL, length, buf); free(buf); if (bhmsg == NULL) { fprintf(stderr, "Error unpacking BlockHeader message\n"); return 1; } length = bhmsg->datasize; if (verbose) fprintf(stderr, "Type: %s\nLength: %u\n", bhmsg->type, length); if (length <= 0 || length > MAX_BLOB_SIZE) { fprintf(stderr, "Blob isn't present or exceeds minimum/maximum size\n"); return 1; } if (strcmp(bhmsg->type, "OSMHeader") == 0) { state = osmheader; } else if (strcmp(bhmsg->type, "OSMData") == 0) { state = osmdata; } block_header__free_unpacked (bhmsg, &protobuf_c_system_allocator); /* We are now reading the 'Blob' */ buf = (unsigned char *) malloc(length * sizeof(unsigned char *)); if(! fread(buf, length, 1, fd)) break; bmsg = blob__unpack (NULL, length, buf); if (bmsg == NULL) { fprintf(stderr, "Error unpacking Blob message\n"); return 1; } free(buf); unsigned char *uncompressed; if (bmsg->has_raw) { uncompressed = bmsg->raw.data; bmsg->raw_size = bmsg->raw.len; // I wonder if we should do this. } else { uncompressed = handleCompressedBlob(bmsg); if (uncompressed == NULL) { fprintf(stderr, "Uncompression failed\n"); return 1; } } if (state == osmheader) { HeaderBlock *hmsg = header_block__unpack (NULL, bmsg->raw_size, uncompressed); if (hmsg == NULL) { fprintf(stderr, "Error unpacking HeaderBlock message\n"); return 1; } if (verbose) fprintf(stderr, "%s\n", hmsg->required_features[0]); header_block__free_unpacked (hmsg, &protobuf_c_system_allocator); } else if (state == osmdata) { /* * Unpack Block and check if all went well */ PrimitiveBlock *pmsg = primitive_block__unpack (NULL, bmsg->raw_size, uncompressed); if (pmsg == NULL) { fprintf(stderr, "Error unpacking PrimitiveBlock message\n"); return 1; } double lat_offset = NANO_DEGREE * pmsg->lat_offset; double lon_offset = NANO_DEGREE * pmsg->lon_offset; double granularity = NANO_DEGREE * pmsg->granularity; if (verbose) fprintf(stderr, "\t""Granularity: %d""\n", pmsg->granularity); if (verbose) fprintf(stderr, "\t""Primitive groups: %li""\n", pmsg->n_primitivegroup); for (unsigned int j = 0; j < pmsg->n_primitivegroup; j++) { if (verbose) fprintf(stderr,"\t\t""Nodes: %li""\n"\ "\t\t""Ways: %li""\n"\ "\t\t""Relations: %li""\n", (pmsg->primitivegroup[j]->dense ? pmsg->primitivegroup[j]->dense->n_id : pmsg->primitivegroup[j]->n_nodes), pmsg->primitivegroup[j]->n_ways, pmsg->primitivegroup[j]->n_relations); /* TODO: Nodes is *untested* */ if (pmsg->primitivegroup[j]->n_nodes > 0) { for (unsigned k = 0; k < pmsg->primitivegroup[j]->n_nodes; k++) { Node *node = pmsg->primitivegroup[j]->nodes[k]; printf("\t""<node id=\"%li\" lat=\"%.07f\" lon=\"%.07f\"", node->id, lat_offset + (node->lat * granularity), lon_offset + (node->lon * granularity)); if (node->info) { Info *info = node->info; if (info->has_version) { printnumericattribute("version", info->version); } if (info->has_changeset) { printnumericattribute("changeset", info->changeset); } if (info->has_user_sid) { ProtobufCBinaryData user = pmsg->stringtable->s[info->user_sid]; printuser(user); } if (info->has_uid) { printnumericattribute("uid", info->uid); } if (info->has_timestamp) { printtimestamp("timestamp", info->timestamp); } } if (node->n_keys == 0 || node->n_vals == 0) { fputs_unlocked("/>""\n", stdout); } else { fputs_unlocked(">""\n", stdout); for (unsigned l = 0; l < node->n_keys; l++) { ProtobufCBinaryData key = pmsg->stringtable->s[node->keys[l]]; ProtobufCBinaryData val = pmsg->stringtable->s[node->vals[l]]; printtag(key, val); } fputs_unlocked("\t""</node>""\n", stdout); } } } else if (pmsg->primitivegroup[j]->n_ways > 0) { for (unsigned k = 0; k < pmsg->primitivegroup[j]->n_ways; k++) { Way *way = pmsg->primitivegroup[j]->ways[k]; printsotid("way", way->id); if (way->info) { Info *info = way->info; if (info->has_version) { printnumericattribute("version", info->version); } if (info->has_changeset) { printnumericattribute("changeset", info->changeset); } if (info->has_user_sid) { ProtobufCBinaryData user = pmsg->stringtable->s[info->user_sid]; printuser(user); } if (info->has_uid) { printnumericattribute("uid", info->uid); } if (info->has_timestamp) { printtimestamp("timestamp", info->timestamp); } } if ((way->n_keys == 0 || way->n_vals == 0) && way->n_refs == 0) { fputs_unlocked("/>""\n", stdout); } else { long int deltaref = 0; fputs_unlocked(">""\n", stdout); for (unsigned l = 0; l < way->n_refs; l++) { deltaref += way->refs[l]; printnd(deltaref); } for (unsigned l = 0; l < way->n_keys; l++) { ProtobufCBinaryData key = pmsg->stringtable->s[way->keys[l]]; ProtobufCBinaryData val = pmsg->stringtable->s[way->vals[l]]; printtag(key, val); } fputs_unlocked("\t""</way>""\n", stdout); } } } else if (pmsg->primitivegroup[j]->n_relations > 0) { for (unsigned k = 0; k < pmsg->primitivegroup[j]->n_relations; k++) { Relation *relation = pmsg->primitivegroup[j]->relations[k]; printsotid("relation", relation->id); if (relation->info) { Info *info = relation->info; if (info->has_version) { printnumericattribute("version", info->version); } if (info->has_changeset) { printnumericattribute("changeset", info->changeset); } if (info->has_user_sid) { ProtobufCBinaryData user = pmsg->stringtable->s[info->user_sid]; printuser(user); } if (info->has_uid) { printnumericattribute("uid", info->uid); } if (info->has_timestamp) { printtimestamp("timestamp", info->timestamp); } } if ((relation->n_keys == 0 || relation->n_vals == 0) && relation->n_memids == 0) { fputs_unlocked("/>""\n", stdout); } else { long int deltamemids = 0; fputs_unlocked(">""\n", stdout); for (unsigned l = 0; l < relation->n_memids; l++) { char *type; ProtobufCBinaryData role = pmsg->stringtable->s[relation->roles_sid[l]]; deltamemids += relation->memids[l]; switch (relation->types[l]) { case RELATION__MEMBER_TYPE__NODE: type = "node"; break; case RELATION__MEMBER_TYPE__WAY: type = "way"; break; case RELATION__MEMBER_TYPE__RELATION: type = "relation"; break; default: fprintf(stderr, "Unsupported type: %u""\n", relation->types[l]); return 1; } printmember(type, deltamemids, role); } for (unsigned l = 0; l < relation->n_keys; l++) { ProtobufCBinaryData key = pmsg->stringtable->s[relation->keys[l]]; ProtobufCBinaryData val = pmsg->stringtable->s[relation->vals[l]]; printtag(key, val); } fputs_unlocked("\t""</relation>""\n", stdout); } } } else if (pmsg->primitivegroup[j]->n_changesets > 0) { for (unsigned k = 0; k < pmsg->primitivegroup[j]->n_changesets; k++) { ChangeSet *changeset = pmsg->primitivegroup[j]->changesets[k]; printsotid("changeset", changeset->id); if (changeset->info) { Info *info = changeset->info; /* Not in Changeset if (info->has_version) { printnumericattribute("version", info->version); } if (info->has_changeset) { printnumericattribute("changeset", info->changeset); }*/ if (info->has_user_sid) { ProtobufCBinaryData user = pmsg->stringtable->s[info->user_sid]; printuser(user); } if (info->has_uid) { printnumericattribute("uid", info->uid); } if (info->has_timestamp) { printtimestamp("created_at", info->timestamp); if (changeset->has_closetime_delta) { printtimestamp("closed_at", (info->timestamp + changeset->closetime_delta)); } } } printf(" open=\"%s\" min_lon=\"%.07f\" min_lat=\"%.07f\" max_lon=\"%.07f\" max_lat=\"%.07f\"", (changeset->open ? "true" : "false"), lat_offset + (changeset->bbox->left * granularity), lon_offset + (changeset->bbox->bottom * granularity), lat_offset + (changeset->bbox->right * granularity), lon_offset + (changeset->bbox->top * granularity)); if (changeset->n_keys == 0 || changeset->n_vals == 0) { fputs_unlocked("/>""\n", stdout); } else { fputs_unlocked(">""\n", stdout); for (unsigned l = 0; l < changeset->n_keys; l++) { ProtobufCBinaryData key = pmsg->stringtable->s[changeset->keys[l]]; ProtobufCBinaryData val = pmsg->stringtable->s[changeset->vals[l]]; printtag(key, val); } fputs_unlocked("\t""</changeset>""\n", stdout); } } } else if (pmsg->primitivegroup[j]->dense) { unsigned l = 0; unsigned long int deltaid = 0; long int deltalat = 0; long int deltalon = 0; unsigned long int deltatimestamp = 0; unsigned long int deltachangeset = 0; long int deltauid = 0; unsigned long int deltauser_sid = 0; DenseNodes *dense = pmsg->primitivegroup[j]->dense; for (unsigned k = 0; k < dense->n_id; k++) { unsigned char has_tags = 0; deltaid += dense->id[k]; deltalat += dense->lat[k]; deltalon += dense->lon[k]; printf("\t""<node id=\"%li\" lat=\"%.07f\" lon=\"%.07f\"", deltaid, lat_offset + (deltalat * granularity), lon_offset + (deltalon * granularity)); if (dense->denseinfo) { DenseInfo *denseinfo = dense->denseinfo; deltatimestamp += denseinfo->timestamp[k]; deltachangeset += denseinfo->changeset[k]; deltauid += denseinfo->uid[k]; deltauser_sid += denseinfo->user_sid[k]; printnumericattribute("version", denseinfo->version[k]); printnumericattribute("changeset", deltachangeset); if (deltauid != -1) { // osmosis devs failed to read the specs printuser(pmsg->stringtable->s[deltauser_sid]); printnumericattribute("uid", deltauid); } printtimestamp("timestamp", deltatimestamp); } if (l < dense->n_keys_vals) { while (dense->keys_vals[l] != 0 && l < dense->n_keys_vals) { if (has_tags < 1) { has_tags++; fputs_unlocked(">\n", stdout); } ProtobufCBinaryData key = pmsg->stringtable->s[dense->keys_vals[l]]; ProtobufCBinaryData val = pmsg->stringtable->s[dense->keys_vals[l+1]]; printtag(key, val); l += 2; } l += 1; } if (has_tags < 1) { fputs_unlocked("/>""\n", stdout); } else { fputs_unlocked("\t""</node>""\n", stdout); } } } } primitive_block__free_unpacked (pmsg, &protobuf_c_system_allocator); } if (!bmsg->has_raw) free(uncompressed); blob__free_unpacked (bmsg, &protobuf_c_system_allocator); } while (!feof(fd)); fputs_unlocked("</osm>""\n", stdout); if (!feof(fd)) { fprintf(stderr, "Input processing terminated early\n"); return 1; } return 0; }