hmt/main.c

388 lines
8.4 KiB
C

/*
* Humax HMT Tool
* (c) af123, 2011-2016
*/
#include <stdio.h>
#include <errno.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <string.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <time.h>
#include "lint.h"
int debug = 0;
const char *version = "2.0.10";
unsigned long sysopts = 0;
int
syntax()
{
fprintf(stderr, "Humax HMT Tool v%s, by af123, 2011-2016.\n\n",
version);
fprintf(stderr,
"Syntax: hmt [command] <filename> [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=<seconds>[:<seconds>]...\n"
" +setbookmarks=<seconds>[:<seconds>]...\n"
" +clearbookmarks\n"
" +settitle=<new title>\n"
" +setsynopsis=<new synopsis>\n"
" +setguidance=<new guidance>\n"
);
fprintf(stderr,
" +setseries=<series,episode,episodes>\n"
" +setfolder=<new folder> (patch hmt only)\n"
" +setfilename=<new filename> (patch hmt only)\n"
" +setgenre=<genre> (can just specifiy initial part)\n"
" +setresume=<resume point (seconds)> "
"(-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 preceeded 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 preceeded 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;
}