int main (int argc, char **argv) { int x = 0, y = 0, rom_index = 0, c = 0; #if (FILENAME_MAX < MAXBUFSIZE) static char buf[MAXBUFSIZE]; #else static char buf[FILENAME_MAX]; #endif struct stat fstate; struct option long_options[UCON64_MAX_ARGS]; printf ("%s\n" "Uses code from various people. See 'developers.html' for more!\n" "This may be freely redistributed under the terms of the GNU Public License\n\n", ucon64_title); if (atexit (ucon64_exit) == -1) { fputs ("ERROR: Could not register function with atexit()\n", stderr); exit (1); } // flush st_ucon64_t memset (&ucon64, 0, sizeof (st_ucon64_t)); ucon64.rom = ucon64.file = ucon64.mapr = ucon64.comment = ""; ucon64.parport_needed = 0; ucon64.flags = WF_DEFAULT; ucon64.fname_arch[0] = 0; ucon64.argc = argc; ucon64.argv = argv; // must be set prior to calling // ucon64_load_discmage() (for DOS) // convert (st_getopt2_t **) to (st_getopt2_t *) memset (&options, 0, sizeof (st_getopt2_t) * UCON64_MAX_ARGS); for (c = x = 0; option[x]; x++) for (y = 0; option[x][y].name || option[x][y].help; y++) if (c < UCON64_MAX_ARGS) { memcpy (&options[c], &option[x][y], sizeof (st_getopt2_t)); c++; } ucon64.options = options; #ifdef DEBUG ucon64_runtime_debug (); // check (st_getopt2_t *) options consistency #endif #ifdef __unix__ // We need to modify the umask, because the configfile is made while we are // still running in root mode. Maybe 0 is even better (in case root did // `chmod +s'). umask (002); #endif ucon64_configfile (); #ifdef USE_ANSI_COLOR // ANSI colors? ucon64.ansi_color = get_property_int (ucon64.configfile, "ansi_color"); // the conditional call to ansi_init() has to be done *after* the check for // the switch -ncol #endif // parallel port? #ifdef USE_PPDEV get_property (ucon64.configfile, "parport_dev", ucon64.parport_dev, "/dev/parport0"); #elif defined AMIGA get_property (ucon64.configfile, "parport_dev", ucon64.parport_dev, "parallel.device"); #endif // use -1 (UCON64_UNKNOWN) to force probing if the config file doesn't contain // a parport line sscanf (get_property (ucon64.configfile, "parport", buf, "-1"), "%x", &ucon64.parport); // make backups? ucon64.backup = get_property_int (ucon64.configfile, "backups"); // $HOME/.ucon64/ ? get_property_fname (ucon64.configfile, "ucon64_configdir", ucon64.configdir, ""); // DAT file handling ucon64.dat_enabled = 0; get_property_fname (ucon64.configfile, "ucon64_datdir", ucon64.datdir, ""); // we use ucon64.datdir as path to the dats if (!access (ucon64.datdir, // !W_OK doesn't mean that files can't be written to dir for Win32 exe's #if !defined __CYGWIN__ && !defined _WIN32 W_OK | #endif R_OK | X_OK)) if (!stat (ucon64.datdir, &fstate)) if (S_ISDIR (fstate.st_mode)) ucon64.dat_enabled = 1; if (!ucon64.dat_enabled) if (!access (ucon64.configdir, #if !defined __CYGWIN__ && !defined _WIN32 W_OK | #endif R_OK | X_OK)) if (!stat (ucon64.configdir, &fstate)) if (S_ISDIR (fstate.st_mode)) { // fprintf (stderr, "Please move your DAT files from %s to %s\n\n", ucon64.configdir, ucon64.datdir); strcpy (ucon64.datdir, ucon64.configdir); // use .ucon64/ instead of .ucon64/dat/ ucon64.dat_enabled = 1; } if (ucon64.dat_enabled) ucon64_dat_indexer (); // update cache (index) files if necessary #ifdef USE_DISCMAGE // load libdiscmage ucon64.discmage_enabled = ucon64_load_discmage (); #endif if (argc < 2) { ucon64_usage (argc, argv); return 0; } // turn st_getopt2_t into struct option getopt2_long_only (long_options, options, UCON64_MAX_ARGS); // getopt() is utilized to make uCON64 handle/parse cmdlines in a sane // and expected way x = optind = 0; memset (&arg, 0, sizeof (st_args_t) * UCON64_MAX_ARGS); while ((c = getopt_long_only (argc, argv, "", long_options, NULL)) != -1) { if (c == '?') // getopt() returns 0x3f ('?') when an unknown option was given { fprintf (stderr, "Try '%s " OPTION_LONG_S "help' for more information.\n", argv[0]); exit (1); } if (x < UCON64_MAX_ARGS) { const st_ucon64_obj_t *p = (st_ucon64_obj_t *) getopt2_get_index_by_val (options, c)->object; arg[x].console = UCON64_UNKNOWN; // default if (p) { arg[x].flags = p->flags; if (p->console) arg[x].console = p->console; } arg[x].val = c; arg[x++].optarg = (optarg ? optarg : NULL); } else // this shouldn't happen exit (1); } #ifdef DEBUG for (x = 0; arg[x].val; x++) printf ("%d %s %d %d\n\n", arg[x].val, arg[x].optarg ? arg[x].optarg : "(null)", arg[x].flags, arg[x].console); #endif rom_index = optind; // save index of first file if (rom_index == argc) ucon64_execute_options(); else for (; rom_index < argc; rom_index++) { int result = 0; char buf2[FILENAME_MAX]; #ifndef _WIN32 struct dirent *ep; DIR *dp; #else char search_pattern[FILENAME_MAX]; WIN32_FIND_DATA find_data; HANDLE dp; #endif realpath2 (argv[rom_index], buf); if (stat (buf, &fstate) != -1) { if (S_ISREG (fstate.st_mode)) result = ucon64_process_rom (buf); else if (S_ISDIR (fstate.st_mode)) // a dir? { char *p; #if defined __MSDOS__ || defined _WIN32 || defined __CYGWIN__ /* Note that this code doesn't make much sense for Cygwin, because at least the version I use (1.3.6, dbjh) doesn't support current directories for drives. */ c = toupper (buf[0]); if (buf[strlen (buf) - 1] == FILE_SEPARATOR || (c >= 'A' && c <= 'Z' && buf[1] == ':' && buf[2] == 0)) #else if (buf[strlen (buf) - 1] == FILE_SEPARATOR) #endif p = ""; else p = FILE_SEPARATOR_S; #ifndef _WIN32 if ((dp = opendir (buf))) { while ((ep = readdir (dp))) { sprintf (buf2, "%s%s%s", buf, p, ep->d_name); if (stat (buf2, &fstate) != -1) if (S_ISREG (fstate.st_mode)) { result = ucon64_process_rom (buf2); if (result == 1) break; } } closedir (dp); } #else sprintf (search_pattern, "%s%s*", buf, p); if ((dp = FindFirstFile (search_pattern, &find_data)) != INVALID_HANDLE_VALUE) { do { sprintf (buf2, "%s%s%s", buf, p, find_data.cFileName); if (stat (buf2, &fstate) != -1) if (S_ISREG (fstate.st_mode)) { result = ucon64_process_rom (buf2); if (result == 1) break; } } while (FindNextFile (dp, &find_data)); FindClose (dp); } #endif } else result = ucon64_process_rom (buf); } else result = ucon64_process_rom (buf); if (result == 1) break; } return 0; }
int main (int argc, char **argv) { // int i = 0; // char buf[MAXBUFSIZE]; int c = 0, option_index = 0; int x = 0, y = 0; struct option long_only_options[ARGS_MAX]; int result = 0; // const char *p = NULL; const st_property_t props[] = { { "ansi_color", "1", "use ANSI colors in output? (1=yes; 0=no)" }, { "default_cmdline", "", "will be used when quh is started w/o args" }, { "settings", "100", "internal settings like volume, etc." }, #if 0 { "quh_configdir", PROPERTY_MODE_DIR ("quh"), "directory with additional config files" }, #endif {NULL, NULL, NULL} }; memset (&quh, 0, sizeof (st_quh_t)); // defaults quh.pid = 1; tmpnam3 (quh.tmp_file, 0); set_suffix (quh.tmp_file, ".wav"); if(!(quh.o = cache_open (MAXBUFSIZE, CACHE_MEM|CACHE_LIFO))) { fprintf (stderr, "ERROR: Could not malloc %d bytes\n", MAXBUFSIZE); return -1; } realpath2 (PROPERTY_HOME_RC ("quh"), quh.configfile); result = property_check (quh.configfile, QUH_CONFIG_VERSION, 1); if (result == 1) // update needed result = set_property_array (quh.configfile, props); if (result == -1) // property_check() or update failed return -1; signal (SIGINT, quh_signal_handler); signal (SIGTERM, quh_signal_handler); atexit (quh_exit); quh.ansi_color = get_property_int (quh.configfile, "ansi_color"); quh.settings = get_property_int (quh.configfile, "settings"); quh.argc = argc; quh.argv = argv; #if 0 // memorize cmdline if (quh.argc > 2) { for (; quh.argv[i] && i < quh.argc; i++) sprintf (strchr (buf, 0), "%s ", quh.argv[i]); set_property (quh.configfile, "default_cmdline", buf, "will be used when quh is started w/o args"); } else { p = get_property (quh.configfile, "default_cmdline", PROPERTY_MODE_TEXT); if (p) { strncpy (buf, p, MAXBUFSIZE)[MAXBUFSIZE - 1] = 0; quh.argc = strarg (quh.argv, buf, " ", QUH_MAX_ARGS); } } #endif // set default filter chain filters = 0; quh.filter_id[filters++] = QUH_CACHE_PASS; quh.filter_id[filters++] = QUH_CONSOLE_PASS; #ifdef USE_ID3 // quh.filter_id[filters++] = QUH_ID3_IN; #endif // quh.filter_id[filters++] = QUH_CDDB_IN; #ifdef USE_OSS quh.filter_id[filters++] = QUH_OSS_OUT; #elif defined USE_SDL quh.filter_id[filters++] = QUH_SDL_OUT; #endif // convert (st_getopt2_t **) to (st_getopt2_t *) memset (&options, 0, sizeof (st_getopt2_t) * QUH_MAX_ARGS); for (c = x = 0; option[x]; x++) for (y = 0; option[x][y].name || option[x][y].help; y++) if (c < QUH_MAX_ARGS) { memcpy (&options[c], &option[x][y], sizeof (st_getopt2_t)); c++; } #if 0 for (x = 0; quh_decode_usage[x]; x++) if (c < QUH_MAX_ARGS) { memcpy (&options[c], quh_decode_usage[x], sizeof (st_getopt2_t)); c++; } #endif for (x = 0; quh_filter_usage[x]; x++) if (c < QUH_MAX_ARGS) { memcpy (&options[c], quh_filter_usage[x], sizeof (st_getopt2_t)); c++; } for (x = 0; option2[x]; x++) for (y = 0; option2[x][y].name || option2[x][y].help; y++) if (c < QUH_MAX_ARGS) { memcpy (&options[c], &option2[x][y], sizeof (st_getopt2_t)); c++; } getopt2_long_only (long_only_options, options, ARGS_MAX); #if 0 // if no options or filenames were specified we use a default cmdline if (argc < 2) // || !optind) { p = get_property (quh.configfile, "default_cmdline", PROPERTY_MODE_TEXT); if (p) { strncpy (quh.cmdline, p, ARGS_MAX)[ARGS_MAX - 1] = 0; quh.argc = strarg (quh.argv, quh.cmdline, " ", QUH_MAX_ARGS); } } else // store cmdline { strcpy (quh.cmdline, argv[0]); for (x = 1; x < argc; x++) sprintf (strchr (quh.cmdline, 0), " \"%s\"", quh.argv[x]); set_property (quh.configfile, "default_cmdline", quh.cmdline, NULL); } for (x = 0; x < quh.argc; x++) printf ("quh.argv[%d] == %s\n", x, quh.argv[x]); fflush (stdout); #endif while ((c = getopt_long_only (quh.argc, quh.argv, "", long_only_options, &option_index)) != -1) quh_opts (c); // if (quh.verbose) if (!quh.quiet) fputs ("Quh " QUH_VERSION_S " 'Having ears makes sense again' 2005-2006 by NoisyB\n" "This may be freely redistributed under the terms of the GNU Public License\n\n", stdout); if (quh.argc < 2) // || !optind) { getopt2_usage (options); return -1; } #warning files? #if 0 if (!getfile (quh.argc, quh.argv, quh_set_fname, (GETFILE_FILES_ONLY | (quh.flags & QUH_RECURSIVE ? GETFILE_RECURSIVE : 0)))) // recursively? { if (!quh.quiet) getopt2_usage (options); return -1; } #endif if (!quh.filter_id[0]) { fputs ("ERROR: you haven't specified any filters\n", stderr); fflush (stderr); return -1; } if (!quh.files) { fputs ("ERROR: you haven't specified any files to play\n", stderr); fflush (stderr); return -1; } if (!(quh.filter_chain = filter_malloc_chain (quh_filter))) { fputs ("ERROR: filter_malloc_chain() failed\n", stderr); fflush (stderr); return -1; } if (filter_init (quh.filter_chain, NULL, NULL) == -1) { fputs ("ERROR: filter_init() failed\n", stderr); fflush (stderr); return -1; } quh_play (); return 0; }