static void chmfile_system_info(struct chmFile *cfd, ChmFile *chmfile) { struct chmUnitInfo ui; unsigned char buffer[4096]; int index = 0; unsigned char* cursor = NULL; u_int16_t value = 0; u_int32_t lcid = 0; size_t size = 0; if (chm_resolve_object(cfd, "/#SYSTEM", &ui) != CHM_RESOLVE_SUCCESS) return; size = chm_retrieve_object(cfd, &ui, buffer, 4L, 4096); if (!size) return; buffer[size - 1] = 0; for(;;) { // This condition won't hold if I process anything // except NUL-terminated strings! if(index > size - 1 - (long)sizeof(u_int16_t)) break; cursor = buffer + index; value = UINT16ARRAY(cursor); g_debug("system value = %d", value); switch(value) { case 0: index += 2; cursor = buffer + index; chmfile->hhc = g_strdup_printf("/%s", buffer + index + 2); g_debug("hhc %s", chmfile->hhc); break; case 1: index += 2; cursor = buffer + index; chmfile->hhk = g_strdup_printf("/%s", buffer + index + 2); g_debug("hhk %s", chmfile->hhk); break; case 2: index += 2; cursor = buffer + index; chmfile->home = g_strdup_printf("/%s", buffer + index + 2); g_debug("home %s", chmfile->home); break; case 3: index += 2; cursor = buffer + index; chmfile->title = g_strdup((char *)buffer + index + 2); g_debug("title %s", chmfile->title); break; case 4: // LCID stuff index += 2; cursor = buffer + index; lcid = UINT32ARRAY(buffer + index + 2); g_debug("lcid %x", lcid); chmfile->encoding = get_encoding_by_lcid(lcid); break; case 6: index += 2; cursor = buffer + index; if(!chmfile->hhc) { char *hhc, *hhk; hhc = g_strdup_printf("/%s.hhc", buffer + index + 2); hhk = g_strdup_printf("/%s.hhk", buffer + index + 2); if (chm_resolve_object(cfd, hhc, &ui) == CHM_RESOLVE_SUCCESS) chmfile->hhc = hhc; if (chm_resolve_object(cfd, hhk, &ui) == CHM_RESOLVE_SUCCESS) chmfile->hhk = hhk; } break; case 16: index += 2; cursor = buffer + index; g_debug("font %s", buffer + index + 2); break; default: index += 2; cursor = buffer + index; } value = UINT16ARRAY(cursor); index += value + 2; } }
static void chm_system_info(struct fileinfo *info) { FILE *fp; unsigned char buffer[4096]; char system_file[1024]; size_t size = 0, len = 0; int index = 0; unsigned char* cursor = NULL; u_int16_t value = 0; sprintf(system_file, "%s/#SYSTEM", info->bookfolder); d(printf("chm_system_info >>> system info file = %s\n", system_file)); fp = fopen(system_file, "r"); if (fp == NULL) { fprintf(stderr, "#SYSTEM file open failed.\n"); return; } fread(buffer, sizeof(char), 4, fp); // Skip 4 bytes size = fread(buffer, sizeof(char), 4096, fp); if (!size) return; buffer[size - 1] = 0; for(;;) { if (index > size - 1 - (long)sizeof(u_int16_t)) break; cursor = buffer + index; value = UINT16ARRAY(cursor); d(printf("chm_system_info >>> value = %d\n", value)); switch(value) { case 0: index += 2; cursor = buffer + index; len = strlen((const char*)(buffer + index + 2)); info->hhc = (char *)malloc(len + 1); strcpy(info->hhc, (const char*)(buffer + index + 2)); d(printf("chm_system_info >>> hhc = %s\n", info->hhc)); break; case 1: index += 2; cursor = buffer + index; len = strlen((const char*)(buffer + index + 2)); info->hhk = (char *)malloc(len + 1); strcpy(info->hhk, (const char*)(buffer + index + 2)); d(printf("chm_system_info >>> hhk = %s\n", info->hhk)); break; case 2: index += 2; cursor = buffer + index; len = strlen((const char*)(buffer + index + 2)); info->homepage = (char *)malloc(len + 1); strcpy(info->homepage, (const char*)(buffer + index + 2)); d(printf("chm_system_info >>> homepage = %s\n", info->homepage)); break; case 3: index += 2; cursor = buffer + index; len = strlen((const char*)(buffer + index + 2)); info->bookname = (char *)malloc(len + 1); strcpy(info->bookname, (const char*)(buffer + index + 2)); d(printf("chm_system_info >>> bookname = %s\n", info->bookname)); break; case 4: index += 2; cursor = buffer + index; info->lcid = UINT32ARRAY(buffer + index + 2); break; default: index += 2; cursor = buffer + index; } value = UINT16ARRAY(cursor); index += value + 2; } }