/* global functions */ int main(int argc, char *argv[]){ int fd; void *map; unsigned int size; /* init */ traps(); if(argc != 4){ fprintf(stderr, "Usage: %s <depfile> <config_header> <config_dir>\n", argv[0]); return 1; } depfile = argv[1]; conf_header = argv[2]; conf_dir = argv[3]; /* open and mmap depfile */ if(file_map(depfile, &fd, &map, &size) != 0) return 1; /* parse depfile */ parse_dep_file(map, size); /* exit */ file_unmap(fd, map, size); return 0; }
void tdisk_finish() { int i; for (i = 0; i < 4; i++) { if (!tdisks[i].image) continue; file_unmap (tdisks[i].image, tdisks[i].length, !tdisks[i].ro); } }
static void read_hues() { const char *end; const char *p = file_map("files/hues.mul", &end); parse_hues(p, end); file_unmap(p, end); }
static void read_tiledata() { const char *end; const char *p = file_map("files/tiledata.mul", &end); parse_tiledata(p, end); file_unmap(p, end); }
static void read_cliloc() { const char *end; const char *p = file_map("files/Cliloc.enu", &end); parse_cliloc(p, end); file_unmap(p, end); }
static void read_speech() { const char *end; const char *p = file_map("files/speech.mul", &end); // do stuff... parse_speech(p, end, NULL); file_unmap(p, end); }
static void index(const char *filename, ml_index **idx) { const char *end; const char *p = file_map(filename, &end); //printf("index: %s\n", filename); parse_index(p, end, idx); file_unmap(p, end); }
void file_unmap_all(void) { struct file *f=file_list; int limit=1000; while (f && limit-- > 0) { file_unmap(f); f=f->next; } }
void file_destroy(struct file *f) { close(f->fd); if ( f->begin != NULL ) { file_unmap( f ); } g_free(f->name); g_free(f); }
static void land(int offset, int length, ml_art **art, bool rotate) { const char *end; const char *p = file_map("files/art.mul", &end); assert(offset >= 0); assert(length >= 0); assert(p + offset + length <= end); // do stuff... parse_land(p + offset, p + offset + length, art, rotate); file_unmap(p, end); }
static void gump(int offset, int length, int width, int height, ml_gump **g) { const char *end; const char *p = file_map("files/Gumpart.mul", &end); assert(offset >= 0); assert(length >= 0); assert(p + offset + length <= end); // do stuff... parse_gump(p + offset, p + offset + length, width, height, g); file_unmap(p, end); }
static void multi(int offset, int length, ml_multi **m) { const char *end; const char *p = file_map("files/multi.mul", &end); assert(offset >= 0); assert(length >= 0); assert(p + offset + length <= end); printf("offset: %d, length: %d\n", offset, length); // do stuff... parse_multi(p + offset, p + offset + length, m); file_unmap(p, end); }
static void anim(int offset, int length, ml_anim **animation) { const char *end; const char *p = file_map("files/anim.mul", &end); assert(offset >= 0); assert(length >= 0); assert(p + offset + length <= end); //printf("offset %d length %d\n", offset, length); // do stuff... parse_anim(p + offset, p + offset + length, animation); file_unmap(p, end); }
static void read_unicode_font_metadata() { assert(font_metadatas == NULL); font_metadata_count = 13; font_metadatas = (ml_font_metadata *)malloc(sizeof(ml_font_metadata) * font_metadata_count); for (int i = 0; i < font_metadata_count; i++) { unicode_font_metadata(i, &font_metadatas[i]); } const char *end; const char *p = file_map("files/Cliloc.enu", &end); parse_cliloc(p, end); file_unmap(p, end); }
void file_destroy(struct file *f) { if (f->headers) g_hash_table_destroy(f->headers); switch (f->special) { case 0: case 1: close(f->fd); break; } if ( f->begin != NULL ) { file_unmap( f ); } g_free(f->buffer); g_free(f->name); g_free(f); }
static void render_unicode_font_string(int font_id, std::wstring s, ml_art **res) { assert(font_id >= 0 && font_id <= 12); char filename[128]; if (font_id == 0) { sprintf(filename, "files/unifont.mul"); } else { sprintf(filename, "files/unifont%d.mul", font_id); } const char *end; const char *p; p = file_map(filename, &end); parse_render_unicode_font_string(p, end, font_id, s, res); file_unmap(p, end); }
static void statics_block(int map, int offset, int length, ml_statics_block **sb) { assert(map == 0 || map == 1); const char *end; const char *p; if (map == 0) { p = file_map("files/statics0.mul", &end); } else if (map == 1) { p = file_map("files/statics1.mul", &end); } assert(offset >= 0); assert(length >= 0); assert(p + offset + length <= end); parse_statics_block(p + offset, p + offset + length, sb); file_unmap(p, end); }
static void unicode_font_metadata(int font_id, ml_font_metadata *font_metadata) { assert(font_id >= 0 && font_id <= 12); char filename[128]; if (font_id == 0) { sprintf(filename, "files/unifont.mul"); } else { sprintf(filename, "files/unifont%d.mul", font_id); } const char *end; const char *p; p = file_map(filename, &end); parse_unicode_font_metadata(p, end, font_metadata); file_unmap(p, end); }
MEXP(int) checkRevision(const char* formula, const char* files[], int numFiles, int mpqNumber, unsigned long* checksum) { long values[4], ovd[4], ovs1[4], ovs2[4]; char ops[4]; const char* token; int curFormula = 0; file_t f; uint8_t* file_buffer; uint32_t* dwBuf; uint32_t* current; size_t seed_count; #if DEBUG int i; bncsutil_debug_message_a("checkRevision(\"%s\", {", formula); for (i = 0; i < numFiles; i++) { bncsutil_debug_message_a("\t\"%s\",", files[i]); } bncsutil_debug_message_a("}, %d, %d, %p);", numFiles, mpqNumber, checksum); #endif if (!formula || !files || numFiles == 0 || mpqNumber <= 0 || !checksum) { bncsutil_debug_message("error: checkRevision() parameter sanity check " "failed"); return 0; } seed_count = checkrevision_seeds.size(); if (seed_count == 0) { initialize_checkrevision_seeds(); seed_count = checkrevision_seeds.size(); } if (seed_count <= (size_t) mpqNumber) { bncsutil_debug_message_a("error: no revision check seed value defined " "for MPQ number %d", mpqNumber); return 0; } token = formula; while (token && *token) { if (*(token + 1) == '=') { int variable = BUCR_GETNUM(*token); if (variable < 0 || variable > 3) { bncsutil_debug_message_a("error: Unknown revision check formula" " variable %c", *token); return 0; } token += 2; // skip over equals sign if (BUCR_ISNUM(*token)) { values[variable] = atol(token); } else { if (curFormula > 3) { // more than 4 operations? bloody hell. bncsutil_debug_message("error: Revision check formula" " contains more than 4 operations; unsupported."); return 0; } ovd[curFormula] = variable; ovs1[curFormula] = BUCR_GETNUM(*token); ops[curFormula] = *(token + 1); ovs2[curFormula] = BUCR_GETNUM(*(token + 2)); curFormula++; } } for (; *token != 0; token++) { if (*token == ' ') { token++; break; } } } // Actual hashing (yay!) // "hash A by the hashcode" values[0] ^= checkrevision_seeds[mpqNumber]; for (int i = 0; i < numFiles; i++) { size_t file_len, remainder, rounded_size, buffer_size; f = file_open(files[i], FILE_READ); if (!f) { bncsutil_debug_message_a("error: Failed to open file %s", files[i]); return 0; } file_len = file_size(f); remainder = file_len % 1024; rounded_size = file_len - remainder; file_buffer = (uint8_t*) file_map(f, file_len, 0); if (!file_buffer) { file_close(f); bncsutil_debug_message_a("error: Failed to map file %s into memory", files[i]); return 0; } if (remainder == 0) { // Mapped buffer may be used directly, without padding. dwBuf = (uint32_t*) file_buffer; buffer_size = file_len; } else { // Must be padded to nearest KB. size_t extra = 1024 - remainder; uint8_t pad = (uint8_t) 0xFF; uint8_t* pad_dest; buffer_size = file_len + extra; dwBuf = (uint32_t*) malloc(buffer_size); if (!dwBuf) { bncsutil_debug_message_a("error: Failed to allocate %d bytes " "of memory as a temporary buffer", buffer_size); file_unmap(f, file_buffer); file_close(f); return 0; } memcpy(dwBuf, file_buffer, file_len); file_unmap(f, file_buffer); file_buffer = (uint8_t*) 0; pad_dest = ((uint8_t*) dwBuf) + file_len; for (size_t j = file_len; j < buffer_size; j++) { *pad_dest++ = pad--; } } current = dwBuf; for (size_t j = 0; j < buffer_size; j += 4) { values[3] = LSB4(*(current++)); for (int k = 0; k < curFormula; k++) { switch (ops[k]) { case '+': values[ovd[k]] = values[ovs1[k]] + values[ovs2[k]]; break; case '-': values[ovd[k]] = values[ovs1[k]] - values[ovs2[k]]; break; case '^': values[ovd[k]] = values[ovs1[k]] ^ values[ovs2[k]]; break; case '*': // well, you never know values[ovd[k]] = values[ovs1[k]] * values[ovs2[k]]; break; case '/': // well, you never know values[ovd[k]] = values[ovs1[k]] / values[ovs2[k]]; break; default: // unrecognized operation // shit file_unmap(f, dwBuf); file_close(f); return 0; } } } if (file_buffer) file_unmap(f, file_buffer); else if (dwBuf && file_buffer == 0) free(dwBuf); // padded buffer file_close(f); } *checksum = (unsigned long) LSB4(values[2]); #if DEBUG bncsutil_debug_message_a("\tChecksum = %lu", *checksum); #endif return 1; }
static int parse_config_file(void) { char line[LINE_SIZE]; char* bufline; char* linepos; char* variable; char* value; char* buf; size_t bufsize; size_t cur; size_t count; int lineno; int retval = 0; if (file_map(udev_config_filename, &buf, &bufsize) != 0) { err("can't open '%s' as config file: %s", udev_config_filename, strerror(errno)); return -ENODEV; } /* loop through the whole file */ lineno = 0; cur = 0; while (cur < bufsize) { count = buf_get_line(buf, bufsize, cur); bufline = &buf[cur]; cur += count + 1; lineno++; if (count >= sizeof(line)) { err("line too long, conf line skipped %s, line %d", udev_config_filename, lineno); continue; } /* eat the whitespace */ while ((count > 0) && isspace(bufline[0])) { bufline++; count--; } if (count == 0) { continue; } /* see if this is a comment */ if (bufline[0] == COMMENT_CHARACTER) { continue; } memcpy(line, bufline, count); line[count] = '\0'; linepos = line; retval = get_key(&linepos, &variable, &value); if (retval != 0) { err("error parsing %s, line %d:%d", udev_config_filename, lineno, (int)(linepos - line)); continue; } if (strcasecmp(variable, "udev_root") == 0) { strlcpy(udev_root, value, sizeof(udev_root)); remove_trailing_chars(udev_root, '/'); continue; } if (strcasecmp(variable, "udev_rules") == 0) { strlcpy(udev_rules_dir, value, sizeof(udev_rules_dir)); remove_trailing_chars(udev_rules_dir, '/'); continue; } if (strcasecmp(variable, "udev_log") == 0) { udev_log_priority = log_priority(value); continue; } } file_unmap(buf, bufsize); return retval; }
int cavan_font_load_bmp(struct cavan_font *font, const char *bmp, int lines) { int fd; int ret; size_t size; struct bmp_file_header *file_hdr; struct bmp_info_header *info_hdr; struct bmp_header *header; fd = file_mmap(bmp, (void **) &header, &size, 0); if (fd < 0) { pr_red_info("file_mmap"); return fd; } file_hdr = &header->file_hdr; info_hdr = &header->info_hdr; bmp_show_file_header(file_hdr); bmp_show_info_header(info_hdr); font->name = "BMP"; font->lines = lines; font->width = info_hdr->width; font->height = info_hdr->height; font->cwidth = font->width / 96; font->cheight = info_hdr->height / lines; font->rundata = NULL; font->rundata_size = 0; font->body = NULL; ret = cavan_font_init(font); if (ret < 0) { pr_red_info("cavan_font_init"); goto out_file_unmap; } switch (info_hdr->bit_count) { case 8: { const u8 *p, *file_end; byte *body = font->body + font->width * font->height; struct bmp_color_table_entry *colors = (struct bmp_color_table_entry *) (header + 1); p = ((u8 *) header) + file_hdr->offset; file_end = p + font->width * font->height; while (1) { const u8 *line_end = p + font->width; if (line_end > file_end) { break; } body -= font->width; while (p < line_end) { struct bmp_color_table_entry *color = colors + (*p); if (color->red > 128 && color->green > 128 && color->blue > 128) { *body = 0xFF; } else { *body = 0; } p++; body++; } body -= font->width; } } break; case 16: { const u16 *p, *file_end; byte *body = font->body + font->width * font->height; p = (u16 *) (((byte *) header) + file_hdr->offset); file_end = p + font->width * font->height; while (1) { const u16 *line_end = p + font->width; if (line_end > file_end) { break; } body -= font->width; while (p < line_end) { if (*p) { *body = 0xFF; } else { *body = 0; } p++; body++; } body -= font->width; } } break; case 24: { const u8 *p, *file_end; byte *body = font->body + font->width * font->height; p = (u8 *) (((byte *) header) + file_hdr->offset); file_end = p + font->width * font->height * 3; while (1) { const u8 *line_end = p + font->width * 3; if (line_end > file_end) { break; } body -= font->width; while (p < line_end) { int brightness; brightness = cavan_display_cal_brightness(p[0], p[1], p[2]); if (brightness > 64) { *body = 0xFF; } else { *body = 0; } p += 3; body++; } body -= font->width; } } break; case 32: { const u8 *p, *file_end; byte *body = font->body + font->width * font->height; p = (u8 *) (((byte *) header) + file_hdr->offset); file_end = p + font->width * font->height * 4; while (1) { const u8 *line_end = p + font->width * 4; if (line_end > file_end) { break; } body -= font->width; while (p < line_end) { if (p[0] > 128 && p[1] > 128 && p[2] > 128) { *body = 0xFF; } else { *body = 0; } p += 4; body++; } body -= font->width; } } break; default: ret = -EINVAL; pr_red_info("unknown bit_count = %d", info_hdr->bit_count); goto out_cavan_font_deinit; } file_unmap(fd, header, size); return 0; out_cavan_font_deinit: cavan_font_deinit(font); out_file_unmap: file_unmap(fd, header, size); return ret; }
int udev_db_lookup_name(const char *name, char *devpath, size_t len) { char dbpath[PATH_MAX]; DIR *dir; int found = 0; strlcpy(dbpath, udev_root, sizeof(dbpath)); strlcat(dbpath, "/"DB_DIR, sizeof(dbpath)); dir = opendir(dbpath); if (dir == NULL) { info("no udev_db available '%s': %s", dbpath, strerror(errno)); return -1; } while (!found) { struct dirent *ent; char filename[PATH_SIZE]; char nodename[PATH_SIZE]; struct stat stats; char *bufline; char *buf; size_t bufsize; size_t cur; size_t count; ent = readdir(dir); if (ent == NULL || ent->d_name[0] == '\0') break; if (ent->d_name[0] == '.') continue; snprintf(filename, sizeof(filename), "%s/%s", dbpath, ent->d_name); filename[sizeof(filename)-1] = '\0'; dbg("looking at '%s'", filename); if (lstat(filename, &stats) != 0) { info("unable to read %s: %s", filename, strerror(errno)); continue; } if ((stats.st_mode & S_IFMT) == S_IFLNK) { char target[NAME_SIZE]; int target_len; info("found a symlink as db file"); target_len = readlink(filename, target, sizeof(target)); if (target_len > 0) target[target_len] = '\0'; else { info("error reading db link %s: %s", filename, strerror(errno)); return -1; } dbg("db link points to '%s'", target); if (strcmp(name, target) == 0) { db_file_to_devpath(ent->d_name, devpath, len); found =1; } continue; } if (file_map(filename, &buf, &bufsize) != 0) { info("unable to read db file '%s': %s", filename, strerror(errno)); continue; } cur = 0; while (cur < bufsize && !found) { count = buf_get_line(buf, bufsize, cur); bufline = &buf[cur]; cur += count+1; switch(bufline[0]) { case 'N': case 'S': if (count > sizeof(nodename)) count = sizeof(nodename); memcpy(nodename, &bufline[2], count-2); nodename[count-2] = '\0'; dbg("compare '%s' '%s'", nodename, name); if (strcmp(nodename, name) == 0) { db_file_to_devpath(ent->d_name, devpath, len); found = 1; } break; default: continue; } } file_unmap(buf, bufsize); } closedir(dir); if (found) return 0; else return -1; }
int udev_db_get_device(struct udevice *udev, const char *devpath) { struct stat stats; char filename[PATH_SIZE]; char line[PATH_SIZE]; unsigned int maj, min; char *bufline; char *buf; size_t bufsize; size_t cur; size_t count; strlcpy(udev->dev->devpath, devpath, sizeof(udev->dev->devpath)); devpath_to_db_path(devpath, filename, sizeof(filename)); if (lstat(filename, &stats) != 0) { info("no db file to read %s: %s", filename, strerror(errno)); return -1; } if ((stats.st_mode & S_IFMT) == S_IFLNK) { char target[NAME_SIZE]; int target_len; info("found a symlink as db file"); target_len = readlink(filename, target, sizeof(target)); if (target_len > 0) target[target_len] = '\0'; else { info("error reading db link %s: %s", filename, strerror(errno)); return -1; } dbg("db link points to '%s'", target); strlcpy(udev->name, target, sizeof(udev->name)); return 0; } if (file_map(filename, &buf, &bufsize) != 0) { info("error reading db file %s: %s", filename, strerror(errno)); return -1; } cur = 0; while (cur < bufsize) { count = buf_get_line(buf, bufsize, cur); bufline = &buf[cur]; cur += count+1; switch(bufline[0]) { case 'N': if (count > sizeof(udev->name)) count = sizeof(udev->name); memcpy(udev->name, &bufline[2], count-2); udev->name[count-2] = '\0'; break; case 'M': if (count > sizeof(line)) count = sizeof(line); memcpy(line, &bufline[2], count-2); line[count-2] = '\0'; sscanf(line, "%u:%u", &maj, &min); udev->devt = makedev(maj, min); break; case 'S': if (count > sizeof(line)) count = sizeof(line); memcpy(line, &bufline[2], count-2); line[count-2] = '\0'; name_list_add(&udev->symlink_list, line, 0); break; case 'A': if (count > sizeof(line)) count = sizeof(line); memcpy(line, &bufline[2], count-2); line[count-2] = '\0'; udev->partitions = atoi(line); break; case 'R': if (count > sizeof(line)) count = sizeof(line); memcpy(line, &bufline[2], count-2); line[count-2] = '\0'; udev->ignore_remove = atoi(line); break; case 'E': if (count > sizeof(line)) count = sizeof(line); memcpy(line, &bufline[2], count-2); line[count-2] = '\0'; name_list_add(&udev->env_list, line, 0); break; } } file_unmap(buf, bufsize); if (udev->name[0] == '\0') return -1; return 0; }
int cavan_font_save_bmp(struct cavan_font *font, const char *pathname, int bit_count) { int fd; int ret; size_t size; size_t color_table_size; struct bmp_header *header; color_table_size = bmp_get_color_table_size(bit_count); size = sizeof(*header) + font->width * font->height * bit_count / 8; size += color_table_size * sizeof(struct bmp_color_table_entry); fd = file_mmap(pathname, (void **) &header, &size, O_RDWR | O_CREAT | O_TRUNC); if (fd < 0) { pr_red_info("file_mmap"); return fd; } bmp_header_init(header, font->width, font->height, bit_count); switch (bit_count) { case 8: { u8 *pixel; const byte *body; struct bmp_color_table_entry *colors = (struct bmp_color_table_entry *) (header + 1); colors[0].red = colors[0].green = colors[0].blue = 0x00; colors[1].red = colors[1].green = colors[1].blue = 0xFF; colors[0].reserved = colors[1].reserved = 0x00; pixel = (u8 *) (colors + color_table_size); for (body = font->body + font->width * (font->height - 1); body >= font->body; body -= font->width * 2) { const byte *body_end; for (body_end = body + font->width; body < body_end; body++, pixel++) { *pixel = (*body) == 0 ? 0 : 1; } } } break; case 16: { u16 *pixel = (u16 *) (header + 1); const byte *body; for (body = font->body + font->width * (font->height - 1); body >= font->body; body -= font->width * 2) { const byte *body_end; for (body_end = body + font->width; body < body_end; body++, pixel++) { *pixel = (*body) == 0 ? 0x0000 : 0xFFFF; } } } break; case 24: { byte *pixel = (byte *) (header + 1); const byte *body; for (body = font->body + font->width * (font->height - 1); body >= font->body; body -= font->width * 2) { const byte *body_end; for (body_end = body + font->width; body < body_end; body++, pixel += 3) { pixel[0] = pixel[1] = pixel[2] = (*body) == 0 ? 0x00 : 0xFF; } } } break; case 32: { u32 *pixel = (u32 *) (header + 1); const byte *body; for (body = font->body + font->width * (font->height - 1); body >= font->body; body -= font->width * 2) { const byte *body_end; for (body_end = body + font->width; body < body_end; body++, pixel++) { *pixel = (*body) == 0 ? 0x00000000 : 0xFFFFFFFF; } } } break; default: pr_red_info("unknown bit_count = %d", bit_count); ret = -EINVAL; goto out_file_unmap; } ret = 0; out_file_unmap: file_unmap(fd, header, size); return ret; }
/* parse the supplied dependency file */ static void parse_dep_file(void *dmap, size_t len){ char *m = dmap, *end = m + len, *tgt, *prereq; int fd; unsigned int size; unsigned int confh_len = strlen(conf_header); char *fmap; /* clear hash table */ hashtbl_clear(); /* find target */ while(m < end && (*m == ' ' || *m == '\\' || *m == '\n')) m++; tgt = m; while(m < end && *m != ':') m++; if(m < end) *m = 0; m++; /* print target */ printf("%s:", tgt); /* handle prerequisites */ while(m < end){ // find next prerequisites while(m < end && (*m == ' ' || *m == '\\' || *m == '\n')) m++; prereq = m; while(m < end && *m != ' ' && *m != '\n' && *m != '\\') m++; // break if prerequisite is actually a target if(m > 0 && m[-1] == ':'){ *m = 0; m++; printf("\n\n%s", prereq); break; } if(m < end) *m = 0; if(m >= end || tgt >= end || prereq >= end) break; // parse prerequisite that are not the conf_header if(strrcmp(prereq, m - prereq, conf_header, confh_len)){ printf(" \\\n %s", prereq); if(file_map(prereq, &fd, (void*)&fmap, &size) != 0) return; parse_prereq(fmap, size); file_unmap(fd, fmap, size); } m++; } /* print the remainder of the dependency file, * i.e. remaining targets */ printf("\n%s", m); }