void relation(const osmium::Relation& relation) { print_title("RELATION", relation); print_meta(relation); }
void node(const osmium::Node& node) { print_title("NODE", node); print_meta(node); print_location(node); }
void way(const osmium::Way& way) { print_title("WAY", way); print_meta(way); }
static void long_usage(int err) { char *enclist; FILE* o = stdout; if(err) { o = stderr; fprintf(o, "You made some mistake in program usage... let me remind you:\n\n"); } print_title(o); fprintf(o,"\nusage: %s [option(s)] [file(s) | URL(s) | -]\n", prgName); fprintf(o,"\ninput options\n\n"); fprintf(o," -k <n> --skip <n> skip n frames at beginning\n"); fprintf(o," --skip-id3v2 skip ID3v2 tags without parsing\n"); fprintf(o," -n --frames <n> play only <n> frames of every stream\n"); fprintf(o," --fuzzy Enable fuzzy seeks (guessing byte offsets or using approximate seek points from Xing TOC)\n"); fprintf(o," -y --no-resync DISABLES resync on error (--resync is deprecated)\n"); fprintf(o," -p <f> --proxy <f> set WWW proxy\n"); fprintf(o," -u --auth set auth values for HTTP access\n"); fprintf(o," --ignore-mime ignore HTTP MIME types (content-type)\n"); fprintf(o," --no-seekbuffer disable seek buffer\n"); fprintf(o," -@ <f> --list <f> play songs in playlist <f> (plain list, m3u, pls (shoutcast))\n"); fprintf(o," -l <n> --listentry <n> play nth title in playlist; show whole playlist for n < 0\n"); fprintf(o," --continue playlist continuation mode (see man page)\n"); fprintf(o," --loop <n> loop track(s) <n> times, < 0 means infinite loop (not with --random!)\n"); fprintf(o," --keep-open (--remote mode only) keep loaded file open after reaching end\n"); fprintf(o," --timeout <n> Timeout in seconds before declaring a stream dead (if <= 0, wait forever)\n"); fprintf(o," -z --shuffle shuffle song-list before playing\n"); fprintf(o," -Z --random full random play\n"); fprintf(o," --no-icy-meta Do not accept ICY meta data\n"); fprintf(o," -i --index index / scan through the track before playback\n"); fprintf(o," --index-size <n> change size of frame index\n"); fprintf(o," --preframes <n> number of frames to decode in advance after seeking (to keep layer 3 bit reservoir happy)\n"); fprintf(o," --resync-limit <n> Set number of bytes to search for valid MPEG data; <0 means search whole stream.\n"); fprintf(o," --streamdump <f> Dump a copy of input data (as read by libmpg123) to given file.\n"); fprintf(o," --icy-interval <n> Enforce ICY interval in bytes (for playing a stream dump.\n"); fprintf(o," --ignore-streamlength Ignore header info about length of MPEG streams."); fprintf(o,"\noutput/processing options\n\n"); fprintf(o," -o <o> --output <o> select audio output module\n"); fprintf(o," --list-modules list the available modules\n"); fprintf(o," -a <d> --audiodevice <d> select audio device (depending on chosen module)\n"); fprintf(o," -s --stdout write raw audio to stdout (host native format)\n"); fprintf(o," -S --STDOUT play AND output stream (not implemented yet)\n"); fprintf(o," -w <f> --wav <f> write samples as WAV file in <f> (- is stdout)\n"); fprintf(o," --au <f> write samples as Sun AU file in <f> (- is stdout)\n"); fprintf(o," --cdr <f> write samples as raw CD audio file in <f> (- is stdout)\n"); fprintf(o," --reopen force close/open on audiodevice\n"); #ifdef OPT_MULTI fprintf(o," --cpu <string> set cpu optimization\n"); fprintf(o," --test-cpu list optimizations possible with cpu and exit\n"); fprintf(o," --list-cpu list builtin optimizations and exit\n"); #endif #ifdef OPT_3DNOW fprintf(o," --test-3dnow display result of 3DNow! autodetect and exit (obsoleted by --cpu)\n"); fprintf(o," --force-3dnow force use of 3DNow! optimized routine (obsoleted by --test-cpu)\n"); fprintf(o," --no-3dnow force use of floating-pointer routine (obsoleted by --cpu)\n"); #endif fprintf(o," -g --gain [DEPRECATED] set audio hardware output gain\n"); fprintf(o," -f <n> --scale <n> scale output samples (soft gain - based on 32768), default=%li)\n", param.outscale); fprintf(o," --rva-mix,\n"); fprintf(o," --rva-radio use RVA2/ReplayGain values for mix/radio mode\n"); fprintf(o," --rva-album,\n"); fprintf(o," --rva-audiophile use RVA2/ReplayGain values for album/audiophile mode\n"); fprintf(o," -0 --left --single0 play only left channel\n"); fprintf(o," -1 --right --single1 play only right channel\n"); fprintf(o," -m --mono --mix mix stereo to mono\n"); fprintf(o," --stereo duplicate mono channel\n"); fprintf(o," -r --rate force a specific audio output rate\n"); fprintf(o," -2 --2to1 2:1 downsampling\n"); fprintf(o," -4 --4to1 4:1 downsampling\n"); fprintf(o," --pitch <value> set hardware pitch (speedup/down, 0 is neutral; 0.05 is 5%%)\n"); fprintf(o," --8bit force 8 bit output\n"); fprintf(o," --float force floating point output (internal precision)\n"); audio_enclist(&enclist); fprintf(o," -e <c> --encoding <c> force a specific encoding (%s)\n", enclist != NULL ? enclist : "OOM!"); fprintf(o," -d n --doublespeed n play only every nth frame\n"); fprintf(o," -h n --halfspeed n play every frame n times\n"); fprintf(o," --equalizer exp.: scales freq. bands acrd. to 'equalizer.dat'\n"); fprintf(o," --gapless remove padding/junk on mp3s (best with Lame tag)\n"); fprintf(o," This is on by default when libmpg123 supports it.\n"); fprintf(o," --no-gapless disable gapless mode, not remove padding/junk\n"); fprintf(o," --no-infoframe disable parsing of Xing/Lame/VBR/Info frame\n"); fprintf(o," -D n --delay n insert a delay of n seconds before each track\n"); fprintf(o," -o h --headphones (aix/hp/sun) output on headphones\n"); fprintf(o," -o s --speaker (aix/hp/sun) output on speaker\n"); fprintf(o," -o l --lineout (aix/hp/sun) output to lineout\n"); #ifndef NOXFERMEM fprintf(o," -b <n> --buffer <n> set play buffer (\"output cache\")\n"); fprintf(o," --preload <value> fraction of buffer to fill before playback\n"); fprintf(o," --smooth keep buffer over track boundaries\n"); #endif fprintf(o,"\nmisc options\n\n"); fprintf(o," -t --test only decode, no output (benchmark)\n"); fprintf(o," -c --check count and display clipped samples\n"); fprintf(o," -v[*] --verbose increase verboselevel\n"); fprintf(o," -q --quiet quiet mode\n"); #ifdef HAVE_TERMIOS fprintf(o," -C --control enable terminal control keys\n"); fprintf(o," --ctrlusr1 <c> control key (characer) to map to SIGUSR1\n"); fprintf(o," (default is for stop/start)\n"); fprintf(o," --ctrlusr2 <c> control key (characer) to map to SIGUSR2\n"); fprintf(o," (default is for next track)\n"); #endif #ifndef GENERIC fprintf(o," --title set terminal title to filename\n"); #endif fprintf(o," --long-tag spacy id3 display with every item on a separate line\n"); fprintf(o," --lyrics show lyrics (from ID3v2 USLT frame)\n"); fprintf(o," --utf8 Regardless of environment, print metadata in UTF-8.\n"); fprintf(o," -R --remote generic remote interface\n"); fprintf(o," --remote-err force use of stderr for generic remote interface\n"); #ifdef FIFO fprintf(o," --fifo <path> open a FIFO at <path> for commands instead of stdin\n"); #endif #ifdef HAVE_SETPRIORITY fprintf(o," --aggressive tries to get higher priority (nice)\n"); #endif #if defined (HAVE_SCHED_SETSCHEDULER) || defined (HAVE_WINDOWS_H) fprintf(o," -T --realtime tries to get realtime priority\n"); #endif #ifdef HAVE_WINDOWS_H fprintf(o," --priority <n> use specified process priority\n"); fprintf(o," accepts -2 to 3 as integer arguments\n"); fprintf(o," -2 as idle, 0 as normal and 3 as realtime.\n"); #endif fprintf(o," -? --help give compact help\n"); fprintf(o," --longhelp give this long help listing\n"); fprintf(o," --version give name / version string\n"); fprintf(o,"\nSee the manpage "PACKAGE_NAME"(1) for more information.\n"); safe_exit(err); }
int main(int sys_argc, char ** sys_argv) { int result; char end_of_files = FALSE; long parr; char *fname; int libpar = 0; mpg123_pars *mp; #if !defined(WIN32) && !defined(GENERIC) struct timeval start_time; #endif aux_out = stdout; /* Need to initialize here because stdout is not a constant?! */ #if defined (WANT_WIN32_UNICODE) if(win32_cmdline_utf8(&argc, &argv) != 0) { error("Cannot convert command line to UTF8!"); safe_exit(76); } #else argv = sys_argv; argc = sys_argc; #endif #if defined (WANT_WIN32_SOCKETS) win32_net_init(); #endif if(!(fullprogname = strdup(argv[0]))) { error("OOM"); /* Out Of Memory. Don't waste bytes on that error. */ safe_exit(1); } /* Extract binary and path, take stuff before/after last / or \ . */ if( (prgName = strrchr(fullprogname, '/')) || (prgName = strrchr(fullprogname, '\\'))) { /* There is some explicit path. */ prgName[0] = 0; /* End byte for path. */ prgName++; binpath = fullprogname; } else { prgName = fullprogname; /* No path separators there. */ binpath = NULL; /* No path at all. */ } /* Need to initialize mpg123 lib here for default parameter values. */ result = mpg123_init(); if(result != MPG123_OK) { error1("Cannot initialize mpg123 library: %s", mpg123_plain_strerror(result)); safe_exit(77); } cleanup_mpg123 = TRUE; mp = mpg123_new_pars(&result); /* This may get leaked on premature exit(), which is mainly a cosmetic issue... */ if(mp == NULL) { error1("Crap! Cannot get mpg123 parameters: %s", mpg123_plain_strerror(result)); safe_exit(78); } /* get default values */ mpg123_getpar(mp, MPG123_DOWN_SAMPLE, &parr, NULL); param.down_sample = (int) parr; mpg123_getpar(mp, MPG123_RVA, ¶m.rva, NULL); mpg123_getpar(mp, MPG123_DOWNSPEED, ¶m.halfspeed, NULL); mpg123_getpar(mp, MPG123_UPSPEED, ¶m.doublespeed, NULL); mpg123_getpar(mp, MPG123_OUTSCALE, ¶m.outscale, NULL); mpg123_getpar(mp, MPG123_FLAGS, &parr, NULL); mpg123_getpar(mp, MPG123_INDEX_SIZE, ¶m.index_size, NULL); param.flags = (int) parr; param.flags |= MPG123_SEEKBUFFER; /* Default on, for HTTP streams. */ mpg123_getpar(mp, MPG123_RESYNC_LIMIT, ¶m.resync_limit, NULL); mpg123_getpar(mp, MPG123_PREFRAMES, ¶m.preframes, NULL); #ifdef OS2 _wildcard(&argc,&argv); #endif while ((result = getlopt(argc, argv, opts))) switch (result) { case GLO_UNKNOWN: fprintf (stderr, "%s: Unknown option \"%s\".\n", prgName, loptarg); usage(1); case GLO_NOARG: fprintf (stderr, "%s: Missing argument for option \"%s\".\n", prgName, loptarg); usage(1); } /* Do this _after_ parameter parsing. */ check_locale(); /* Check/set locale; store if it uses UTF-8. */ if(param.list_cpu) { const char **all_dec = mpg123_decoders(); printf("Builtin decoders:"); while(*all_dec != NULL){ printf(" %s", *all_dec); ++all_dec; } printf("\n"); mpg123_delete_pars(mp); return 0; } if(param.test_cpu) { const char **all_dec = mpg123_supported_decoders(); printf("Supported decoders:"); while(*all_dec != NULL){ printf(" %s", *all_dec); ++all_dec; } printf("\n"); mpg123_delete_pars(mp); return 0; } if(param.gain != -1) { warning("The parameter -g is deprecated and may be removed in the future."); } if (loptind >= argc && !param.listname && !param.remote) usage(1); /* Init audio as early as possible. If there is the buffer process to be spawned, it shouldn't carry the mpg123_handle with it. */ bufferblock = mpg123_safe_buffer(); /* Can call that before mpg123_init(), it's stateless. */ if(init_output(&ao) < 0) { error("Failed to initialize output, goodbye."); mpg123_delete_pars(mp); return 99; /* It's safe here... nothing nasty happened yet. */ } have_output = TRUE; /* ========================================================================================================= */ /* Enterning the leaking zone... we start messing with stuff here that should be taken care of when leaving. */ /* Don't just exit() or return out... */ /* ========================================================================================================= */ httpdata_init(&htd); #if !defined(WIN32) && !defined(GENERIC) if (param.remote) { param.verbose = 0; param.quiet = 1; param.flags |= MPG123_QUIET; } #endif /* Set the frame parameters from command line options */ if(param.quiet) param.flags |= MPG123_QUIET; #ifdef OPT_3DNOW if(dnow != 0) param.cpu = (dnow == SET_3DNOW) ? "3dnow" : "i586"; #endif if(param.cpu != NULL && (!strcmp(param.cpu, "auto") || !strcmp(param.cpu, ""))) param.cpu = NULL; if(!( MPG123_OK == (result = mpg123_par(mp, MPG123_VERBOSE, param.verbose, 0)) && ++libpar && MPG123_OK == (result = mpg123_par(mp, MPG123_FLAGS, param.flags, 0)) && ++libpar && MPG123_OK == (result = mpg123_par(mp, MPG123_DOWN_SAMPLE, param.down_sample, 0)) && ++libpar && MPG123_OK == (result = mpg123_par(mp, MPG123_RVA, param.rva, 0)) && ++libpar && MPG123_OK == (result = mpg123_par(mp, MPG123_FORCE_RATE, param.force_rate, 0)) && ++libpar && MPG123_OK == (result = mpg123_par(mp, MPG123_DOWNSPEED, param.halfspeed, 0)) && ++libpar && MPG123_OK == (result = mpg123_par(mp, MPG123_UPSPEED, param.doublespeed, 0)) && ++libpar && MPG123_OK == (result = mpg123_par(mp, MPG123_ICY_INTERVAL, 0, 0)) && ++libpar && MPG123_OK == (result = mpg123_par(mp, MPG123_RESYNC_LIMIT, param.resync_limit, 0)) && ++libpar && MPG123_OK == (result = mpg123_par(mp, MPG123_TIMEOUT, param.timeout, 0)) && ++libpar && MPG123_OK == (result = mpg123_par(mp, MPG123_OUTSCALE, param.outscale, 0)) && ++libpar && MPG123_OK == (result = mpg123_par(mp, MPG123_PREFRAMES, param.preframes, 0)) )) { error2("Cannot set library parameter %i: %s", libpar, mpg123_plain_strerror(result)); safe_exit(45); } if (!(param.listentry < 0) && !param.quiet) print_title(stderr); /* do not pollute stdout! */ { long default_index; mpg123_getpar(mp, MPG123_INDEX_SIZE, &default_index, NULL); if( param.index_size != default_index && (result = mpg123_par(mp, MPG123_INDEX_SIZE, param.index_size, 0.)) != MPG123_OK ) error1("Setting of frame index size failed: %s", mpg123_plain_strerror(result)); } if(param.force_rate && param.down_sample) { error("Down sampling and fixed rate options not allowed together!"); safe_exit(1); } /* Now actually get an mpg123_handle. */ mh = mpg123_parnew(mp, param.cpu, &result); if(mh == NULL) { error1("Crap! Cannot get a mpg123 handle: %s", mpg123_plain_strerror(result)); safe_exit(77); } mpg123_delete_pars(mp); /* Don't need the parameters anymore ,they're in the handle now. */ /* Prepare stream dumping, possibly replacing mpg123 reader. */ if(dump_open(mh) != 0) safe_exit(78); /* Now either check caps myself or query buffer for that. */ audio_capabilities(ao, mh); load_equalizer(mh); #ifdef HAVE_SETPRIORITY if(param.aggressive) { /* tst */ int mypid = getpid(); if(!param.quiet) fprintf(stderr,"Aggressively trying to increase priority.\n"); if(setpriority(PRIO_PROCESS,mypid,-20)) error("Failed to aggressively increase priority.\n"); } #endif #if defined (HAVE_SCHED_SETSCHEDULER) && !defined (__CYGWIN__) && !defined (HAVE_WINDOWS_H) /* Cygwin --realtime seems to fail when accessing network, using win32 set priority instead */ /* MinGW may have pthread installed, we prefer win32API */ if (param.realtime) { /* Get real-time priority */ struct sched_param sp; fprintf(stderr,"Getting real-time priority\n"); memset(&sp, 0, sizeof(struct sched_param)); sp.sched_priority = sched_get_priority_min(SCHED_FIFO); if (sched_setscheduler(0, SCHED_RR, &sp) == -1) error("Can't get realtime priority\n"); } #endif /* make sure not Cygwin, it doesn't need it */ #if defined(WIN32) && defined(HAVE_WINDOWS_H) /* argument "3" is equivalent to realtime priority class */ win32_set_priority( param.realtime ? 3 : param.w32_priority); #endif if(!param.remote) prepare_playlist(argc, argv); #if !defined(WIN32) && !defined(GENERIC) /* Remote mode is special... but normal console and terminal-controlled operation needs to catch the SIGINT. For one it serves for track skip when not in terminal control mode. The more important use being a graceful exit, including telling the buffer process what's going on. */ if(!param.remote) catchsignal (SIGINT, catch_interrupt); #endif if(param.remote) { int ret; ret = control_generic(mh); safe_exit(ret); } #ifdef HAVE_TERMIOS debug1("param.term_ctrl: %i", param.term_ctrl); if(param.term_ctrl) term_init(); #endif if(APPFLAG(MPG123APP_CONTINUE)) frames_left = param.frame_number; while ((fname = get_next_file())) { char *dirname, *filename; int newdir; /* skip_tracks includes the previous one. */ if(skip_tracks) --skip_tracks; if(skip_tracks) { debug("Skipping this track."); continue; } if(param.delay > 0) { /* One should enable terminal control during that sleeping phase! */ if(param.verbose > 2) fprintf(stderr, "Note: pausing %i seconds before next track.\n", param.delay); output_pause(ao); #ifdef WIN32 Sleep(param.delay*1000); #else sleep(param.delay); #endif output_unpause(ao); } if(!APPFLAG(MPG123APP_CONTINUE)) frames_left = param.frame_number; debug1("Going to play %s", strcmp(fname, "-") ? fname : "standard input"); if(intflag || !open_track(fname)) { #ifdef HAVE_TERMIOS /* We need the opportunity to cancel in case of --loop -1 . */ if(param.term_ctrl) term_control(mh, ao); else #endif /* No wait for a second interrupt before we started playing. */ if(intflag) break; /* We already interrupted this cycle, start fresh with the next one. */ intflag = FALSE; continue; } if(!param.quiet) fprintf(stderr, "\n"); if(param.index) { if(param.verbose) fprintf(stderr, "indexing...\r"); mpg123_scan(mh); } /* Only trigger a seek if we do not want to start with the first frame. Rationale: Because of libmpg123 sample accuracy, this could cause an unnecessary backwards seek, that even may fail on non-seekable streams. For start frame of 0, we are already at the correct position! */ framenum = 0; if(param.start_frame > 0) framenum = mpg123_seek_frame(mh, param.start_frame, SEEK_SET); if(APPFLAG(MPG123APP_CONTINUE)) param.start_frame = 0; if(framenum < 0) { error1("Initial seek failed: %s", mpg123_strerror(mh)); if(mpg123_errcode(mh) == MPG123_BAD_OUTFORMAT) { fprintf(stderr, "%s", "So, you have trouble getting an output format... this is the matrix of currently possible formats:\n"); print_capabilities(ao, mh); fprintf(stderr, "%s", "Somehow the input data and your choices don't allow one of these.\n"); } mpg123_close(mh); continue; } /* Prinout and xterm title need this, possibly independently. */ newdir = split_dir_file(fname ? fname : "standard input", &dirname, &filename); if (!param.quiet) { if(newdir) fprintf(stderr, "Directory: %s\n", dirname); #ifdef HAVE_TERMIOS /* Reminder about terminal usage. */ if(param.term_ctrl) term_hint(); #endif fprintf(stderr, "Playing MPEG stream %lu of %lu: %s ...\n", (unsigned long)pl.pos, (unsigned long)pl.fill, filename); if(htd.icy_name.fill) fprintf(stderr, "ICY-NAME: %s\n", htd.icy_name.p); if(htd.icy_url.fill) fprintf(stderr, "ICY-URL: %s\n", htd.icy_url.p); } #if !defined(GENERIC) { const char *term_type; term_type = getenv("TERM"); if(term_type && param.xterm_title) { if(!strncmp(term_type,"xterm",5) || !strncmp(term_type,"rxvt",4)) fprintf(stderr, "\033]0;%s\007", filename); else if(!strncmp(term_type,"screen",6)) fprintf(stderr, "\033k%s\033\\", filename); else if(!strncmp(term_type,"iris-ansi",9)) fprintf(stderr, "\033P1.y %s\033\\\033P3.y%s\033\\", filename, filename); fflush(stderr); /* Paranoia: will the buffer buffer the escapes? */ } } #endif /* Rethink that SIGINT logic... */ #if !defined(WIN32) && !defined(GENERIC) #ifdef HAVE_TERMIOS if(!param.term_ctrl) #endif gettimeofday (&start_time, NULL); #endif while(!intflag) { int meta; if(param.frame_number > -1) { debug1("frames left: %li", (long) frames_left); if(!frames_left) { if(APPFLAG(MPG123APP_CONTINUE)) end_of_files = TRUE; break; } } if(!play_frame()) break; if(!param.quiet) { meta = mpg123_meta_check(mh); if(meta & (MPG123_NEW_ID3|MPG123_NEW_ICY)) { if(meta & MPG123_NEW_ID3) print_id3_tag(mh, param.long_id3, stderr); if(meta & MPG123_NEW_ICY) print_icy(mh, stderr); mpg123_meta_free(mh); /* Do not waste memory after delivering. */ } } if(!fresh && param.verbose) { #ifndef NOXFERMEM if (param.verbose > 1 || !(framenum & 0x7)) print_stat(mh,0,xfermem_get_usedspace(buffermem)); #else if(param.verbose > 1 || !(framenum & 0x7)) print_stat(mh,0,0); #endif } #ifdef HAVE_TERMIOS if(!param.term_ctrl) continue; else term_control(mh, ao); #endif } if(!param.smooth && param.usebuffer) buffer_drain(); if(param.verbose) print_stat(mh,0,xfermem_get_usedspace(buffermem)); if(!param.quiet) { double secs; long frank; fprintf(stderr, "\n"); if(mpg123_getstate(mh, MPG123_FRANKENSTEIN, &frank, NULL) == MPG123_OK && frank) fprintf(stderr, "This was a Frankenstein track.\n"); mpg123_position(mh, 0, 0, NULL, NULL, &secs, NULL); fprintf(stderr,"[%d:%02d] Decoding of %s finished.\n", (int)(secs / 60), ((int)secs) % 60, filename); } else if(param.verbose) fprintf(stderr, "\n"); close_track(); if (intflag) { if(!skip_or_die(&start_time)) break; intflag = FALSE; #ifndef NOXFERMEM if(!param.smooth && param.usebuffer) buffer_resync(); #endif } if(end_of_files) break; } /* end of loop over input files */ /* Ensure we played everything. */ if(param.smooth && param.usebuffer) { buffer_drain(); buffer_resync(); } if(APPFLAG(MPG123APP_CONTINUE)) { continue_msg("CONTINUE"); } /* Free up memory used by playlist */ if(!param.remote) free_playlist(); safe_exit(0); /* That closes output and restores terminal, too. */ return 0; }
int main (int argc, char *argv[]) { setlocale (LC_ALL, ""); bindtextdomain (PACKAGE, LOCALEBASEDIR); textdomain (PACKAGE); enum { HELP_OPTION = CHAR_MAX + 1 }; static const char *options = "a:c:d:hiP:vVx"; static const struct option long_options[] = { { "add", 1, 0, 'a' }, { "connect", 1, 0, 'c' }, { "csv", 0, 0, 0 }, { "domain", 1, 0, 'd' }, { "format", 2, 0, 0 }, { "help", 0, 0, HELP_OPTION }, { "human-readable", 0, 0, 'h' }, { "inodes", 0, 0, 'i' }, { "long-options", 0, 0, 0 }, { "one-per-guest", 0, 0, 0 }, { "uuid", 0, 0, 0 }, { "verbose", 0, 0, 'v' }, { "version", 0, 0, 'V' }, { 0, 0, 0, 0 } }; struct drv *drvs = NULL; struct drv *drv; const char *format = NULL; bool format_consumed = true; int c; int option_index; size_t max_threads = 0; int err; g = guestfs_create (); if (g == NULL) { fprintf (stderr, _("guestfs_create: failed to create handle\n")); exit (EXIT_FAILURE); } for (;;) { c = getopt_long (argc, argv, options, long_options, &option_index); if (c == -1) break; switch (c) { case 0: /* options which are long only */ if (STREQ (long_options[option_index].name, "long-options")) display_long_options (long_options); else if (STREQ (long_options[option_index].name, "format")) { OPTION_format; } else if (STREQ (long_options[option_index].name, "csv")) { csv = 1; } else if (STREQ (long_options[option_index].name, "one-per-guest")) { /* nothing - left for backwards compatibility */ } else if (STREQ (long_options[option_index].name, "uuid")) { uuid = 1; } else { fprintf (stderr, _("%s: unknown long option: %s (%d)\n"), program_name, long_options[option_index].name, option_index); exit (EXIT_FAILURE); } break; case 'a': OPTION_a; break; case 'c': OPTION_c; break; case 'd': OPTION_d; break; case 'h': human = 1; break; case 'i': inodes = 1; break; case 'P': if (sscanf (optarg, "%zu", &max_threads) != 1) { fprintf (stderr, _("%s: -P option is not numeric\n"), program_name); exit (EXIT_FAILURE); } break; case 'v': OPTION_v; break; case 'V': OPTION_V; break; case 'x': OPTION_x; break; case HELP_OPTION: usage (EXIT_SUCCESS); default: usage (EXIT_FAILURE); } } /* Old-style syntax? There were no -a or -d options in the old * virt-df which is how we detect this. */ if (drvs == NULL) { while (optind < argc) { if (strchr (argv[optind], '/') || access (argv[optind], F_OK) == 0) { /* simulate -a option */ drv = calloc (1, sizeof (struct drv)); if (!drv) { perror ("malloc"); exit (EXIT_FAILURE); } drv->type = drv_a; drv->a.filename = strdup (argv[optind]); if (!drv->a.filename) { perror ("strdup"); exit (EXIT_FAILURE); } drv->next = drvs; drvs = drv; } else { /* simulate -d option */ drv = calloc (1, sizeof (struct drv)); if (!drv) { perror ("malloc"); exit (EXIT_FAILURE); } drv->type = drv_d; drv->d.guest = argv[optind]; drv->next = drvs; drvs = drv; } optind++; } } /* These are really constants, but they have to be variables for the * options parsing code. Assert here that they have known-good * values. */ assert (read_only == 1); assert (inspector == 0); assert (live == 0); /* Must be no extra arguments on the command line. */ if (optind != argc) usage (EXIT_FAILURE); CHECK_OPTION_format_consumed; /* -h and --csv doesn't make sense. Spreadsheets will corrupt these * fields. (RHBZ#600977). */ if (human && csv) { fprintf (stderr, _("%s: you cannot use -h and --csv options together.\n"), program_name); exit (EXIT_FAILURE); } /* virt-df has two modes. If the user didn't specify any drives, * then we do the df on every libvirt guest. That's the if-clause * below. If the user specified domains/drives, then we assume they * belong to a single guest. That's the else-clause below. */ if (drvs == NULL) { #if defined(HAVE_LIBVIRT) get_all_libvirt_domains (libvirt_uri); print_title (); err = start_threads (max_threads, g, df_work); free_domains (); #else fprintf (stderr, _("%s: compiled without support for libvirt.\n"), program_name); exit (EXIT_FAILURE); #endif } else { /* Single guest. */ CLEANUP_FREE char *name = NULL; /* Add domains/drives from the command line (for a single guest). */ add_drives (drvs, 'a'); if (guestfs_launch (g) == -1) exit (EXIT_FAILURE); print_title (); /* Synthesize a display name. */ name = make_display_name (drvs); /* XXX regression: in the Perl version we cached the UUID from the * libvirt domain handle so it was available to us here. In this * version the libvirt domain handle is hidden inside * guestfs_add_domain so the UUID is not available easily for * single '-d' command-line options. */ err = df_on_handle (g, name, NULL, stdout); /* Free up data structures, no longer needed after this point. */ free_drives (drvs); } guestfs_close (g); exit (err == 0 ? EXIT_SUCCESS : EXIT_FAILURE); }
/* * Display a dialog box with a list of options that can be turned on or off * in the style of radiolist (only one option turned on at a time). */ int dialog_checklist(const char *title, const char *prompt, int height, int width, int list_height) { int i, x, y, box_x, box_y; int key = 0, button = 0, choice = 0, scroll = 0, max_choice; WINDOW *dialog, *list; /* which item to highlight */ item_foreach() { if (item_is_tag('X')) choice = item_n(); if (item_is_selected()) { choice = item_n(); break; } } do_resize: if (getmaxy(stdscr) < (height + 6)) return -ERRDISPLAYTOOSMALL; if (getmaxx(stdscr) < (width + 6)) return -ERRDISPLAYTOOSMALL; max_choice = MIN(list_height, item_count()); /* center dialog box on screen */ x = (COLS - width) / 2; y = (LINES - height) / 2; draw_shadow(stdscr, y, x, height, width); dialog = newwin(height, width, y, x); keypad(dialog, TRUE); draw_box(dialog, 0, 0, height, width, dlg.dialog.atr, dlg.border.atr); wattrset(dialog, dlg.border.atr); mvwaddch(dialog, height - 3, 0, ACS_LTEE); for (i = 0; i < width - 2; i++) waddch(dialog, ACS_HLINE); wattrset(dialog, dlg.dialog.atr); waddch(dialog, ACS_RTEE); print_title(dialog, title, width); wattrset(dialog, dlg.dialog.atr); print_autowrap(dialog, prompt, width - 2, 1, 3); list_width = width - 6; box_y = height - list_height - 5; box_x = (width - list_width) / 2 - 1; /* create new window for the list */ list = subwin(dialog, list_height, list_width, y + box_y + 1, x + box_x + 1); keypad(list, TRUE); /* draw a box around the list items */ draw_box(dialog, box_y, box_x, list_height + 2, list_width + 2, dlg.menubox_border.atr, dlg.menubox.atr); /* Find length of longest item in order to center checklist */ check_x = 0; item_foreach() check_x = MAX(check_x, strlen(item_str()) + 4); check_x = (list_width - check_x) / 2; item_x = check_x + 4; if (choice >= list_height) { scroll = choice - list_height + 1; choice -= scroll; } /* Print the list */ for (i = 0; i < max_choice; i++) { item_set(scroll + i); print_item(list, i, i == choice); } print_arrows(dialog, choice, item_count(), scroll, box_y, box_x + check_x + 5, list_height); print_buttons(dialog, height, width, 0); wnoutrefresh(dialog); wnoutrefresh(list); doupdate(); while (key != KEY_ESC) { key = wgetch(dialog); for (i = 0; i < max_choice; i++) { item_set(i + scroll); if (toupper(key) == toupper(item_str()[0])) break; } if (i < max_choice || key == KEY_UP || key == KEY_DOWN || key == '+' || key == '-') { if (key == KEY_UP || key == '-') { if (!choice) { if (!scroll) continue; /* Scroll list down */ if (list_height > 1) { /* De-highlight current first item */ item_set(scroll); print_item(list, 0, FALSE); scrollok(list, TRUE); wscrl(list, -1); scrollok(list, FALSE); } scroll--; item_set(scroll); print_item(list, 0, TRUE); print_arrows(dialog, choice, item_count(), scroll, box_y, box_x + check_x + 5, list_height); wnoutrefresh(dialog); wrefresh(list); continue; /* wait for another key press */ } else i = choice - 1; } else if (key == KEY_DOWN || key == '+') { if (choice == max_choice - 1) { if (scroll + choice >= item_count() - 1) continue; /* Scroll list up */ if (list_height > 1) { /* De-highlight current last item before scrolling up */ item_set(scroll + max_choice - 1); print_item(list, max_choice - 1, FALSE); scrollok(list, TRUE); wscrl(list, 1); scrollok(list, FALSE); } scroll++; item_set(scroll + max_choice - 1); print_item(list, max_choice - 1, TRUE); print_arrows(dialog, choice, item_count(), scroll, box_y, box_x + check_x + 5, list_height); wnoutrefresh(dialog); wrefresh(list); continue; /* wait for another key press */ } else i = choice + 1; } if (i != choice) { /* De-highlight current item */ item_set(scroll + choice); print_item(list, choice, FALSE); /* Highlight new item */ choice = i; item_set(scroll + choice); print_item(list, choice, TRUE); wnoutrefresh(dialog); wrefresh(list); } continue; /* wait for another key press */ } switch (key) { case 'H': case 'h': case '?': button = 1; /* fall-through */ case 'S': case 's': case ' ': case '\n': item_foreach() item_set_selected(0); item_set(scroll + choice); item_set_selected(1); delwin(list); delwin(dialog); return button; case TAB: case KEY_LEFT: case KEY_RIGHT: button = ((key == KEY_LEFT ? --button : ++button) < 0) ? 1 : (button > 1 ? 0 : button); print_buttons(dialog, height, width, button); wrefresh(dialog); break; case 'X': case 'x': key = KEY_ESC; break; case KEY_ESC: key = on_key_esc(dialog); break; case KEY_RESIZE: delwin(list); delwin(dialog); on_key_resize(); goto do_resize; } /* Now, update everything... */ doupdate(); } delwin(list); delwin(dialog); return key; /* ESC pressed */ }
void area(const osmium::Area& area) { print_title("AREA", area); print_meta(area); }
int main(int argc, char * argv[]) { int k,baseLength; int whichReply[NUMKEYWORDS]; char lastinput[MAXLINELEN]; char reply[MAXLINELEN]; char *baseResponse, *token; const char separator[2]=" "; char inputstr[MAXLINELEN]; // use the first reply for each keyword match the first time you see that keyword for (int x=0;x< NUMKEYWORDS; x++) { whichReply[x] = 0; } // print a nice centered title screen print_title(); lastinput[0]='\0'; while (1) { readline(inputstr); // check for termination if (strcmp(inputstr,"BYE")==0) break; // check for repeated entries if (strcmp(lastinput,inputstr)==0) { printf("PLEASE DON'T REPEAT YOURSELF!\n"); continue; } strncpy(lastinput,inputstr,strlen(inputstr)+1); // see if any of the keywords is contained in the input // if not, we use the last element of keywords as our default responses char *location; strcpy(reply,""); for(k=0;k<NUMKEYWORDS-1;k++) { location=strstr(inputstr, keywords[k]); if(location != NULL) break; } // Build Eliza's response // start with Eliza's canned response, based on the keyword match baseResponse = (char *) responses[k][whichReply[k]]; baseLength = strlen(baseResponse); if(baseResponse[baseLength-1] != '*') { // if we have a baseResponse without an asterix, just use it as-is strcat(reply, baseResponse); } else { // if we do have an asterix, fill in the remaining with the user input // use all but the last character of the base response strncat(reply, baseResponse, baseLength-1); // now add in the rest of the user's input, starting at <location> // but skip over the keyword itself location+=strlen(keywords[k]); // take them one word at a time, so that we can substitute pronouns token = strtok(location, separator); while(token != NULL) { for(int s=0;s<NUMSWAPS;s++) { if(strcmp(SWAPS[s][0], token) == 0) { token = (char *) SWAPS[s][1]; break; } } strcat(reply," "); strcat(reply, token); token=strtok(NULL, separator); }; strcat(reply, "?"); } printf("%s\n", reply); // next time, use the next appropriate reply for that keyword whichReply[k]++; if ( whichReply[k] >= ResponsesPerKeyword[k]) whichReply[k] = 0; } printf( "GOODBYE! THANKS FOR VISITING WITH ME...\n"); }
/* * Display a dialog box with a list of options that can be turned on or off * in the style of radiolist (only one option turned on at a time). */ int dialog_checklist(const char *title, const char *prompt, int height, int width, int list_height, int item_no, const char *const *items) { int i, x, y, box_x, box_y; int key = 0, button = 0, choice = 0, scroll = 0, max_choice, *status; WINDOW *dialog, *list; /* Allocate space for storing item on/off status */ if ((status = malloc(sizeof(int) * item_no)) == NULL) { endwin(); fprintf(stderr, "\nCan't allocate memory in dialog_checklist().\n"); exit(-1); } /* Initializes status */ for (i = 0; i < item_no; i++) { status[i] = !strcasecmp(items[i * 3 + 2], "on"); if ((!choice && status[i]) || !strcasecmp(items[i * 3 + 2], "selected")) choice = i + 1; } if (choice) choice--; max_choice = MIN(list_height, item_no); /* center dialog box on screen */ x = (COLS - width) / 2; y = (LINES - height) / 2; draw_shadow(stdscr, y, x, height, width); dialog = newwin(height, width, y, x); keypad(dialog, TRUE); draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr); wattrset(dialog, border_attr); mvwaddch(dialog, height - 3, 0, ACS_LTEE); for (i = 0; i < width - 2; i++) waddch(dialog, ACS_HLINE); wattrset(dialog, dialog_attr); waddch(dialog, ACS_RTEE); print_title(dialog, title, width); wattrset(dialog, dialog_attr); print_autowrap(dialog, prompt, width - 2, 1, 3); list_width = width - 6; box_y = height - list_height - 5; box_x = (width - list_width) / 2 - 1; /* create new window for the list */ list = subwin(dialog, list_height, list_width, y + box_y + 1, x + box_x + 1); keypad(list, TRUE); /* draw a box around the list items */ draw_box(dialog, box_y, box_x, list_height + 2, list_width + 2, menubox_border_attr, menubox_attr); /* Find length of longest item in order to center checklist */ check_x = 0; for (i = 0; i < item_no; i++) check_x = MAX(check_x, +strlen(items[i * 3 + 1]) + 4); check_x = (list_width - check_x) / 2; item_x = check_x + 4; if (choice >= list_height) { scroll = choice - list_height + 1; choice -= scroll; } /* Print the list */ for (i = 0; i < max_choice; i++) { print_item(list, items[(scroll + i) * 3 + 1], status[i + scroll], i, i == choice); } print_arrows(dialog, choice, item_no, scroll, box_y, box_x + check_x + 5, list_height); print_buttons(dialog, height, width, 0); wnoutrefresh(dialog); wnoutrefresh(list); doupdate(); while (key != ESC) { key = wgetch(dialog); for (i = 0; i < max_choice; i++) if (toupper(key) == toupper(items[(scroll + i) * 3 + 1][0])) break; if (i < max_choice || key == KEY_UP || key == KEY_DOWN || key == '+' || key == '-') { if (key == KEY_UP || key == '-') { if (!choice) { if (!scroll) continue; /* Scroll list down */ if (list_height > 1) { /* De-highlight current first item */ print_item(list, items[scroll * 3 + 1], status[scroll], 0, FALSE); scrollok(list, TRUE); wscrl(list, -1); scrollok(list, FALSE); } scroll--; print_item(list, items[scroll * 3 + 1], status[scroll], 0, TRUE); print_arrows(dialog, choice, item_no, scroll, box_y, box_x + check_x + 5, list_height); wnoutrefresh(dialog); wrefresh(list); continue; /* wait for another key press */ } else i = choice - 1; } else if (key == KEY_DOWN || key == '+') { if (choice == max_choice - 1) { if (scroll + choice >= item_no - 1) continue; /* Scroll list up */ if (list_height > 1) { /* De-highlight current last item before scrolling up */ print_item(list, items[(scroll + max_choice - 1) * 3 + 1], status[scroll + max_choice - 1], max_choice - 1, FALSE); scrollok(list, TRUE); wscrl(list, 1); scrollok(list, FALSE); } scroll++; print_item(list, items[(scroll + max_choice - 1) * 3 + 1], status[scroll + max_choice - 1], max_choice - 1, TRUE); print_arrows(dialog, choice, item_no, scroll, box_y, box_x + check_x + 5, list_height); wnoutrefresh(dialog); wrefresh(list); continue; /* wait for another key press */ } else i = choice + 1; } if (i != choice) { /* De-highlight current item */ print_item(list, items[(scroll + choice) * 3 + 1], status[scroll + choice], choice, FALSE); /* Highlight new item */ choice = i; print_item(list, items[(scroll + choice) * 3 + 1], status[scroll + choice], choice, TRUE); wnoutrefresh(dialog); wrefresh(list); } continue; /* wait for another key press */ } switch (key) { case 'H': case 'h': case '?': fprintf(stderr, "%s", items[(scroll + choice) * 3]); delwin(dialog); free(status); return 1; case TAB: case KEY_LEFT: case KEY_RIGHT: button = ((key == KEY_LEFT ? --button : ++button) < 0) ? 1 : (button > 1 ? 0 : button); print_buttons(dialog, height, width, button); wrefresh(dialog); break; case 'S': case 's': case ' ': case '\n': if (!button) { if (!status[scroll + choice]) { for (i = 0; i < item_no; i++) status[i] = 0; status[scroll + choice] = 1; for (i = 0; i < max_choice; i++) print_item(list, items[(scroll + i) * 3 + 1], status[scroll + i], i, i == choice); } wnoutrefresh(dialog); wrefresh(list); for (i = 0; i < item_no; i++) if (status[i]) fprintf(stderr, "%s", items[i * 3]); } else fprintf(stderr, "%s", items[(scroll + choice) * 3]); delwin(dialog); free(status); return button; case 'X': case 'x': key = ESC; case ESC: break; } /* Now, update everything... */ doupdate(); } delwin(dialog); free(status); return -1; /* ESC pressed */ }
/* * Display text from a file in a dialog box. */ int dialog_textbox(const char *title, const char *tbuf, int initial_height, int initial_width) { int i, x, y, cur_x, cur_y, key = 0; int height, width, boxh, boxw; int passed_end; WINDOW *dialog, *box; begin_reached = 1; end_reached = 0; page_length = 0; hscroll = 0; buf = tbuf; page = buf; /* page is pointer to start of page to be displayed */ do_resize: getmaxyx(stdscr, height, width); if (height < 8 || width < 8) return -ERRDISPLAYTOOSMALL; if (initial_height != 0) height = initial_height; else if (height > 4) height -= 4; else height = 0; if (initial_width != 0) width = initial_width; else if (width > 5) width -= 5; else width = 0; /* center dialog box on screen */ x = (getmaxx(stdscr) - width) / 2; y = (getmaxy(stdscr) - height) / 2; draw_shadow(stdscr, y, x, height, width); dialog = newwin(height, width, y, x); keypad(dialog, TRUE); /* Create window for box region, used for scrolling text */ boxh = height - 4; boxw = width - 2; box = subwin(dialog, boxh, boxw, y + 1, x + 1); wattrset(box, dlg.dialog.atr); wbkgdset(box, dlg.dialog.atr & A_COLOR); keypad(box, TRUE); /* register the new window, along with its borders */ draw_box(dialog, 0, 0, height, width, dlg.dialog.atr, dlg.border.atr); wattrset(dialog, dlg.border.atr); mvwaddch(dialog, height - 3, 0, ACS_LTEE); for (i = 0; i < width - 2; i++) waddch(dialog, ACS_HLINE); wattrset(dialog, dlg.dialog.atr); wbkgdset(dialog, dlg.dialog.atr & A_COLOR); waddch(dialog, ACS_RTEE); print_title(dialog, title, width); print_button(dialog, gettext(" Exit "), height - 2, width / 2 - 4, TRUE); wnoutrefresh(dialog); getyx(dialog, cur_y, cur_x); /* Save cursor position */ /* Print first page of text */ attr_clear(box, boxh, boxw, dlg.dialog.atr); refresh_text_box(dialog, box, boxh, boxw, cur_y, cur_x); while ((key != KEY_ESC) && (key != '\n')) { key = wgetch(dialog); switch (key) { case 'E': /* Exit */ case 'e': case 'X': case 'x': delwin(box); delwin(dialog); return 0; case 'g': /* First page */ case KEY_HOME: if (!begin_reached) { begin_reached = 1; page = buf; refresh_text_box(dialog, box, boxh, boxw, cur_y, cur_x); } break; case 'G': /* Last page */ case KEY_END: end_reached = 1; /* point to last char in buf */ page = buf + strlen(buf); back_lines(boxh); refresh_text_box(dialog, box, boxh, boxw, cur_y, cur_x); break; case 'K': /* Previous line */ case 'k': case KEY_UP: if (!begin_reached) { back_lines(page_length + 1); /* We don't call print_page() here but use * scrolling to ensure faster screen update. * However, 'end_reached' and 'page_length' * should still be updated, and 'page' should * point to start of next page. This is done * by calling get_line() in the following * 'for' loop. */ scrollok(box, TRUE); wscrl(box, -1); /* Scroll box region down one line */ scrollok(box, FALSE); page_length = 0; passed_end = 0; for (i = 0; i < boxh; i++) { if (!i) { /* print first line of page */ print_line(box, 0, boxw); wnoutrefresh(box); } else /* Called to update 'end_reached' and 'page' */ get_line(); if (!passed_end) page_length++; if (end_reached && !passed_end) passed_end = 1; } print_position(dialog); wmove(dialog, cur_y, cur_x); /* Restore cursor position */ wrefresh(dialog); } break; case 'B': /* Previous page */ case 'b': case KEY_PPAGE: if (begin_reached) break; back_lines(page_length + boxh); refresh_text_box(dialog, box, boxh, boxw, cur_y, cur_x); break; case 'J': /* Next line */ case 'j': case KEY_DOWN: if (!end_reached) { begin_reached = 0; scrollok(box, TRUE); scroll(box); /* Scroll box region up one line */ scrollok(box, FALSE); print_line(box, boxh - 1, boxw); wnoutrefresh(box); print_position(dialog); wmove(dialog, cur_y, cur_x); /* Restore cursor position */ wrefresh(dialog); } break; case KEY_NPAGE: /* Next page */ case ' ': if (end_reached) break; begin_reached = 0; refresh_text_box(dialog, box, boxh, boxw, cur_y, cur_x); break; case '0': /* Beginning of line */ case 'H': /* Scroll left */ case 'h': case KEY_LEFT: if (hscroll <= 0) break; if (key == '0') hscroll = 0; else hscroll--; /* Reprint current page to scroll horizontally */ back_lines(page_length); refresh_text_box(dialog, box, boxh, boxw, cur_y, cur_x); break; case 'L': /* Scroll right */ case 'l': case KEY_RIGHT: if (hscroll >= MAX_LEN) break; hscroll++; /* Reprint current page to scroll horizontally */ back_lines(page_length); refresh_text_box(dialog, box, boxh, boxw, cur_y, cur_x); break; case KEY_ESC: key = on_key_esc(dialog); break; case KEY_RESIZE: back_lines(height); delwin(box); delwin(dialog); on_key_resize(); goto do_resize; } } delwin(box); delwin(dialog); return key; /* ESC pressed */ }
/* * Display a dialog box for inputing a string */ int dialog_inputbox(const char *title, const char *prompt, int height, int width, const char *init) { int i, x, y, box_y, box_x, box_width; int input_x = 0, scroll = 0, key = 0, button = -1; char *instr = dialog_input_result; WINDOW *dialog; if (!init) instr[0] = '\0'; else strcpy(instr, init); do_resize: if (getmaxy(stdscr) <= (height - 2)) return -ERRDISPLAYTOOSMALL; if (getmaxx(stdscr) <= (width - 2)) return -ERRDISPLAYTOOSMALL; /* center dialog box on screen */ x = (COLS - width) / 2; y = (LINES - height) / 2; draw_shadow(stdscr, y, x, height, width); dialog = newwin(height, width, y, x); keypad(dialog, TRUE); draw_box(dialog, 0, 0, height, width, dlg.dialog.atr, dlg.border.atr); (void)wattrset(dialog, dlg.border.atr); mvwaddch(dialog, height - 3, 0, ACS_LTEE); for (i = 0; i < width - 2; i++) waddch(dialog, ACS_HLINE); (void)wattrset(dialog, dlg.dialog.atr); waddch(dialog, ACS_RTEE); print_title(dialog, title, width); (void)wattrset(dialog, dlg.dialog.atr); print_autowrap(dialog, prompt, width - 2, 1, 3); /* Draw the input field box */ box_width = width - 6; getyx(dialog, y, x); box_y = y + 2; box_x = (width - box_width) / 2; draw_box(dialog, y + 1, box_x - 1, 3, box_width + 2, dlg.dialog.atr, dlg.border.atr); print_buttons(dialog, height, width, 0); /* Set up the initial value */ wmove(dialog, box_y, box_x); (void)wattrset(dialog, dlg.inputbox.atr); input_x = strlen(instr); if (input_x >= box_width) { scroll = input_x - box_width + 1; input_x = box_width - 1; for (i = 0; i < box_width - 1; i++) waddch(dialog, instr[scroll + i]); } else { waddstr(dialog, instr); } wmove(dialog, box_y, box_x + input_x); wrefresh(dialog); while (key != KEY_ESC) { key = wgetch(dialog); if (button == -1) { /* Input box selected */ switch (key) { case TAB: case KEY_UP: case KEY_DOWN: break; case KEY_LEFT: continue; case KEY_RIGHT: continue; case KEY_BACKSPACE: case 127: if (input_x || scroll) { (void)wattrset(dialog, dlg.inputbox.atr); if (!input_x) { scroll = scroll < box_width - 1 ? 0 : scroll - (box_width - 1); wmove(dialog, box_y, box_x); for (i = 0; i < box_width; i++) waddch(dialog, instr[scroll + input_x + i] ? instr[scroll + input_x + i] : ' '); input_x = strlen(instr) - scroll; } else input_x--; instr[scroll + input_x] = '\0'; mvwaddch(dialog, box_y, input_x + box_x, ' '); wmove(dialog, box_y, input_x + box_x); wrefresh(dialog); } continue; default: if (key < 0x100 && isprint(key)) { if (scroll + input_x < MAX_LEN) { (void)wattrset(dialog, dlg.inputbox.atr); instr[scroll + input_x] = key; instr[scroll + input_x + 1] = '\0'; if (input_x == box_width - 1) { scroll++; wmove(dialog, box_y, box_x); for (i = 0; i < box_width - 1; i++) waddch(dialog, instr [scroll + i]); } else { wmove(dialog, box_y, input_x++ + box_x); waddch(dialog, key); } wrefresh(dialog); } else flash(); /* Alarm user about overflow */ continue; } } } switch (key) { case 'O': case 'o': delwin(dialog); return 0; case 'H': case 'h': delwin(dialog); return 1; case KEY_UP: case KEY_LEFT: switch (button) { case -1: button = 1; /* Indicates "Help" button is selected */ print_buttons(dialog, height, width, 1); break; case 0: button = -1; /* Indicates input box is selected */ print_buttons(dialog, height, width, 0); wmove(dialog, box_y, box_x + input_x); wrefresh(dialog); break; case 1: button = 0; /* Indicates "OK" button is selected */ print_buttons(dialog, height, width, 0); break; } break; case TAB: case KEY_DOWN: case KEY_RIGHT: switch (button) { case -1: button = 0; /* Indicates "OK" button is selected */ print_buttons(dialog, height, width, 0); break; case 0: button = 1; /* Indicates "Help" button is selected */ print_buttons(dialog, height, width, 1); break; case 1: button = -1; /* Indicates input box is selected */ print_buttons(dialog, height, width, 0); wmove(dialog, box_y, box_x + input_x); wrefresh(dialog); break; } break; case ' ': case '\n': delwin(dialog); return (button == -1 ? 0 : button); case 'X': case 'x': key = KEY_ESC; break; case KEY_ESC: key = on_key_esc(dialog); break; case KEY_RESIZE: delwin(dialog); on_key_resize(); goto do_resize; } } delwin(dialog); return KEY_ESC; /* ESC pressed */ }
void pay(struct set_t *store, struct sales_promotion *promotions, struct set_t *shopping) { struct set_t *pomo_set; //购物车中的促销商品 struct set_t* double_pomo_set; //购物车中同时享受两种优惠的商品 struct set_t *temp1, *temp2; //临时变量 struct set_t *pure_goods; //购物车中不享受优惠的商品 struct promotion_one_info *pomo_info; //促销活动 enum promotion_category pomo_priority; //如果商品享受两种优惠,应该优先使用哪种 float cost_save; //优惠节约金额 float expenditure; //消费总计 struct free_one_list *free_list; //赠送的商品 cost_save = expenditure = 0; pomo_info = promotions->promotion_all_info;//指向优惠活动的头指针 pomo_priority = promotions->priority; free_list = NULL; double_pomo_set = shopping; pure_goods = shopping; while(pomo_info) { //循环遍历每种活动 //先计算享受两种优惠的商品 temp1 = double_pomo_set; double_pomo_set = set_inter(double_pomo_set, pomo_info->sales_set); if (temp1 != shopping) { set_free(&temp1); }/*释放set_inter生成的临时的set*/ //计算没有优惠的商品 temp2 = pure_goods; pure_goods = set_minus(pure_goods, pomo_info->sales_set); if(temp2 != shopping) { set_free(&temp2); }/*释放set_minus生成的临时的set*/ pomo_info = pomo_info->next_promotion; }/*while*/ //打印小票头信息 print_title(); //计算没有优惠 settle_product(store, pure_goods, &cost_save, &expenditure); //计算二重优惠 settle_double_promotion(store, pomo_priority, double_pomo_set, &cost_save, &expenditure); //计算一种优惠的商品,并结算 for (pomo_info = promotions->promotion_all_info;\ pomo_info; pomo_info = pomo_info->next_promotion){ switch (pomo_info->type) { case DISCOUNT: //95折扣 temp1 = set_inter(pomo_info->sales_set,shopping); settle_discount(store, temp1, double_pomo_set, &cost_save, &expenditure); if(temp1) set_free(&temp1); break; case FREE_ONE: //买二送一 temp1 = set_inter(pomo_info->sales_set,shopping); settle_free_one(store, temp1, double_pomo_set, &cost_save, &expenditure); if(temp1) set_free(&temp1); break; default: assert(!"no this promotion\n"); break; }/*switch*/ }/*for*/ //赠送商品列表打印 free_list = put_free_one_list(NULL, 0); free_one_print(free_list); //小票末尾信息打印 print_tail(cost_save, expenditure); }
/* * Display a dialog box with two buttons - Yes and No */ int dialog_yesno(const char *title, const char *prompt, int height, int width) { int i, x, y, key = 0, button = 0; WINDOW *dialog; do_resize: if (getmaxy(stdscr) < (height + 4)) return -ERRDISPLAYTOOSMALL; if (getmaxx(stdscr) < (width + 4)) return -ERRDISPLAYTOOSMALL; /* center dialog box on screen */ x = (COLS - width) / 2; y = (LINES - height) / 2; draw_shadow(stdscr, y, x, height, width); dialog = newwin(height, width, y, x); keypad(dialog, TRUE); draw_box(dialog, 0, 0, height, width, dlg.dialog.atr, dlg.border.atr); wattrset(dialog, dlg.border.atr); mvwaddch(dialog, height - 3, 0, ACS_LTEE); for (i = 0; i < width - 2; i++) waddch(dialog, ACS_HLINE); wattrset(dialog, dlg.dialog.atr); waddch(dialog, ACS_RTEE); print_title(dialog, title, width); wattrset(dialog, dlg.dialog.atr); print_autowrap(dialog, prompt, width - 2, 1, 3); print_buttons(dialog, height, width, 0); while (key != KEY_ESC) { key = wgetch(dialog); switch (key) { case 'Y': case 'y': delwin(dialog); return 0; case 'N': case 'n': delwin(dialog); return 1; case TAB: case KEY_LEFT: case KEY_RIGHT: button = ((key == KEY_LEFT ? --button : ++button) < 0) ? 1 : (button > 1 ? 0 : button); print_buttons(dialog, height, width, button); wrefresh(dialog); break; case ' ': case '\n': delwin(dialog); return button; case KEY_ESC: key = on_key_esc(dialog); break; case KEY_RESIZE: delwin(dialog); on_key_resize(); goto do_resize; } } delwin(dialog); return key; /* ESC pressed */ }
int main(int argc, char *argv[]) { if (argc != 2) exit(EXIT_SUCCESS); printf(NOTICE); HANDLE hFileMap = MapPE_open(argv[1]); PIMAGE_DOS_HEADER hDOS = MapPE_DOS(hFileMap); PIMAGE_NT_HEADERS hNT = MapPE_NT(hFileMap); PIMAGE_SECTION_HEADER hSection; PIMAGE_IMPORT_DESCRIPTOR hEntryImport; PIMAGE_THUNK_DATA hOriginalFirstThunk; PIMAGE_THUNK_DATA hFirstThunk; PIMAGE_IMPORT_BY_NAME API; /*/ typedef struct _IMAGE_DOS_HEADER { WORD e_magic; WORD e_cblp; WORD e_cp; WORD e_crlc; WORD e_cparhdr; WORD e_minalloc; WORD e_maxalloc; WORD e_ss; WORD e_sp; WORD e_csum; WORD e_ip; WORD e_cs; WORD e_lfarlc; WORD e_ovno; WORD e_res[4]; WORD e_oemid; WORD e_oeminfo; WORD e_res2[10]; LONG e_lfanew; } IMAGE_DOS_HEADER,*PIMAGE_DOS_HEADER; /*/ print_title("IMAGE_DOS_HEADER"); //#define IMAGE_DOS_SIGNATURE 0x5A4D printx("e_magic", hDOS->e_magic); printx("e_cblp", hDOS->e_cblp); printx("e_cp", hDOS->e_cp); printx("e_crlc", hDOS->e_crlc); printx("e_cparhdr", hDOS->e_cparhdr); printx("e_minalloc", hDOS->e_minalloc); printx("e_maxalloc", hDOS->e_maxalloc); printx("e_ss", hDOS->e_ss); printx("e_sp", hDOS->e_sp); printx("e_csum", hDOS->e_csum); printx("e_ip", hDOS->e_ip); printx("e_cs", hDOS->e_cs); printx("e_lfarlc", hDOS->e_lfarlc); printx("e_ovno", hDOS->e_ovno); printx("e_res", hDOS->e_res); printx("e_oemid", hDOS->e_oemid); printx("e_oeminfo", hDOS->e_oeminfo); printx("e_res2", hDOS->e_res2); printx("e_lfanew", hDOS->e_lfanew); /*/ typedef struct _IMAGE_NT_HEADERS { DWORD Signature; IMAGE_FILE_HEADER FileHeader; IMAGE_OPTIONAL_HEADER32 OptionalHeader; } IMAGE_NT_HEADERS32,*PIMAGE_NT_HEADERS32; /*/ print_title("IMAGE_NT_HEADERS"); printx("Signature", hNT->Signature); /*/ typedef struct _IMAGE_FILE_HEADER { WORD Machine; WORD NumberOfSections; DWORD TimeDateStamp; DWORD PointerToSymbolTable; DWORD NumberOfSymbols; WORD SizeOfOptionalHeader; WORD Characteristics; } IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER; /*/ print_title("IMAGE_FILE_HEADER"); printx("Machine", hNT->FileHeader.Machine); printx("NumberOfSections", hNT->FileHeader.NumberOfSections); printx("TimeDateStamp", hNT->FileHeader.TimeDateStamp); printx("PointerToSymbolTable", hNT->FileHeader.PointerToSymbolTable); printx("NumberOfSymbols", hNT->FileHeader.NumberOfSymbols); printx("SizeOfOptionalHeader", hNT->FileHeader.SizeOfOptionalHeader); printx("Characteristics", hNT->FileHeader.Characteristics); /*/ typedef struct _IMAGE_OPTIONAL_HEADER { WORD Magic; BYTE MajorLinkerVersion; BYTE MinorLinkerVersion; DWORD SizeOfCode; DWORD SizeOfInitializedData; DWORD SizeOfUninitializedData; DWORD AddressOfEntryPoint; DWORD BaseOfCode; DWORD BaseOfData; DWORD ImageBase; DWORD SectionAlignment; DWORD FileAlignment; WORD MajorOperatingSystemVersion; WORD MinorOperatingSystemVersion; WORD MajorImageVersion; WORD MinorImageVersion; WORD MajorSubsystemVersion; WORD MinorSubsystemVersion; DWORD Win32VersionValue; DWORD SizeOfImage; DWORD SizeOfHeaders; DWORD CheckSum; WORD Subsystem; WORD DllCharacteristics; DWORD SizeOfStackReserve; DWORD SizeOfStackCommit; DWORD SizeOfHeapReserve; DWORD SizeOfHeapCommit; DWORD LoaderFlags; DWORD NumberOfRvaAndSizes; IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; } IMAGE_OPTIONAL_HEADER32,*PIMAGE_OPTIONAL_HEADER32; /*/ print_title("IMAGE_OPTIONAL_HEADER"); printx("Magic", hNT->OptionalHeader.Magic); printx("MajorLinkerVersion", hNT->OptionalHeader.MajorLinkerVersion); printx("MinorLinkerVersion", hNT->OptionalHeader.MinorLinkerVersion); printx("SizeOfCode", hNT->OptionalHeader.SizeOfCode); printx("SizeOfInitializedData", hNT->OptionalHeader.SizeOfInitializedData); printx("SizeOfUninitializedData", hNT->OptionalHeader.SizeOfUninitializedData); printx("AddressOfEntryPoint", hNT->OptionalHeader.AddressOfEntryPoint); printx("BaseOfCode", hNT->OptionalHeader.BaseOfCode); printx("BaseOfData", hNT->OptionalHeader.BaseOfData); printx("ImageBase", hNT->OptionalHeader.ImageBase); printx("SectionAlignment", hNT->OptionalHeader.SectionAlignment); printx("FileAlignment", hNT->OptionalHeader.FileAlignment); printx("MajorOperatingSystemVersion", hNT->OptionalHeader.MajorOperatingSystemVersion); printx("MinorOperatingSystemVersion", hNT->OptionalHeader.MinorOperatingSystemVersion); printx("MajorImageVersion", hNT->OptionalHeader.MajorImageVersion); printx("MinorImageVersion", hNT->OptionalHeader.MinorImageVersion); printx("MajorSubsystemVersion", hNT->OptionalHeader.MajorSubsystemVersion); printx("MinorSubsystemVersion", hNT->OptionalHeader.MinorSubsystemVersion); printx("Win32VersionValue", hNT->OptionalHeader.Win32VersionValue); printx("SizeOfImage", hNT->OptionalHeader.SizeOfImage); printx("SizeOfHeaders", hNT->OptionalHeader.SizeOfHeaders); printx("CheckSum", hNT->OptionalHeader.CheckSum); printx("Subsystem", hNT->OptionalHeader.Subsystem); printx("DllCharacteristics", hNT->OptionalHeader.DllCharacteristics); printx("SizeOfStackReserve", hNT->OptionalHeader.SizeOfStackReserve); printx("SizeOfStackCommit", hNT->OptionalHeader.SizeOfStackCommit); printx("SizeOfHeapReserve", hNT->OptionalHeader.SizeOfHeapReserve); printx("SizeOfHeapCommit", hNT->OptionalHeader.SizeOfHeapCommit); printx("LoaderFlags", hNT->OptionalHeader.LoaderFlags); printx("NumberOfRvaAndSizes", hNT->OptionalHeader.NumberOfRvaAndSizes); /*/ #define IMAGE_DIRECTORY_ENTRY_EXPORT 0 #define IMAGE_DIRECTORY_ENTRY_IMPORT 1 #define IMAGE_DIRECTORY_ENTRY_RESOURCE 2 #define IMAGE_DIRECTORY_ENTRY_EXCEPTION 3 #define IMAGE_DIRECTORY_ENTRY_SECURITY 4 #define IMAGE_DIRECTORY_ENTRY_BASERELOC 5 #define IMAGE_DIRECTORY_ENTRY_DEBUG 6 #define IMAGE_DIRECTORY_ENTRY_COPYRIGHT 7 #define IMAGE_DIRECTORY_ENTRY_ARCHITECTURE 7 #define IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8 #define IMAGE_DIRECTORY_ENTRY_TLS 9 #define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10 #define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT 11 #define IMAGE_DIRECTORY_ENTRY_IAT 12 #define IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT 13 #define IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR 14 /*/ print_title("DataDirectory"); print_dd("[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress", hNT->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress); print_dd("[IMAGE_DIRECTORY_ENTRY_EXPORT].Size", hNT->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size); print_dd("[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress", hNT->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress); print_dd("[IMAGE_DIRECTORY_ENTRY_IMPORT].Size", hNT->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size); print_dd("[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress", hNT->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress); print_dd("[IMAGE_DIRECTORY_ENTRY_RESOURCE].Size", hNT->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].Size); print_dd("[IMAGE_DIRECTORY_ENTRY_EXCEPTION].VirtualAddress", hNT->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXCEPTION].VirtualAddress); print_dd("[IMAGE_DIRECTORY_ENTRY_EXCEPTION].Size", hNT->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXCEPTION].Size); print_dd("[IMAGE_DIRECTORY_ENTRY_SECURITY].VirtualAddress", hNT->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY].VirtualAddress); print_dd("[IMAGE_DIRECTORY_ENTRY_SECURITY].Size", hNT->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY].Size); print_dd("[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress", hNT->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress); print_dd("[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size", hNT->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size); print_dd("[IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress", hNT->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress); print_dd("[IMAGE_DIRECTORY_ENTRY_DEBUG].Size", hNT->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].Size); print_dd("[IMAGE_DIRECTORY_ENTRY_COPYRIGHT].VirtualAddress", hNT->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COPYRIGHT].VirtualAddress); print_dd("[IMAGE_DIRECTORY_ENTRY_COPYRIGHT].Size", hNT->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COPYRIGHT].Size); print_dd("[IMAGE_DIRECTORY_ENTRY_ARCHITECTURE].VirtualAddress", hNT->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_ARCHITECTURE].VirtualAddress); print_dd("[IMAGE_DIRECTORY_ENTRY_ARCHITECTURE].Size", hNT->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_ARCHITECTURE].Size); print_dd("[IMAGE_DIRECTORY_ENTRY_GLOBALPTR].VirtualAddress", hNT->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_GLOBALPTR].VirtualAddress); print_dd("[IMAGE_DIRECTORY_ENTRY_GLOBALPTR].Size", hNT->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_GLOBALPTR].Size); print_dd("[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress", hNT->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress); print_dd("[IMAGE_DIRECTORY_ENTRY_TLS].Size", hNT->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].Size); print_dd("[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG].VirtualAddress", hNT->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG].VirtualAddress); print_dd("[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG].Size", hNT->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG].Size); print_dd("[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress", hNT->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress); print_dd("[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].Size", hNT->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].Size); print_dd("[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress", hNT->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress); print_dd("[IMAGE_DIRECTORY_ENTRY_IAT].Size", hNT->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].Size); print_dd("[IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT].VirtualAddress", hNT->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT].VirtualAddress); print_dd("[IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT].Size", hNT->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT].Size); print_dd("[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress", hNT->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress); print_dd("[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].Size", hNT->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].Size); /*/ typedef struct _IMAGE_SECTION_HEADER { BYTE Name[IMAGE_SIZEOF_SHORT_NAME]; union { DWORD PhysicalAddress; DWORD VirtualSize; } Misc; DWORD VirtualAddress; DWORD SizeOfRawData; DWORD PointerToRawData; DWORD PointerToRelocations; DWORD PointerToLinenumbers; WORD NumberOfRelocations; WORD NumberOfLinenumbers; DWORD Characteristics; } IMAGE_SECTION_HEADER,*PIMAGE_SECTION_HEADER; /*/ print_title("IMAGE_SECTION_HEADER"); int i; for (i = 0; i < hNT->FileHeader.NumberOfSections; i++) { hSection = MapPE_SECTIONS(hFileMap, i); print_subtitle("Name", hSection->Name); printx("Misc.PhysicalAddress", hSection->Misc.PhysicalAddress); printx("Misc.VirtualSize", hSection->Misc.VirtualSize); printx("VirtualAddress", hSection->VirtualAddress); printx("SizeOfRawData", hSection->SizeOfRawData); printx("PointerToRawData", hSection->PointerToRawData); printx("PointerToRelocations", hSection->PointerToRelocations); printx("PointerToLinenumbers", hSection->PointerToLinenumbers); printx("NumberOfRelocations", hSection->NumberOfRelocations); printx("NumberOfLinenumbers", hSection->NumberOfLinenumbers); printx("Characteristics", hSection->Characteristics); } /*/ typedef struct _IMAGE_IMPORT_DESCRIPTOR { _ANONYMOUS_UNION union { DWORD Characteristics; DWORD OriginalFirstThunk; } DUMMYUNIONNAME; DWORD TimeDateStamp; DWORD ForwarderChain; DWORD Name; DWORD FirstThunk; } IMAGE_IMPORT_DESCRIPTOR,*PIMAGE_IMPORT_DESCRIPTOR; /*/ print_title("IMAGE_DIRECTORY_ENTRY_IMPORT alias Import Address Table (IAT)"); DWORD EntryExportVA = hNT->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress; DWORD EntryExportSize = hNT->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size; hEntryImport = (PIMAGE_IMPORT_DESCRIPTOR) (hFileMap + RVAtoOFFSET(hFileMap, EntryExportVA)); while (hEntryImport->FirstThunk) { print_subtitle("[+] Name", hFileMap + RVAtoOFFSET(hFileMap, hEntryImport->Name)); printx("OriginalFirstThunk", hEntryImport->OriginalFirstThunk); printx("FirstThunk", hEntryImport->FirstThunk); printx("Characteristics", hEntryImport->Characteristics); printx("TimeDateStamp", hEntryImport->TimeDateStamp); printx("ForwarderChain", hEntryImport->ForwarderChain); /*/ typedef struct _IMAGE_THUNK_DATA { union { DWORD ForwarderString; DWORD Function; DWORD Ordinal; DWORD AddressOfData; } u1; } IMAGE_THUNK_DATA,*PIMAGE_THUNK_DATA; /*/ hOriginalFirstThunk = (PIMAGE_THUNK_DATA) (hFileMap + RVAtoOFFSET(hFileMap, hEntryImport->OriginalFirstThunk)); hFirstThunk = (PIMAGE_THUNK_DATA) (hFileMap + RVAtoOFFSET(hFileMap, hEntryImport->FirstThunk)); while (hOriginalFirstThunk->u1.AddressOfData) { /*/ typedef struct _IMAGE_IMPORT_BY_NAME { WORD Hint; BYTE Name[1]; } IMAGE_IMPORT_BY_NAME,*PIMAGE_IMPORT_BY_NAME; /*/ API = (PIMAGE_IMPORT_BY_NAME) (hFileMap + RVAtoOFFSET(hFileMap, hOriginalFirstThunk->u1.AddressOfData)); print_subtitle("Name", API->Name); printx("Hint", API->Hint); printx("Function", hOriginalFirstThunk->u1.Function); hOriginalFirstThunk++; hFirstThunk++; } hEntryImport++; } MapPE_close(hFileMap); printf("[+] END OF DOOM [+]"); return 0; }
void operator()(const osmium::Way& way) { print_title("WAY", way); print_meta(way); }