diff --git a/tools/retrolaunch/cd_detect.c b/tools/retrolaunch/cd_detect.c index f6c407a66d..490e9f2a81 100644 --- a/tools/retrolaunch/cd_detect.c +++ b/tools/retrolaunch/cd_detect.c @@ -15,7 +15,8 @@ #define MAGIC_LEN 16 -struct MagicEntry { +struct MagicEntry +{ const char* system_name; const char* magic; }; @@ -28,294 +29,322 @@ static struct MagicEntry MAGIC_NUMBERS[] = { }; static int find_first_data_track(const char* cue_path, int32_t* offset, - char* track_path, size_t max_len) { - int rv; - int fd = -1; - char tmp_token[MAX_TOKEN_LEN]; - int m, s, f; - char cue_dir[PATH_MAX]; - strlcpy(cue_dir, cue_path, PATH_MAX); - path_basedir(cue_dir); + char* track_path, size_t max_len) +{ + int rv; + int fd = -1; + char tmp_token[MAX_TOKEN_LEN]; + int m, s, f; + char cue_dir[PATH_MAX]; + strlcpy(cue_dir, cue_path, PATH_MAX); + path_basedir(cue_dir); - fd = open(cue_path, O_RDONLY); - if (fd < 0) { - LOG_WARN("Could not open CUE file '%s': %s", cue_path, - strerror(errno)); - return -errno; - } + fd = open(cue_path, O_RDONLY); + if (fd < 0) + { + LOG_WARN("Could not open CUE file '%s': %s", cue_path, + strerror(errno)); + return -errno; + } - LOG_DEBUG("Parsing CUE file '%s'...", cue_path); + LOG_DEBUG("Parsing CUE file '%s'...", cue_path); - while (get_token(fd, tmp_token, MAX_TOKEN_LEN) > 0) { - if (strcmp(tmp_token, "FILE") == 0) { - get_token(fd, tmp_token, MAX_TOKEN_LEN); - fill_pathname_join(track_path, cue_dir, tmp_token, max_len); + while (get_token(fd, tmp_token, MAX_TOKEN_LEN) > 0) + { + if (strcmp(tmp_token, "FILE") == 0) + { + get_token(fd, tmp_token, MAX_TOKEN_LEN); + fill_pathname_join(track_path, cue_dir, tmp_token, max_len); - } else if (strcasecmp(tmp_token, "TRACK") == 0) { - get_token(fd, tmp_token, MAX_TOKEN_LEN); - get_token(fd, tmp_token, MAX_TOKEN_LEN); - if (strcasecmp(tmp_token, "AUDIO") == 0) { - continue; - } + } + else if (strcasecmp(tmp_token, "TRACK") == 0) + { + get_token(fd, tmp_token, MAX_TOKEN_LEN); + get_token(fd, tmp_token, MAX_TOKEN_LEN); + if (strcasecmp(tmp_token, "AUDIO") == 0) + continue; - find_token(fd, "INDEX"); - get_token(fd, tmp_token, MAX_TOKEN_LEN); - get_token(fd, tmp_token, MAX_TOKEN_LEN); - if (sscanf(tmp_token, "%02d:%02d:%02d", &m, &s, &f) < 3) { - LOG_WARN("Error parsing time stamp '%s'", tmp_token); - return -errno; - } - *offset = ((m * 60) * (s * 75) * f) * 25; + find_token(fd, "INDEX"); + get_token(fd, tmp_token, MAX_TOKEN_LEN); + get_token(fd, tmp_token, MAX_TOKEN_LEN); + if (sscanf(tmp_token, "%02d:%02d:%02d", &m, &s, &f) < 3) + { + LOG_WARN("Error parsing time stamp '%s'", tmp_token); + return -errno; + } + *offset = ((m * 60) * (s * 75) * f) * 25; - LOG_DEBUG("Found 1st data track on file '%s+%d'", - track_path, *offset); + LOG_DEBUG("Found 1st data track on file '%s+%d'", + track_path, *offset); - rv = 0; - goto clean; - } - } + rv = 0; + goto clean; + } + } - rv = -EINVAL; + rv = -EINVAL; clean: - close(fd); - return rv; + close(fd); + return rv; } static int find_ps1_canonical_name(const char* game_id, char* game_name, - size_t max_len) { - int fd; - char tmp_token[MAX_TOKEN_LEN]; - int rv = 0; - fd = open("cddb/ps1.idlst", O_RDONLY); - if (fd < 0) { - LOG_WARN("Could not open id list: %s", strerror(errno)); - return -errno; - } + size_t max_len) +{ + char tmp_token[MAX_TOKEN_LEN]; + int rv = 0; + int fd = open("cddb/ps1.idlst", O_RDONLY); + if (fd < 0) + { + LOG_WARN("Could not open id list: %s", strerror(errno)); + return -errno; + } - while (get_token(fd, tmp_token, MAX_TOKEN_LEN) > 0) { - if(strcasecmp(tmp_token, game_id) != 0) { - get_token(fd, tmp_token, max_len); - continue; - } + while (get_token(fd, tmp_token, MAX_TOKEN_LEN) > 0) + { + if(strcasecmp(tmp_token, game_id) != 0) + { + get_token(fd, tmp_token, max_len); + continue; + } - if ((rv = get_token(fd, game_name, max_len)) < 0) { - goto clean; - } + if ((rv = get_token(fd, game_name, max_len)) < 0) + goto clean; - rv = 0; - goto clean; - } + rv = 0; + goto clean; + } - rv = -ENOENT; + rv = -ENOENT; clean: - close(fd); - return rv; + close(fd); + return rv; } static int detect_ps1_game(const char* track_path, int32_t offset, - char* game_name, size_t max_len) { - int rv; - char buff[4096]; - const char* pattern = "cdrom:"; - const char* pat_c; - char* c; - char* id_start; - int i; + char* game_name, size_t max_len) +{ + int rv; + char buff[4096]; + const char* pattern = "cdrom:"; + const char* pat_c; + char* c; + char* id_start; + int i; - int fd = open(track_path, O_RDONLY); - if (fd < 0) { - LOG_DEBUG("Could not open data track: %s", strerror(errno)); - return -errno; - } + int fd = open(track_path, O_RDONLY); + if (fd < 0) + { + LOG_DEBUG("Could not open data track: %s", strerror(errno)); + return -errno; + } - lseek(fd, 0x9340, SEEK_SET); - if (read(fd, buff, 10) > 0) { - buff[10] = '\0'; - buff[4] = '-'; - LOG_DEBUG("Found disk label '%s'", buff); - rv = find_ps1_canonical_name(buff, game_name, max_len); - if (rv == 0) { - goto clean; - } - } - memset(buff, 0, sizeof(buff)); - pat_c = pattern; - while (1) { - rv = read(fd, buff, 4096); - if (rv < 0) { - rv = -errno; - goto clean; - } + lseek(fd, 0x9340, SEEK_SET); + if (read(fd, buff, 10) > 0) + { + buff[10] = '\0'; + buff[4] = '-'; + LOG_DEBUG("Found disk label '%s'", buff); + rv = find_ps1_canonical_name(buff, game_name, max_len); + if (rv == 0) + goto clean; + } - for (i = 0; i < rv; i++) { - if (*pat_c == buff[i]) { - pat_c++; - } else { - pat_c = pattern; - continue; + memset(buff, 0, sizeof(buff)); + pat_c = pattern; + + while (1) + { + rv = read(fd, buff, 4096); + if (rv < 0) + { + rv = -errno; + goto clean; + } + + for (i = 0; i < rv; i++) + { + if (*pat_c == buff[i]) + pat_c++; + else + { + pat_c = pattern; + continue; + } + + if (*pat_c == '\0') + { + id_start = &buff[i] + 1; + c = strchr(id_start, ';'); + if (!c) + { + LOG_DEBUG("Invalid pattern in buffer."); + rv = -EINVAL; + goto clean; } - - if (*pat_c == '\0') { - id_start = &buff[i] + 1; - c = strchr(id_start, ';'); - if (!c) { - LOG_DEBUG("Invalid pattern in buffer."); - rv = -EINVAL; - goto clean; - } - *c = '\0'; - c = strrchr(id_start, '\\'); - if (c != NULL) { - id_start = c + 1; - } - id_start[4] = '-'; - id_start[8] = id_start[9]; - id_start[9] = id_start[10]; - id_start[10] = '\0'; - LOG_DEBUG("Found ps1 id %s", id_start); - rv = find_ps1_canonical_name(id_start, game_name, max_len); - goto clean; - } - } - } - rv = -EINVAL; + *c = '\0'; + c = strrchr(id_start, '\\'); + if (c != NULL) + id_start = c + 1; + id_start[4] = '-'; + id_start[8] = id_start[9]; + id_start[9] = id_start[10]; + id_start[10] = '\0'; + LOG_DEBUG("Found ps1 id %s", id_start); + rv = find_ps1_canonical_name(id_start, game_name, max_len); + goto clean; + } + } + } + rv = -EINVAL; clean: - close(fd); - return rv; + close(fd); + return rv; } static int detect_system(const char* track_path, int32_t offset, - const char** system_name) { - int rv; - char magic[MAGIC_LEN]; - int fd; - //struct MagicEntry entry; - int i; + const char** system_name) +{ + int rv; + char magic[MAGIC_LEN]; + int fd; + //struct MagicEntry entry; + int i; - fd = open(track_path, O_RDONLY); - if (fd < 0) { - LOG_WARN("Could not open data track of file '%s': %s", - track_path, strerror(errno)); - rv = -errno; - goto clean; - } + fd = open(track_path, O_RDONLY); + if (fd < 0) + { + LOG_WARN("Could not open data track of file '%s': %s", + track_path, strerror(errno)); + rv = -errno; + goto clean; + } - lseek(fd, offset, SEEK_SET); - if (read(fd, magic, MAGIC_LEN) < MAGIC_LEN) { - LOG_WARN("Could not read data from file '%s' at offset %d: %s", - track_path, offset, strerror(errno)); - rv = -errno; - goto clean; - } + lseek(fd, offset, SEEK_SET); + if (read(fd, magic, MAGIC_LEN) < MAGIC_LEN) + { + LOG_WARN("Could not read data from file '%s' at offset %d: %s", + track_path, offset, strerror(errno)); + rv = -errno; + goto clean; + } - LOG_DEBUG("Comparing with known magic numbers..."); - for (i = 0; MAGIC_NUMBERS[i].system_name != NULL; i++) { - if (memcmp(MAGIC_NUMBERS[i].magic, magic, MAGIC_LEN) == 0) { - *system_name = MAGIC_NUMBERS[i].system_name; - rv = 0; - goto clean; - } - } + LOG_DEBUG("Comparing with known magic numbers..."); + for (i = 0; MAGIC_NUMBERS[i].system_name != NULL; i++) + { + if (memcmp(MAGIC_NUMBERS[i].magic, magic, MAGIC_LEN) == 0) + { + *system_name = MAGIC_NUMBERS[i].system_name; + rv = 0; + goto clean; + } + } - LOG_WARN("Could not find compatible system"); - rv = -EINVAL; + LOG_WARN("Could not find compatible system"); + rv = -EINVAL; clean: - close(fd); - return rv; + close(fd); + return rv; } -int find_first_cue(const char* m3u_path, char* cue_path, size_t max_len) { - char c; - int skip = 0; - int midstream = 0; +int find_first_cue(const char* m3u_path, char* cue_path, size_t max_len) +{ + char c; + int skip = 0; + int midstream = 0; - int fd = open(m3u_path, O_RDONLY); - if (fd < 0) { - LOG_WARN("Could not open m3u '%s': %s", m3u_path, strerror(errno)); - return -errno; - } + int fd = open(m3u_path, O_RDONLY); + if (fd < 0) + { + LOG_WARN("Could not open m3u '%s': %s", m3u_path, strerror(errno)); + return -errno; + } - strncpy(cue_path, m3u_path, PATH_MAX); - path_basedir(cue_path); - cue_path += strlen(cue_path); - cue_path[0] = '/'; - cue_path++; + strncpy(cue_path, m3u_path, PATH_MAX); + path_basedir(cue_path); + cue_path += strlen(cue_path); + cue_path[0] = '/'; + cue_path++; - while ((read(fd, &c, 1) > 0)) { - switch (c) { - case '#': - if (!midstream) { - skip = 1; - } - break; - case '\n': - if (skip) { - skip = 0; - } else if(midstream) { - cue_path[0] = '\0'; - close(fd); - return 0; - } - break; - case ' ': - if (!midstream) { - break; - } - default: - if (!skip) { - midstream = 1; - cue_path[0] = c; - cue_path++; - } - } - } + while ((read(fd, &c, 1) > 0)) + { + switch (c) + { + case '#': + if (!midstream) + skip = 1; + break; + case '\n': + if (skip) + skip = 0; + else if(midstream) + { + cue_path[0] = '\0'; + close(fd); + return 0; + } + break; + case ' ': + if (!midstream) + break; + default: + if (!skip) + { + midstream = 1; + cue_path[0] = c; + cue_path++; + } + } + } - close(fd); - return -EINVAL; + close(fd); + return -EINVAL; } -int detect_cd_game(const char* target_path, char* game_name, size_t max_len) { - char cue_path[PATH_MAX]; - char track_path[PATH_MAX]; - int32_t offset = 0; - const char* system_name = NULL; - int rv; - if (strcasecmp(target_path + strlen(target_path) - 4, ".m3u") == 0) { - rv = find_first_cue(target_path, cue_path, PATH_MAX); - if (rv < 0) { - LOG_WARN("Could not parse m3u: %s", strerror(-rv)); - return rv; - } +int detect_cd_game(const char* target_path, char* game_name, size_t max_len) +{ + char cue_path[PATH_MAX]; + char track_path[PATH_MAX]; + int32_t offset = 0; + const char* system_name = NULL; + int rv; + if (strcasecmp(target_path + strlen(target_path) - 4, ".m3u") == 0) + { + rv = find_first_cue(target_path, cue_path, PATH_MAX); + if (rv < 0) + { + LOG_WARN("Could not parse m3u: %s", strerror(-rv)); + return rv; + } - } else { - strncpy(cue_path, target_path, max_len); - } + } + else + strncpy(cue_path, target_path, max_len); - rv = find_first_data_track(cue_path, &offset, track_path, PATH_MAX); - if (rv < 0) { - LOG_WARN("Could not find valid data track: %s", strerror(-rv)); - return rv; - } + rv = find_first_data_track(cue_path, &offset, track_path, PATH_MAX); + if (rv < 0) + { + LOG_WARN("Could not find valid data track: %s", strerror(-rv)); + return rv; + } - LOG_DEBUG("Reading 1st data track..."); + LOG_DEBUG("Reading 1st data track..."); - if ((rv = detect_system(track_path, offset, &system_name)) < 0) { - return rv; - } + if ((rv = detect_system(track_path, offset, &system_name)) < 0) + return rv; + LOG_DEBUG("Detected %s media", system_name); - LOG_DEBUG("Detected %s media", system_name); + snprintf(game_name, max_len, "%s.", system_name); + game_name += strlen(system_name) + 1; + max_len -= strlen(system_name) + 1; + if (strcmp(system_name, "ps1") == 0) + { + if (detect_ps1_game(track_path, offset, game_name, max_len) == 0) + return 0; + } - snprintf(game_name, max_len, "%s.", system_name); - game_name += strlen(system_name) + 1; - max_len -= strlen(system_name) + 1; - if (strcmp(system_name, "ps1") == 0) { - if (detect_ps1_game(track_path, offset, game_name, max_len) == 0) { - return 0; - } - } - - snprintf(game_name, max_len, ""); - return 0; + snprintf(game_name, max_len, ""); + return 0; } diff --git a/tools/retrolaunch/main.c b/tools/retrolaunch/main.c index 12ef76166f..76cea124db 100644 --- a/tools/retrolaunch/main.c +++ b/tools/retrolaunch/main.c @@ -26,124 +26,117 @@ static int find_hash(int fd, const char *hash, char *game_name, size_t max_len) { char token[MAX_TOKEN_LEN] = {0}; - while (1) { - if (find_token(fd, "game") < 0) { - return -1; - } + while (1) + { + if (find_token(fd, "game") < 0) + return -1; - if (find_token(fd, "name") < 0) { - return -1; - } + if (find_token(fd, "name") < 0) + return -1; - if (get_token(fd, game_name, max_len) < 0) { - return -1; - } + if (get_token(fd, game_name, max_len) < 0) + return -1; - if (find_token(fd, "sha1") < 0) { - return -1; - } + if (find_token(fd, "sha1") < 0) + return -1; - if (get_token(fd, token, MAX_TOKEN_LEN) < 0) { - return -1; - } + if (get_token(fd, token, MAX_TOKEN_LEN) < 0) + return -1; - if (strcasecmp(hash, token) == 0) { - return 0; - } - } + if (strcasecmp(hash, token) == 0) + return 0; + } } static int find_rom_canonical_name(const char *hash, char *game_name, size_t max_len) { - // TODO: Error handling - size_t i; - int rv; - int fd; - int offs; - char *dat_path; - const char *dat_name; - const char *dat_name_dot; - struct string_list *files; + // TODO: Error handling + size_t i; + int rv, fd, offs; + char *dat_path; + const char *dat_name, *dat_name_dot; + struct string_list *files = dir_list_new("db", "dat", false); - files = dir_list_new("db", "dat", false); - if (!files) { - return -1; - } + if (!files) + return -1; - for (i = 0; i < files->size; i++) { - dat_path = files->elems[i].data; - dat_name = path_basename(dat_path); + for (i = 0; i < files->size; i++) + { + dat_path = files->elems[i].data; + dat_name = path_basename(dat_path); - dat_name_dot = strchr(dat_name, '.'); - if (!dat_name_dot) { - continue; - } + dat_name_dot = strchr(dat_name, '.'); + if (!dat_name_dot) + continue; - offs = dat_name_dot - dat_name + 1; - memcpy(game_name, dat_name, offs); + offs = dat_name_dot - dat_name + 1; + memcpy(game_name, dat_name, offs); - fd = open(dat_path, O_RDONLY); - if (fd < 0) { - continue; - } + fd = open(dat_path, O_RDONLY); + if (fd < 0) + continue; - if (find_hash(fd, hash, game_name + offs, max_len - offs) == 0) { - rv = 0; - close(fd); - goto clean; - } - close(fd); - } - rv = -1; + if (find_hash(fd, hash, game_name + offs, max_len - offs) == 0) + { + rv = 0; + close(fd); + goto clean; + } + close(fd); + } + rv = -1; clean: - dir_list_free(files); - return rv; + dir_list_free(files); + return rv; } static int get_sha1(const char *path, char *result) { - int fd; - int rv; - unsigned char buff[4096]; - SHA1Context sha; + int fd; + int rv; + unsigned char buff[4096]; + SHA1Context sha; - fd = open(path, O_RDONLY); - if (fd < 0) { - return -errno; - } + fd = open(path, O_RDONLY); + if (fd < 0) + return -errno; - SHA1Reset(&sha); - rv = 1; - while (rv > 0) { - rv = read(fd, buff, 4096); - if (rv < 0) { - close(fd); - return -errno; - } + SHA1Reset(&sha); + rv = 1; + while (rv > 0) + { + rv = read(fd, buff, 4096); + if (rv < 0) + { + close(fd); + return -errno; + } - SHA1Input(&sha, buff, rv); - } + SHA1Input(&sha, buff, rv); + } - if (!SHA1Result(&sha)) { - close(fd); - return -1; - } + if (!SHA1Result(&sha)) + { + close(fd); + return -1; + } - sprintf(result, "%08X%08X%08X%08X%08X", - sha.Message_Digest[0], - sha.Message_Digest[1], - sha.Message_Digest[2], - sha.Message_Digest[3], sha.Message_Digest[4]); - close(fd); - return 0; + sprintf(result, "%08X%08X%08X%08X%08X", + sha.Message_Digest[0], + sha.Message_Digest[1], + sha.Message_Digest[2], + sha.Message_Digest[3], sha.Message_Digest[4]); + close(fd); + return 0; } -struct RunInfo { - char broken_cores[PATH_MAX]; - int multitap; - int dualanalog; - char system[10]; +struct RunInfo +{ + char broken_cores[PATH_MAX]; + int multitap; + int dualanalog; + char system[10]; }; static int read_launch_conf(struct RunInfo *info, const char *game_name) @@ -152,19 +145,18 @@ static int read_launch_conf(struct RunInfo *info, const char *game_name) int rv; int bci = 0; char token[MAX_TOKEN_LEN]; - if (fd < 0) { + if (fd < 0) return -errno; - } - while (1) { - if ((rv = get_token(fd, token, MAX_TOKEN_LEN)) < 0) { + while (1) + { + if ((rv = get_token(fd, token, MAX_TOKEN_LEN)) < 0) goto clean; - } - if (rl_fnmatch(token, game_name, 0) != 0) { - if ((rv = find_token(fd, ";")) < 0) { + if (rl_fnmatch(token, game_name, 0) != 0) + { + if ((rv = find_token(fd, ";")) < 0) goto clean; - } continue; } @@ -172,47 +164,48 @@ static int read_launch_conf(struct RunInfo *info, const char *game_name) break; } - if ((rv = get_token(fd, token, MAX_TOKEN_LEN)) < 0) { + if ((rv = get_token(fd, token, MAX_TOKEN_LEN)) < 0) goto clean; - } - while (strcmp(token, ";") != 0) { - if (strcmp(token, "multitap") == 0) { - info->multitap = 1; - } else if (strcmp(token, "dualanalog") == 0) { - info->dualanalog = 1; - } else if (token[0] == '!') { - strncpy(&info->broken_cores[bci], &token[1], PATH_MAX - bci); - bci += strnlen(&token[1], PATH_MAX) + 1; - } + while (strcmp(token, ";") != 0) + { + if (strcmp(token, "multitap") == 0) + info->multitap = 1; + else if (strcmp(token, "dualanalog") == 0) + info->dualanalog = 1; + else if (token[0] == '!') + { + strncpy(&info->broken_cores[bci], &token[1], PATH_MAX - bci); + bci += strnlen(&token[1], PATH_MAX) + 1; + } - if ((rv = get_token(fd, token, MAX_TOKEN_LEN)) < 0) { - goto clean; - } - - } + if ((rv = get_token(fd, token, MAX_TOKEN_LEN)) < 0) + goto clean; + } rv = 0; clean: close(fd); return rv; } -static int get_run_info(struct RunInfo *info, const char *game_name) { - memset(info, 0, sizeof(struct RunInfo)); - int i; +static int get_run_info(struct RunInfo *info, const char *game_name) +{ + int i; - for (i = 0; i < 9; i++) { - if (game_name[i] == '.') { - break; - } - info->system[i] = game_name[i]; - } - info->system[i] = '\0'; - info->multitap = 0; - info->dualanalog = 0; + memset(info, 0, sizeof(struct RunInfo)); - read_launch_conf(info, game_name); - return 0; + for (i = 0; i < 9; i++) + { + if (game_name[i] == '.') + break; + info->system[i] = game_name[i]; + } + info->system[i] = '\0'; + info->multitap = 0; + info->dualanalog = 0; + + read_launch_conf(info, game_name); + return 0; } @@ -240,32 +233,34 @@ static int detect_rom_game(const char *path, char *game_name, size_t max_len) { char hash[HASH_LEN + 1]; int rv; - const char *suffix; const char **tmp_suffix; - suffix = strrchr(path, '.'); - if (!suffix) { + const char *suffix = strrchr(path, '.'); + if (!suffix) + { LOG_WARN("Could not find extension for: %s", path); return -EINVAL; } memset(hash, 0, sizeof(hash)); - if ((rv = get_sha1(path, hash)) < 0) { + if ((rv = get_sha1(path, hash)) < 0) LOG_WARN("Could not calculate hash: %s", strerror(-rv)); - } - if (find_rom_canonical_name(hash, game_name, max_len) < 0) { + if (find_rom_canonical_name(hash, game_name, max_len) < 0) + { LOG_DEBUG("Could not detect rom with hash `%s` guessing", hash); for (tmp_suffix = SUFFIX_MATCH; *tmp_suffix != NULL; - tmp_suffix += 2) { - if (strcasecmp(suffix, *tmp_suffix) == 0) { - snprintf(game_name, max_len, "%s.", - *(tmp_suffix + 1)); - return 0; - } - } + tmp_suffix += 2) + { + if (strcasecmp(suffix, *tmp_suffix) == 0) + { + snprintf(game_name, max_len, "%s.", + *(tmp_suffix + 1)); + return 0; + } + } return -EINVAL; } @@ -275,81 +270,83 @@ static int detect_rom_game(const char *path, char *game_name, size_t max_len) static int detect_game(const char *path, char *game_name, size_t max_len) { if ((strcasecmp(path + strlen(path) - 4, ".cue") == 0) || - (strcasecmp(path + strlen(path) - 4, ".m3u") == 0)) { + (strcasecmp(path + strlen(path) - 4, ".m3u") == 0)) + { LOG_INFO("Starting CD game detection..."); return detect_cd_game(path, game_name, max_len); - } else { + } + else + { LOG_INFO("Starting rom game detection..."); return detect_rom_game(path, game_name, max_len); } } static int select_core(char *core_path, size_t max_len, - const struct RunInfo *info) { - int fd = open("./cores.conf", O_RDONLY); - int rv; - int bci = 0; - char token[MAX_TOKEN_LEN]; - int broken = 0; - if (fd < 0) { - return -errno; - } + const struct RunInfo *info) +{ + int fd = open("./cores.conf", O_RDONLY); + int rv; + int bci = 0; + char token[MAX_TOKEN_LEN]; + int broken = 0; + if (fd < 0) + return -errno; - LOG_INFO("Selecting core for system '%s'", info->system); - while (1) { - if ((rv = get_token(fd, token, MAX_TOKEN_LEN)) < 0) { - goto clean; - } + LOG_INFO("Selecting core for system '%s'", info->system); + while (1) + { + if ((rv = get_token(fd, token, MAX_TOKEN_LEN)) < 0) + goto clean; - if (rl_fnmatch(token, info->system, 0) != 0) { - if ((rv = find_token(fd, ";")) < 0) { - goto clean; - } - continue; - } + if (rl_fnmatch(token, info->system, 0) != 0) + { + if ((rv = find_token(fd, ";")) < 0) + goto clean; + continue; + } - LOG_INFO("Matched system '%s'", token); + LOG_INFO("Matched system '%s'", token); - break; - } + break; + } - if ((rv = get_token(fd, token, MAX_TOKEN_LEN)) < 0) { - goto clean; - } + if ((rv = get_token(fd, token, MAX_TOKEN_LEN)) < 0) + goto clean; - while (strcmp(token, ";") != 0) { - broken = 0; - for (bci = 0; info->broken_cores[bci] != '\0'; - bci += strlen(&info->broken_cores[bci]) + 1) { + while (strcmp(token, ";") != 0) + { + broken = 0; + for (bci = 0; info->broken_cores[bci] != '\0'; + bci += strlen(&info->broken_cores[bci]) + 1) + { - LOG_DEBUG("%s, %s", &info->broken_cores[bci], token); - if (strcmp(&info->broken_cores[bci], token) == 0) { - broken = 1; - LOG_DEBUG("Not using core %s because it is " - "marked broken for this game", - &info->broken_cores[bci]); - break; - } - } + LOG_DEBUG("%s, %s", &info->broken_cores[bci], token); + if (strcmp(&info->broken_cores[bci], token) == 0) + { + broken = 1; + LOG_DEBUG("Not using core %s because it is " + "marked broken for this game", + &info->broken_cores[bci]); + break; + } + } - if (!broken) { - goto success; - } + if (!broken) + goto success; - if ((rv = get_token(fd, token, MAX_TOKEN_LEN)) < 0) { - goto clean; - } - - } - rv = -EINVAL; - goto clean; + if ((rv = get_token(fd, token, MAX_TOKEN_LEN)) < 0) + goto clean; + } + rv = -EINVAL; + goto clean; success: - snprintf(core_path, max_len, "./cores/%s.so", token); - rv = 0; + snprintf(core_path, max_len, "./cores/%s.so", token); + rv = 0; clean: - close(fd); - return rv; + close(fd); + return rv; } #ifndef RARCH_CONSOLE @@ -363,20 +360,24 @@ static int run_retroarch(const char *path, const struct RunInfo *info) }; int argi = 3; - if ((rv = select_core(core_path, PATH_MAX, info)) < 0) { + if ((rv = select_core(core_path, PATH_MAX, info)) < 0) + { LOG_WARN("Could not find suitable core"); return rv; } LOG_INFO("Using core at '%s'", core_path); - if (info->multitap) { + if (info->multitap) + { retro_argv[argi] = "-4"; argi++; LOG_INFO("Game supports multitap"); } - if (info->dualanalog) { - for (i = 0; i < 8; i++) { + if (info->dualanalog) + { + for (i = 0; i < 8; i++) + { retro_argv[argi] = "-A"; argi++; retro_argv[argi] = "1"; @@ -394,33 +395,36 @@ static int run_retroarch(const char *path, const struct RunInfo *info) int main(int argc, char *argv[]) { - if (argc < 2) { - printf("usage: retrolaunch \n"); - return -1; - } + if (argc < 2) + { + printf("usage: retrolaunch \n"); + return -1; + } - char game_name[MAX_TOKEN_LEN]; - char *path = argv[1]; - struct RunInfo info; - int rv; + char game_name[MAX_TOKEN_LEN]; + char *path = argv[1]; + struct RunInfo info; + int rv; - LOG_INFO("Analyzing '%s'", path); - if ((rv = detect_game(path, game_name, MAX_TOKEN_LEN)) < 0) { - LOG_WARN("Could not detect game: %s", strerror(-rv)); - return -rv; - } + LOG_INFO("Analyzing '%s'", path); + if ((rv = detect_game(path, game_name, MAX_TOKEN_LEN)) < 0) + { + LOG_WARN("Could not detect game: %s", strerror(-rv)); + return -rv; + } - LOG_INFO("Game is `%s`", game_name); - if ((rv = get_run_info(&info, game_name)) < 0) { - LOG_WARN("Could not detect run info: %s", strerror(-rv)); - return -1; - } + LOG_INFO("Game is `%s`", game_name); + if ((rv = get_run_info(&info, game_name)) < 0) + { + LOG_WARN("Could not detect run info: %s", strerror(-rv)); + return -1; + } - LOG_INFO("Launching '%s'", path); + LOG_INFO("Launching '%s'", path); - rv = run_retroarch(path, &info); - LOG_WARN("Could not launch retroarch: %s", strerror(-rv)); - return -rv; + rv = run_retroarch(path, &info); + LOG_WARN("Could not launch retroarch: %s", strerror(-rv)); + return -rv; } // Stub just so that it compiles diff --git a/tools/retrolaunch/parser.c b/tools/retrolaunch/parser.c index cf4ed90ac7..ed494a45bc 100644 --- a/tools/retrolaunch/parser.c +++ b/tools/retrolaunch/parser.c @@ -6,70 +6,75 @@ ssize_t get_token(int fd, char *token, size_t max_len) { - char *c = token; - int rv; - ssize_t len = 0; - int in_string = 0; + char *c = token; + int rv; + ssize_t len = 0; + int in_string = 0; - while (1) { - rv = read(fd, c, 1); - if (rv == 0) { - return 0; - } else if (rv < 1) { - switch (errno) { - case EINTR: - case EAGAIN: - continue; - default: - return -errno; - } - } + while (1) + { + rv = read(fd, c, 1); + if (rv == 0) + return 0; + else if (rv < 1) + { + switch (errno) + { + case EINTR: + case EAGAIN: + continue; + default: + return -errno; + } + } - switch (*c) { - case ' ': - case '\t': - case '\r': - case '\n': - if (c == token) { - continue; - } + switch (*c) + { + case ' ': + case '\t': + case '\r': + case '\n': + if (c == token) + continue; - if (!in_string) { - *c = '\0'; - return len; - } - break; - case '\"': - if (c == token) { - in_string = 1; - continue; - } + if (!in_string) + { + *c = '\0'; + return len; + } + break; + case '\"': + if (c == token) + { + in_string = 1; + continue; + } - *c = '\0'; - return len; - } + *c = '\0'; + return len; + } - len++; - c++; - if (len == (ssize_t)max_len) { - *c = '\0'; - return len; - } - } + len++; + c++; + if (len == (ssize_t)max_len) + { + *c = '\0'; + return len; + } + } } int find_token(int fd, const char *token) { - int tmp_len = strlen(token); - char *tmp_token = (char*)calloc(tmp_len, 1); - if (!tmp_token) { - return -1; - } - while (strncmp(tmp_token, token, tmp_len) != 0) { - if (get_token(fd, tmp_token, tmp_len) <= 0) { - return -1; - } - } + int tmp_len = strlen(token); + char *tmp_token = (char*)calloc(tmp_len, 1); + if (!tmp_token) + return -1; + while (strncmp(tmp_token, token, tmp_len) != 0) + { + if (get_token(fd, tmp_token, tmp_len) <= 0) + return -1; + } - return 0; + return 0; } diff --git a/tools/retrolaunch/rl_fnmatch.c b/tools/retrolaunch/rl_fnmatch.c index f538fef1ba..81430dcef0 100644 --- a/tools/retrolaunch/rl_fnmatch.c +++ b/tools/retrolaunch/rl_fnmatch.c @@ -6,127 +6,121 @@ // Implemnentation of fnmatch(3) so it can be distributed to non *nix platforms // No flags are implemented ATM. We don't use them. Add flags as needed. -int rl_fnmatch(const char *pattern, const char *string, int flags) { - const char *c; - int charmatch = 0; - int rv; - for (c = pattern; *c != '\0'; c++) { - // String ended before pattern - if ((*c != '*') && (*string == '\0')) { - return FNM_NOMATCH; - } +int rl_fnmatch(const char *pattern, const char *string, int flags) +{ + const char *c; + int charmatch = 0; + int rv; + for (c = pattern; *c != '\0'; c++) + { + // String ended before pattern + if ((*c != '*') && (*string == '\0')) + return FNM_NOMATCH; - switch (*c) { - // Match any number of unknown chars - case '*': - // Find next node in the pattern ignoring multiple - // asterixes - do { - c++; - if (*c == '\0') { - return 0; - } - } while (*c == '*'); + switch (*c) + { + // Match any number of unknown chars + case '*': + // Find next node in the pattern ignoring multiple + // asterixes + do { + c++; + if (*c == '\0') + return 0; + } while (*c == '*'); - // Match the remaining pattern ingnoring more and more - // chars. - do { - // We reached the end of the string without a - // match. There is a way to optimize this by - // calculating the minimum chars needed to - // match the remaining pattern but I don't - // think it is worth the work ATM. - if (*string == '\0') { - return FNM_NOMATCH; - } + // Match the remaining pattern ingnoring more and more + // chars. + do { + // We reached the end of the string without a + // match. There is a way to optimize this by + // calculating the minimum chars needed to + // match the remaining pattern but I don't + // think it is worth the work ATM. + if (*string == '\0') + return FNM_NOMATCH; - rv = rl_fnmatch(c, string, flags); - string++; - } while (rv != 0); + rv = rl_fnmatch(c, string, flags); + string++; + } while (rv != 0); - return 0; - // Match char from list - case '[': - charmatch = 0; - for (c++; *c != ']'; c++) { - // Bad formath - if (*c == '\0') { - return FNM_NOMATCH; - } + return 0; + // Match char from list + case '[': + charmatch = 0; + for (c++; *c != ']'; c++) + { + // Bad formath + if (*c == '\0') + return FNM_NOMATCH; - // Match already found - if (charmatch) { - continue; - } + // Match already found + if (charmatch) + continue; - if (*c == *string) { - charmatch = 1; - } - } + if (*c == *string) + charmatch = 1; + } - // No match in list - if (!charmatch) { - return FNM_NOMATCH; - } + // No match in list + if (!charmatch) + return FNM_NOMATCH; - string++; - break; - // Has any char - case '?': - string++; - break; - // Match following char verbatim - case '\\': - c++; - // Dangling escape at end of pattern - if (*c == '\0') { // FIXME: Was c == '\0' (makes no sense). Not sure if c == NULL or *c == '\0' is intended. Assuming *c due to c++ right before. - return FNM_NOMATCH; - } - default: - if (*c != *string) { - return FNM_NOMATCH; - } - string++; - } - } + string++; + break; + // Has any char + case '?': + string++; + break; + // Match following char verbatim + case '\\': + c++; + // Dangling escape at end of pattern + if (*c == '\0') // FIXME: Was c == '\0' (makes no sense). Not sure if c == NULL or *c == '\0' is intended. Assuming *c due to c++ right before. + return FNM_NOMATCH; + default: + if (*c != *string) + return FNM_NOMATCH; + string++; + } + } - // End of string and end of pattend - if (*string == '\0') { - return 0; - } else { - return FNM_NOMATCH; - } + // End of string and end of pattend + if (*string == '\0') + return 0; + return FNM_NOMATCH; } #if __TEST_FNMATCH__ -int main() { - assert(rl_fnmatch("TEST", "TEST", 0) == 0); - assert(rl_fnmatch("TE?T", "TEST", 0) == 0); - assert(rl_fnmatch("TE[Ssa]T", "TEST", 0) == 0); - assert(rl_fnmatch("TE[Ssda]T", "TEsT", 0) == 0); - assert(rl_fnmatch("TE[Ssda]T", "TEdT", 0) == 0); - assert(rl_fnmatch("TE[Ssda]T", "TEaT", 0) == 0); - assert(rl_fnmatch("TEST*", "TEST", 0) == 0); - assert(rl_fnmatch("TEST**", "TEST", 0) == 0); - assert(rl_fnmatch("TE*ST*", "TEST", 0) == 0); - assert(rl_fnmatch("TE**ST*", "TEST", 0) == 0); - assert(rl_fnmatch("TE**ST*", "TExST", 0) == 0); - assert(rl_fnmatch("TE**ST", "TEST", 0) == 0); - assert(rl_fnmatch("TE**ST", "TExST", 0) == 0); - assert(rl_fnmatch("TE\\**ST", "TE*xST", 0) == 0); - assert(rl_fnmatch("*.*", "test.jpg", 0) == 0); - assert(rl_fnmatch("*.jpg", "test.jpg", 0) == 0); - assert(rl_fnmatch("*.[Jj][Pp][Gg]", "test.jPg", 0) == 0); - assert(rl_fnmatch("*.[Jj]*[Gg]", "test.jPg", 0) == 0); - assert(rl_fnmatch("TEST?", "TEST", 0) == FNM_NOMATCH); - assert(rl_fnmatch("TES[asd", "TEST", 0) == FNM_NOMATCH); - assert(rl_fnmatch("TEST\\", "TEST", 0) == FNM_NOMATCH); - assert(rl_fnmatch("TEST*S", "TEST", 0) == FNM_NOMATCH); - assert(rl_fnmatch("TE**ST", "TExT", 0) == FNM_NOMATCH); - assert(rl_fnmatch("TE\\*T", "TExT", 0) == FNM_NOMATCH); - assert(rl_fnmatch("TES?", "TES", 0) == FNM_NOMATCH); - assert(rl_fnmatch("TE", "TEST", 0) == FNM_NOMATCH); - assert(rl_fnmatch("TEST!", "TEST", 0) == FNM_NOMATCH); - assert(rl_fnmatch("DSAD", "TEST", 0) == FNM_NOMATCH); +int main(void) +{ + assert(rl_fnmatch("TEST", "TEST", 0) == 0); + assert(rl_fnmatch("TE?T", "TEST", 0) == 0); + assert(rl_fnmatch("TE[Ssa]T", "TEST", 0) == 0); + assert(rl_fnmatch("TE[Ssda]T", "TEsT", 0) == 0); + assert(rl_fnmatch("TE[Ssda]T", "TEdT", 0) == 0); + assert(rl_fnmatch("TE[Ssda]T", "TEaT", 0) == 0); + assert(rl_fnmatch("TEST*", "TEST", 0) == 0); + assert(rl_fnmatch("TEST**", "TEST", 0) == 0); + assert(rl_fnmatch("TE*ST*", "TEST", 0) == 0); + assert(rl_fnmatch("TE**ST*", "TEST", 0) == 0); + assert(rl_fnmatch("TE**ST*", "TExST", 0) == 0); + assert(rl_fnmatch("TE**ST", "TEST", 0) == 0); + assert(rl_fnmatch("TE**ST", "TExST", 0) == 0); + assert(rl_fnmatch("TE\\**ST", "TE*xST", 0) == 0); + assert(rl_fnmatch("*.*", "test.jpg", 0) == 0); + assert(rl_fnmatch("*.jpg", "test.jpg", 0) == 0); + assert(rl_fnmatch("*.[Jj][Pp][Gg]", "test.jPg", 0) == 0); + assert(rl_fnmatch("*.[Jj]*[Gg]", "test.jPg", 0) == 0); + assert(rl_fnmatch("TEST?", "TEST", 0) == FNM_NOMATCH); + assert(rl_fnmatch("TES[asd", "TEST", 0) == FNM_NOMATCH); + assert(rl_fnmatch("TEST\\", "TEST", 0) == FNM_NOMATCH); + assert(rl_fnmatch("TEST*S", "TEST", 0) == FNM_NOMATCH); + assert(rl_fnmatch("TE**ST", "TExT", 0) == FNM_NOMATCH); + assert(rl_fnmatch("TE\\*T", "TExT", 0) == FNM_NOMATCH); + assert(rl_fnmatch("TES?", "TES", 0) == FNM_NOMATCH); + assert(rl_fnmatch("TE", "TEST", 0) == FNM_NOMATCH); + assert(rl_fnmatch("TEST!", "TEST", 0) == FNM_NOMATCH); + assert(rl_fnmatch("DSAD", "TEST", 0) == FNM_NOMATCH); } #endif diff --git a/tools/retrolaunch/sha1.c b/tools/retrolaunch/sha1.c index d87c7f4830..240cadf3e4 100644 --- a/tools/retrolaunch/sha1.c +++ b/tools/retrolaunch/sha1.c @@ -43,329 +43,210 @@ /* * Define the circular shift macro */ -#define SHA1CircularShift(bits,word) \ - ((((word) << (bits)) & 0xFFFFFFFF) | \ - ((word) >> (32-(bits)))) +#define SHA1CircularShift(bits,word) ((((word) << (bits)) & 0xFFFFFFFF) | ((word) >> (32-(bits)))) -/* Function prototypes */ -void SHA1ProcessMessageBlock(SHA1Context *); -void SHA1PadMessage(SHA1Context *); - -/* - * SHA1Reset - * - * Description: - * This function will initialize the SHA1Context in preparation - * for computing a new message digest. - * - * Parameters: - * context: [in/out] - * The context to reset. - * - * Returns: - * Nothing. - * - * Comments: - * - */ void SHA1Reset(SHA1Context *context) { - context->Length_Low = 0; - context->Length_High = 0; - context->Message_Block_Index = 0; + context->Length_Low = 0; + context->Length_High = 0; + context->Message_Block_Index = 0; - context->Message_Digest[0] = 0x67452301; - context->Message_Digest[1] = 0xEFCDAB89; - context->Message_Digest[2] = 0x98BADCFE; - context->Message_Digest[3] = 0x10325476; - context->Message_Digest[4] = 0xC3D2E1F0; + context->Message_Digest[0] = 0x67452301; + context->Message_Digest[1] = 0xEFCDAB89; + context->Message_Digest[2] = 0x98BADCFE; + context->Message_Digest[3] = 0x10325476; + context->Message_Digest[4] = 0xC3D2E1F0; - context->Computed = 0; - context->Corrupted = 0; + context->Computed = 0; + context->Corrupted = 0; +} + +void SHA1ProcessMessageBlock(SHA1Context *context) +{ + const unsigned K[] = /* Constants defined in SHA-1 */ + { + 0x5A827999, + 0x6ED9EBA1, + 0x8F1BBCDC, + 0xCA62C1D6 + }; + int t; /* Loop counter */ + unsigned temp; /* Temporary word value */ + unsigned W[80]; /* Word sequence */ + unsigned A, B, C, D, E; /* Word buffers */ + + /* + * Initialize the first 16 words in the array W + */ + for(t = 0; t < 16; t++) + { + W[t] = ((unsigned) context->Message_Block[t * 4]) << 24; + W[t] |= ((unsigned) context->Message_Block[t * 4 + 1]) << 16; + W[t] |= ((unsigned) context->Message_Block[t * 4 + 2]) << 8; + W[t] |= ((unsigned) context->Message_Block[t * 4 + 3]); + } + + for(t = 16; t < 80; t++) + { + W[t] = SHA1CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]); + } + + A = context->Message_Digest[0]; + B = context->Message_Digest[1]; + C = context->Message_Digest[2]; + D = context->Message_Digest[3]; + E = context->Message_Digest[4]; + + for(t = 0; t < 20; t++) + { + temp = SHA1CircularShift(5,A) + + ((B & C) | ((~B) & D)) + E + W[t] + K[0]; + temp &= 0xFFFFFFFF; + E = D; + D = C; + C = SHA1CircularShift(30,B); + B = A; + A = temp; + } + + for(t = 20; t < 40; t++) + { + temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[1]; + temp &= 0xFFFFFFFF; + E = D; + D = C; + C = SHA1CircularShift(30,B); + B = A; + A = temp; + } + + for(t = 40; t < 60; t++) + { + temp = SHA1CircularShift(5,A) + + ((B & C) | (B & D) | (C & D)) + E + W[t] + K[2]; + temp &= 0xFFFFFFFF; + E = D; + D = C; + C = SHA1CircularShift(30,B); + B = A; + A = temp; + } + + for(t = 60; t < 80; t++) + { + temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[3]; + temp &= 0xFFFFFFFF; + E = D; + D = C; + C = SHA1CircularShift(30,B); + B = A; + A = temp; + } + + context->Message_Digest[0] = + (context->Message_Digest[0] + A) & 0xFFFFFFFF; + context->Message_Digest[1] = + (context->Message_Digest[1] + B) & 0xFFFFFFFF; + context->Message_Digest[2] = + (context->Message_Digest[2] + C) & 0xFFFFFFFF; + context->Message_Digest[3] = + (context->Message_Digest[3] + D) & 0xFFFFFFFF; + context->Message_Digest[4] = + (context->Message_Digest[4] + E) & 0xFFFFFFFF; + + context->Message_Block_Index = 0; +} + +void SHA1PadMessage(SHA1Context *context) +{ + /* + * Check to see if the current message block is too small to hold + * the initial padding bits and length. If so, we will pad the + * block, process it, and then continue padding into a second + * block. + */ + if (context->Message_Block_Index > 55) + { + context->Message_Block[context->Message_Block_Index++] = 0x80; + while(context->Message_Block_Index < 64) + context->Message_Block[context->Message_Block_Index++] = 0; + + SHA1ProcessMessageBlock(context); + + while(context->Message_Block_Index < 56) + context->Message_Block[context->Message_Block_Index++] = 0; + } + else + { + context->Message_Block[context->Message_Block_Index++] = 0x80; + while(context->Message_Block_Index < 56) + context->Message_Block[context->Message_Block_Index++] = 0; + } + + /* + * Store the message length as the last 8 octets + */ + context->Message_Block[56] = (context->Length_High >> 24) & 0xFF; + context->Message_Block[57] = (context->Length_High >> 16) & 0xFF; + context->Message_Block[58] = (context->Length_High >> 8) & 0xFF; + context->Message_Block[59] = (context->Length_High) & 0xFF; + context->Message_Block[60] = (context->Length_Low >> 24) & 0xFF; + context->Message_Block[61] = (context->Length_Low >> 16) & 0xFF; + context->Message_Block[62] = (context->Length_Low >> 8) & 0xFF; + context->Message_Block[63] = (context->Length_Low) & 0xFF; + + SHA1ProcessMessageBlock(context); } -/* - * SHA1Result - * - * Description: - * This function will return the 160-bit message digest into the - * Message_Digest array within the SHA1Context provided - * - * Parameters: - * context: [in/out] - * The context to use to calculate the SHA-1 hash. - * - * Returns: - * 1 if successful, 0 if it failed. - * - * Comments: - * - */ int SHA1Result(SHA1Context *context) { + if (context->Corrupted) + return 0; - if (context->Corrupted) - { - return 0; - } + if (!context->Computed) + { + SHA1PadMessage(context); + context->Computed = 1; + } - if (!context->Computed) - { - SHA1PadMessage(context); - context->Computed = 1; - } - - return 1; + return 1; } -/* - * SHA1Input - * - * Description: - * This function accepts an array of octets as the next portion of - * the message. - * - * Parameters: - * context: [in/out] - * The SHA-1 context to update - * message_array: [in] - * An array of characters representing the next portion of the - * message. - * length: [in] - * The length of the message in message_array - * - * Returns: - * Nothing. - * - * Comments: - * - */ void SHA1Input( SHA1Context *context, const unsigned char *message_array, unsigned length) { - if (!length) - { - return; - } + if (!length) + return; - if (context->Computed || context->Corrupted) - { - context->Corrupted = 1; - return; - } + if (context->Computed || context->Corrupted) + { + context->Corrupted = 1; + return; + } - while(length-- && !context->Corrupted) - { - context->Message_Block[context->Message_Block_Index++] = - (*message_array & 0xFF); + while(length-- && !context->Corrupted) + { + context->Message_Block[context->Message_Block_Index++] = + (*message_array & 0xFF); - context->Length_Low += 8; - /* Force it to 32 bits */ - context->Length_Low &= 0xFFFFFFFF; - if (context->Length_Low == 0) - { - context->Length_High++; - /* Force it to 32 bits */ - context->Length_High &= 0xFFFFFFFF; - if (context->Length_High == 0) - { - /* Message is too long */ - context->Corrupted = 1; - } - } + context->Length_Low += 8; + /* Force it to 32 bits */ + context->Length_Low &= 0xFFFFFFFF; + if (context->Length_Low == 0) + { + context->Length_High++; + /* Force it to 32 bits */ + context->Length_High &= 0xFFFFFFFF; + if (context->Length_High == 0) + context->Corrupted = 1; /* Message is too long */ + } - if (context->Message_Block_Index == 64) - { - SHA1ProcessMessageBlock(context); - } + if (context->Message_Block_Index == 64) + SHA1ProcessMessageBlock(context); - message_array++; - } + message_array++; + } } -/* - * SHA1ProcessMessageBlock - * - * Description: - * This function will process the next 512 bits of the message - * stored in the Message_Block array. - * - * Parameters: - * None. - * - * Returns: - * Nothing. - * - * Comments: - * Many of the variable names in the SHAContext, especially the - * single character names, were used because those were the names - * used in the publication. - * - * - */ -void SHA1ProcessMessageBlock(SHA1Context *context) -{ - const unsigned K[] = /* Constants defined in SHA-1 */ - { - 0x5A827999, - 0x6ED9EBA1, - 0x8F1BBCDC, - 0xCA62C1D6 - }; - int t; /* Loop counter */ - unsigned temp; /* Temporary word value */ - unsigned W[80]; /* Word sequence */ - unsigned A, B, C, D, E; /* Word buffers */ - /* - * Initialize the first 16 words in the array W - */ - for(t = 0; t < 16; t++) - { - W[t] = ((unsigned) context->Message_Block[t * 4]) << 24; - W[t] |= ((unsigned) context->Message_Block[t * 4 + 1]) << 16; - W[t] |= ((unsigned) context->Message_Block[t * 4 + 2]) << 8; - W[t] |= ((unsigned) context->Message_Block[t * 4 + 3]); - } - - for(t = 16; t < 80; t++) - { - W[t] = SHA1CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]); - } - - A = context->Message_Digest[0]; - B = context->Message_Digest[1]; - C = context->Message_Digest[2]; - D = context->Message_Digest[3]; - E = context->Message_Digest[4]; - - for(t = 0; t < 20; t++) - { - temp = SHA1CircularShift(5,A) + - ((B & C) | ((~B) & D)) + E + W[t] + K[0]; - temp &= 0xFFFFFFFF; - E = D; - D = C; - C = SHA1CircularShift(30,B); - B = A; - A = temp; - } - - for(t = 20; t < 40; t++) - { - temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[1]; - temp &= 0xFFFFFFFF; - E = D; - D = C; - C = SHA1CircularShift(30,B); - B = A; - A = temp; - } - - for(t = 40; t < 60; t++) - { - temp = SHA1CircularShift(5,A) + - ((B & C) | (B & D) | (C & D)) + E + W[t] + K[2]; - temp &= 0xFFFFFFFF; - E = D; - D = C; - C = SHA1CircularShift(30,B); - B = A; - A = temp; - } - - for(t = 60; t < 80; t++) - { - temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[3]; - temp &= 0xFFFFFFFF; - E = D; - D = C; - C = SHA1CircularShift(30,B); - B = A; - A = temp; - } - - context->Message_Digest[0] = - (context->Message_Digest[0] + A) & 0xFFFFFFFF; - context->Message_Digest[1] = - (context->Message_Digest[1] + B) & 0xFFFFFFFF; - context->Message_Digest[2] = - (context->Message_Digest[2] + C) & 0xFFFFFFFF; - context->Message_Digest[3] = - (context->Message_Digest[3] + D) & 0xFFFFFFFF; - context->Message_Digest[4] = - (context->Message_Digest[4] + E) & 0xFFFFFFFF; - - context->Message_Block_Index = 0; -} - -/* - * SHA1PadMessage - * - * Description: - * According to the standard, the message must be padded to an even - * 512 bits. The first padding bit must be a '1'. The last 64 - * bits represent the length of the original message. All bits in - * between should be 0. This function will pad the message - * according to those rules by filling the Message_Block array - * accordingly. It will also call SHA1ProcessMessageBlock() - * appropriately. When it returns, it can be assumed that the - * message digest has been computed. - * - * Parameters: - * context: [in/out] - * The context to pad - * - * Returns: - * Nothing. - * - * Comments: - * - */ -void SHA1PadMessage(SHA1Context *context) -{ - /* - * Check to see if the current message block is too small to hold - * the initial padding bits and length. If so, we will pad the - * block, process it, and then continue padding into a second - * block. - */ - if (context->Message_Block_Index > 55) - { - context->Message_Block[context->Message_Block_Index++] = 0x80; - while(context->Message_Block_Index < 64) - { - context->Message_Block[context->Message_Block_Index++] = 0; - } - - SHA1ProcessMessageBlock(context); - - while(context->Message_Block_Index < 56) - { - context->Message_Block[context->Message_Block_Index++] = 0; - } - } - else - { - context->Message_Block[context->Message_Block_Index++] = 0x80; - while(context->Message_Block_Index < 56) - { - context->Message_Block[context->Message_Block_Index++] = 0; - } - } - - /* - * Store the message length as the last 8 octets - */ - context->Message_Block[56] = (context->Length_High >> 24) & 0xFF; - context->Message_Block[57] = (context->Length_High >> 16) & 0xFF; - context->Message_Block[58] = (context->Length_High >> 8) & 0xFF; - context->Message_Block[59] = (context->Length_High) & 0xFF; - context->Message_Block[60] = (context->Length_Low >> 24) & 0xFF; - context->Message_Block[61] = (context->Length_Low >> 16) & 0xFF; - context->Message_Block[62] = (context->Length_Low >> 8) & 0xFF; - context->Message_Block[63] = (context->Length_Low) & 0xFF; - - SHA1ProcessMessageBlock(context); -}