/* * Humax HMT Tool * (c) af123, 2011-2016 */ #include #include #include #include #include #include #include #include #include #include "lint.h" int debug = 0; const char *version = "2.0.11"; unsigned long sysopts = 0; int syntax() { fprintf(stderr, "Humax HMT Tool v%s, by af123, 2011-2019.\n\n", version); fprintf(stderr, "Syntax: hmt [command] [filename] ...\n"); fprintf(stderr, " Commands:\n" " +/-new Mark/unmark recording as new.\n" " +/-lock Mark/unmark recording as locked.\n" " +/-guidance Mark/unmark recording as having guidance.\n" ); fprintf(stderr, " +/-protect Enable/disable protection" " (prevents decryption on copy).\n" " +/-encrypted Mark/unmark recording as encrypted.\n" " +/-shrunk Mark/unmark recording as shrunk.\n" " +/-dedup Mark/unmark recording as deduped.\n" " +/-detectads Mark/unmark recording as ad-detection-done.\n" ); fprintf(stderr, " -p Display parseable file information (see *).\n" " -list Display file information (default).\n" " -bookmarks Display bookmarks.\n" " +addbookmark=[:]...\n" " +setbookmarks=[:]...\n" " +clearbookmarks\n" " +settitle=\n" " +setsynopsis=\n" " +setguidance=\n" ); fprintf(stderr, " +setseries=\n" " +setfolder= (patch hmt only)\n" " +setfilename= (patch hmt only)\n" " +setgenre= (can just specifiy initial part)\n" " +setresume= " "(-seconds to set from end)\n" ); fprintf(stderr, "\n" "Generic patch commands:\n" " +patch8=offset:value patch 8-bit value\n" " +patch16=offset:value patch 16-bit value\n" " +patch32=offset:value patch 32-bit value\n" " Offset and value can be preceded with 0x to indicate hex.\n" ); fprintf(stderr, "\n" "Generic read commands:\n" " +read8=offset read 8-bit value\n" " +read16=offset read 16-bit value\n" " +read32=offset read 32-bit value\n" " Offset can be preceded with 0x to indicate hex.\n" ); fprintf(stderr, "\n" "* Parseable output is tab delimited and contains the following" " fields:\n" " Title, Synopsis, HD/SD, LCN, Channel Name,\n" " Start time, End time, Flags, Guidance, Bookmark count,\n" " Scheduled start, Scheduled duration, Genre code,\n" " Resume point, Status/Reason.\n" ); fprintf(stderr, "\n"); return 0; } int main(int argc, char **argv) { enum { CMD_LIST = 0, CMD_NEW, CMD_LOCK, CMD_PROTECT, CMD_GUIDANCE, CMD_ENCRYPTED, CMD_SHRUNK, CMD_DEDUP, CMD_DETECTADS, CMD_SETTITLE, CMD_SETSYNOPSIS, CMD_SETGUIDANCE, CMD_SETFOLDER, CMD_SETSERIES, CMD_SETFILENAME, CMD_SETGENRE, CMD_SETRESUME, CMD_BOOKMARKS, CMD_ADDBOOKMARK, CMD_SETBOOKMARKS, CMD_CLEARBOOKMARKS, CMD_PATCH, CMD_UNPATCH } cmd = CMD_LIST; char *newstr = ""; int i, toggle; if (argc > 1 && !strncmp(argv[1], "-d", 2)) { if (argv[1][2] == '\0') debug = 1; else debug = atoi(argv[1] + 2); if (debug > 0) { printf("Set debug level to %d\n", debug); argc--, argv++; } } if (argc > 1 && !strcmp(argv[1], "-p")) { sysopts |= SYSOPT_PARSABLE; argc--, argv++; } if (argc < 2) return syntax(); toggle = 0; switch (*argv[1]) { case '+': toggle = 1; /* Fall-through */ case '-': if (!strcmp(argv[1] + 1, "list")) cmd = CMD_LIST; else if (!strcmp(argv[1] + 1, "new")) cmd = CMD_NEW; else if (!strcmp(argv[1] + 1, "lock")) cmd = CMD_LOCK; else if (!strcmp(argv[1] + 1, "protect")) cmd = CMD_PROTECT; else if (!strcmp(argv[1] + 1, "guidance")) cmd = CMD_GUIDANCE; else if (!strcmp(argv[1] + 1, "encrypted")) cmd = CMD_ENCRYPTED; else if (!strcmp(argv[1] + 1, "shrunk")) cmd = CMD_SHRUNK; else if (!strcmp(argv[1] + 1, "dedup")) cmd = CMD_DEDUP; else if (!strcmp(argv[1] + 1, "detectads")) cmd = CMD_DETECTADS; else if (!strcmp(argv[1] + 1, "bookmarks")) cmd = CMD_BOOKMARKS; else if (!strncmp(argv[1], "+patch", 6)) { newstr = argv[1] + 6; cmd = CMD_PATCH; } else if (!strncmp(argv[1], "+read", 5)) { newstr = argv[1] + 5; cmd = CMD_UNPATCH; } else if (!strncmp(argv[1], "+settitle=", 10)) { newstr = argv[1] + 10; if (strlen(newstr) >= HMT_TITLE_LEN) { fprintf(stderr, "New title too long.\n"); return 0; } cmd = CMD_SETTITLE; } else if (!strncmp(argv[1], "+setsynopsis=", 13)) { newstr = argv[1] + 13; cmd = CMD_SETSYNOPSIS; } else if (!strncmp(argv[1], "+setguidance=", 13)) { newstr = argv[1] + 13; if (strlen(newstr) >= HMT_GUIDANCE_LEN) { fprintf(stderr, "New guidance too long.\n"); return 0; } cmd = CMD_SETGUIDANCE; } else if (!strncmp(argv[1], "+setseries=", 11)) { newstr = argv[1] + 11; cmd = CMD_SETSERIES; } else if (!strncmp(argv[1], "+setfolder=", 11)) { newstr = argv[1] + 11; if (strlen(newstr) >= HMT_FOLDER_LEN) { fprintf(stderr, "New folder too long.\n"); return 0; } cmd = CMD_SETFOLDER; } else if (!strncmp(argv[1], "+setfilename=", 13)) { newstr = argv[1] + 13; if (strlen(newstr) >= HMT_FILENAME_LEN) { fprintf(stderr, "New filename too long.\n"); return 0; } cmd = CMD_SETFILENAME; } else if (!strncmp(argv[1], "+setgenre=", 10)) { newstr = argv[1] + 10; cmd = CMD_SETGENRE; } else if (!strncmp(argv[1], "+setresume=", 11)) { newstr = argv[1] + 11; cmd = CMD_SETRESUME; } else if (!strncmp(argv[1], "+addbookmark=", 13)) { newstr = argv[1] + 13; cmd = CMD_ADDBOOKMARK; } else if (!strncmp(argv[1], "+setbookmarks=", 14)) { newstr = argv[1] + 14; cmd = CMD_SETBOOKMARKS; } else if (!strncmp(argv[1], "+clearbookmarks", 15)) { cmd = CMD_CLEARBOOKMARKS; } else { printf("Unknown command, %s\n", argv[1] + 1); return syntax(); } argc--, argv++; break; } if (debug) printf("Command %d\n", cmd); for (i = 1; i < argc; i++) { struct hmt *hmt; if (!(hmt = open_file(argv[i], cmd == CMD_LIST || cmd == CMD_BOOKMARKS))) continue; switch (cmd) { case CMD_NEW: cmd_new(hmt, toggle); break; case CMD_LOCK: cmd_lock(hmt, toggle); break; case CMD_PROTECT: cmd_protect(hmt, toggle); break; case CMD_ENCRYPTED: cmd_encrypted(hmt, toggle); break; case CMD_SHRUNK: cmd_shrunk(hmt, toggle); break; case CMD_DEDUP: cmd_dedup(hmt, toggle); break; case CMD_DETECTADS: cmd_detectads(hmt, toggle); break; case CMD_SETTITLE: cmd_settitle(hmt, newstr); break; case CMD_SETSYNOPSIS: cmd_setsynopsis(hmt, newstr); break; case CMD_SETGUIDANCE: /* 0x03E0 2 byte 'Guide' flag for Media List. * 0xFF00 = Guide off. 0x0101 = Guide on. */ patch_byte(hmt, HMT_GUIDEFLAG, HMT_GUIDEFLAG_ON); patch_byte(hmt, HMT_GUIDEFLAG + 1, HMT_GUIDEFLAG_ON); patch_string(hmt, HMT_GUIDANCE, HMT_GUIDANCE_LEN, newstr); break; case CMD_SETSERIES: cmd_setseries(hmt, newstr); break; case CMD_SETFOLDER: patch_string(hmt, HMT_FOLDER, HMT_FOLDER_LEN, newstr); break; case CMD_SETFILENAME: patch_string(hmt, HMT_FILENAME, HMT_FILENAME_LEN, newstr); break; case CMD_BOOKMARKS: display_bookmarks(hmt); break; case CMD_GUIDANCE: cmd_guidance(hmt, toggle); break; case CMD_SETGENRE: cmd_setgenre(hmt, newstr); break; case CMD_SETRESUME: cmd_setresume(hmt, newstr); break; case CMD_ADDBOOKMARK: cmd_bookmarks(hmt, newstr, 1); display_bookmarks(hmt); break; case CMD_SETBOOKMARKS: cmd_bookmarks(hmt, newstr, 0); display_bookmarks(hmt); break; case CMD_CLEARBOOKMARKS: cmd_bookmarks(hmt, NULL, 0); display_bookmarks(hmt); break; case CMD_PATCH: cmd_patch(hmt, newstr); break; case CMD_UNPATCH: cmd_unpatch(hmt, newstr); break; default: display_hmt(hmt); } close_file(hmt); } return 0; }