]> git.feebdaed.xyz Git - 0xmirror/radare2.git/commitdiff
Load fortune messages from directories ##shell
authorpancake <pancake@nowsecure.com>
Tue, 9 Dec 2025 17:48:17 +0000 (18:48 +0100)
committerGitHub <noreply@github.com>
Tue, 9 Dec 2025 17:48:17 +0000 (18:48 +0100)
* New dir.fortunes config variable
* Load fortune messages from xdg home
* Support plugin-specific fortunes

Makefile
doc/fortunes.fun [deleted file]
doc/fortunes.tips [deleted file]
doc/fortunes/fun.txt [new file with mode: 0644]
doc/fortunes/tips.txt [new file with mode: 0644]
libr/core/cconfig.c
libr/core/fortune.c
libr/include/r_core.h
libr/include/r_lib.h
libr/util/sys.c
meson.build

index b25e24c188527bd1345bc0d2e008c19c5bb5553b..a9090db63ace518b77b913c949af50dd55775a66 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -165,7 +165,8 @@ windist:
        cp -f libr/include/r_anal/*.h "${WINDIST}/include/libr/r_anal/"
        cp -f libr/include/*.h "${WINDIST}/include/libr"
        #mkdir -p "${WINDIST}/include/libr/sflib"
-       @cp -f doc/fortunes.* "${WINDIST}/share/doc/radare2"
+       @mkdir -p "${WINDIST}/share/radare2/${VERSION}/fortunes"
+       @cp -f doc/fortunes.* "${WINDIST}/share/radare2/${VERSION}/fortunes"
        @mkdir -p "${WINDIST}/share/radare2/${VERSION}/format/dll"
        @cp -f libr/bin/d/elf32 "${WINDIST}/share/radare2/${VERSION}/format"
        @cp -f libr/bin/d/elf64 "${WINDIST}/share/radare2/${VERSION}/format"
@@ -250,6 +251,9 @@ install: install-doc install-man install-panels install-www install-pkgconfig
        cp -rf scripts/*.js scripts/*.py "${DESTDIR}${DATADIR}/radare2/${VERSION}/scripts"
        rm -rf "${DESTDIR}${DATADIR}/radare2/${VERSION}/hud"
        mkdir -p "${DESTDIR}${DATADIR}/radare2/${VERSION}/hud"
+       rm -rf "${DESTDIR}${DATADIR}/radare2/${VERSION}/fortunes"
+       mkdir -p "${DESTDIR}${DATADIR}/radare2/${VERSION}/fortunes"
+       cp -rf doc/fortunes/*.txt "${DESTDIR}${DATADIR}/radare2/${VERSION}/fortunes"
        mkdir -p "${DESTDIR}${BINDIR}"
        rm -f "${DESTDIR}${BINDIR}/clang-format-radare2"
        rm -f "${DESTDIR}${BINDIR}/r2-indent"
@@ -316,6 +320,8 @@ symstall install-symlink: install-man-symlink install-doc-symlink install-pkgcon
        ln -fs scripts "${DESTDIR}${DATADIR}/radare2/${VERSION}/scripts"
        mkdir -p "${DESTDIR}${DATADIR}/radare2/${VERSION}/hud"
        ln -fs "${PWD}/doc/hud" "${DESTDIR}${DATADIR}/radare2/${VERSION}/hud/main"
+       rm -rf "${DESTDIR}${DATADIR}/radare2/${VERSION}/fortunes"
+       ln -fs "${PWD}/doc/fortunes" "${DESTDIR}${DATADIR}/radare2/${VERSION}/fortunes"
        #mkdir -p "${DESTDIR}${DATADIR}/radare2/${VERSION}/flag"
        #ln -fs $(PWD)/libr/flag/d/tags.r2 "${DESTDIR}${DATADIR}/radare2/${VERSION}/flag/tags.r2"
        cd "$(DESTDIR)$(LIBDIR)/radare2/" && rm -f last && ln -fs $(VERSION) last
diff --git a/doc/fortunes.fun b/doc/fortunes.fun
deleted file mode 100644 (file)
index 87c6a7f..0000000
+++ /dev/null
@@ -1,364 +0,0 @@
-No disassemble!!!
-Deltify your life with radare2
-In soviet russia, radare2 debugs you!
-What do you want to debug today?
-I love the smell of bugs in the morning.
-I'm in your source securing your bits.
-radare2 contributes to the One Byte Per Child foundation.
-3nl4r9e y0\/r r4d4r3
-I did it for the pwnz.
-If you send the program you are debugging to 15 friends in 143 minutes and then step three times on the same opcode you will get the name of the person who loves you.
-Heisenbug: A bug that disappears or alters its behavior when one attempts to probe or isolate it.
-radare2 is for lulzhats
-Microloft Visual Radare.NET 2008. Now OOXML Powered!
-A C program is like a fast dance on a newly waxed dance floor by people carrying razors - Waldi Ravens
-radare2 is like windows 7 but even better.
-We are surrounded by the enemy. - Excellent, we can attack in any direction!
-radare2-built farm beats the facebook one.
-Thank you for using radare2. Have a nice night!
-Your r2 was built 20h ago. TOO OLD!
-Use radare2! Lemons included!
-rax2 -s 20e296b20ae296b220e296b20a
-Connection lost with the license server, your r2 session will terminate in 30 minutes.
-This is amazing ...
-I love gradients.
-Wait a moment ...
-Don't do this.
-No such file or directory.
-Default scripting languages are NodeJS and Python.
--bash: r2: command not found
-Press any key to continue ...
-ilo ni li pona li pali e lipu. o musi!
-radare2 for FideOS, now with extra potato
-Your project name should contain an uppercase letter, 8 vowels, some numbers, and the first 5 characters of your private bitcoin key.
-This computer has gone to sleep.
-Have you ever ordered a pizza using radare2?
-I thought we were friends. :_
-Welcome back, lazy human!
-Yo dawg!
----8<--------------------8<------------------8<-----------------8<------
-I accidentally the kernel with radare2.
-I endians swap.
-This page intentionally left blank.
-Here be dragons.
-Trust no one, nor a zero. Both lie.
-EIP = 0x41414141
-/dev/brain: No such file or directory.
-Virtual machines are great, but you lose the ability to kick the hardware.
-Charlie! We are here.
-The door is everything ...
-The door controls time and space.
-The door can see into your soul.
-I am Pentium of Borg. Division is futile. You will be approximated.
-Don't look at the code. Don't look.
-Dissasemble? No dissasemble, no dissassemble!!!!!
-Warning, your trial license is about to expire.
-Please register your copy of r2 today! Only £29.90!
-Welcome to IDA 10.0.
-It's not you, it's me.
-This software comes with no brain included. Please use your own.
-rm: /: Permission denied.
-That's embarrassing.
-In soviet Afghanistan, you debug radare2!
-Wow, my cat knows radare2 hotkeys better than me!
-Documentation is for weak people.
-PEBCAK ERROR: Documentation not found.
-License server overloaded (ETOOMUCHCASH)
-Error: cannot yank negative sleep
-If you're not satisfied by our product, you may ask for a refund.
-Already up-to-date.
-How about a nice game of chess?
-THE ONLY WINNING MOVE IS NOT TO PLAY.
-SHALL WE PLAY A GAME?
-sudo make me a pancake
-I nodejs so hard my exams. What a nodejs!
-Now featuring NoSQL!
-One does not simply write documentation.
-We are bleeding edge here. Can't you feel the razors?
-There's a branch for that.
-Everything up-to-date.
-Sharing your latest session to Facebook ...
-This should be documented, since it's not that obvious.
-It's working! Look at the door!
-This is an unacceptable million year dungeon.
-The Hard ROP Cafe
-Wait a minute! I found a bug, self-fixing ... OK
-Hold on, this should never happen!
-Well this is embarrassing ...
-THIS IS NOT FUNNY
-♥  --
-Can you stand on your head?
-May the segfault be with you.
-I script in C, because I can.
-EXPLICIT CONTENT
-Bindings are mostly powered by tears.
-In Soviet Russia, radare2 has documentation.
-Initial frame selected; you cannot go up.
-Unk, unk, unk, unk
-Experts agree, security holes suck, and we fixed some of them!
-This is just an existentialist experiment.
-Nothing to see here. Move along.
-Select your character: RBin Wizard, Master Anal Paladin, or Assembly Warrior
-I accidentally radared my filesystem today.
-No fix, no sleep
-You see it, you fix it!
-V is for Visual
-r2-goverity: found corruption - please eliminate!
-Stop debugging me!
-THIS IS NOT A BUG
-Polish reversers blame git
-vm is like a small cow in ascii
-Do you want to print 333.5K chars? (y/N)
-Now with more better English!
-:(){ :|:& };:
-All your base are belong to r2
-Ask not what r2 can do for you - ask what you can do for r2
-Try with ASAN, and be amazed
-bash: r3: command not found
-R2 loves everyone, even Java coders, but less than others
-It's not a bug, it's a work in progress
-Stop swearing!
-I didn't say that it was working, I said that it's implemented
-Wrong argument
-Remember that word: C H A I R
-what happens in #radare, stays in #radare
-For a full list of commands see `strings /dev/urandom`
-Good morning, pal *<:-)
-Of course r2 runs FreeBSD
-Reverser by Birth, r2 by Choice
-Radare2, what else?
-This incident will be reported
-command not found: calc.exe
-See you at the defcon CTF
-Don't waste your time
-WASTED
-getdruid to get eclectic uid
-Welcome to "IDA - the roguelike"
-255 shades of (truecolor) grey
-When you sold that exploit, what they really bought, was your silence.
-Greetings, human.
-nothing personal, just bitness
-Too old to crash
-Finished a beer
-ESIL ruined my life
-ESIL: The Aftersleep
-Insert coin to continue ...
-See you in shell
-Mess with the best, Die like the rest
-Sarah Connor?
-Log On. Hack In. Go Anywhere. Get Everything.
-phrack, better than java in the browser -- jvoisin
-Did you know that radare2 can decompile to assembly?
-Are you still there?
-Follow the white rabbit
-Do not try to sploit that binary - that's impossible. Instead, only try to realize the truth: there is no binary.
-Hello Mr. Anderson
-Try pressing the pigeon-shaped button
-What has been executed cannot be unexecuted
-What about taking a break? Here, have this nice 0xCC.
-r2 is meant to be read by machines.
-Prove you are a robot to continue ...
-This is fine.
-Using radare2 to generate intelligence ...
-Taking the file and moving it somewhere else
-It's the year of desktop on radare2
-💺
-It's the year of radare2 on the desktop
-SSAbotage from ISIL
-"a collection of garbage" -- an r2 pro user
-A git pull a day keeps the segfault away
-Are you a wizard?
-Learn pancake as if you were radare!
-r2 is a great OS, but a terrible hex editor
-THE CAKE IS A PIE
-radare2 0.9.7 is so old, my grandfather was using it with his enigma in WWII
-Have you seen the latest radare2 TV spot?
-scp ~/.idapro/ida.key radare.org:/var/www/radare.org/pub/losers/
-Too bad there is no gif support in r2. Yet. -- @r2gif
-Almost 5am, maybe you should go to bed.
-Jingle sploits, jingle sploits, ropchain all the way.
-Mind that the 'g' in radare is silent
-256 colors ought to be enough for anybody
-Hang in there, Baby!
-Run a command with unspecified long sequence of 'a', pancake will be summoned and do the analysis for you.
-In r2land usability is treated as a bug
-radare2 is WYSIWYF - what you see is what you fix
-Your endian swaps
-*(ut64*)buffer ought to be illegal
-How about Global Thermonuclear War?
-There is no F5 key in radare2 yet
-Did you know that r2 is 10 years old?
-Beer in mind.
-r2 -- leading options since 2006
-Don’t feed the bugs! (except delicious stacktraces)!
-Feed the bugs!
-You haxor! Me jane?
-r2 talks to you. tries to make you feel well.
-Now i'm like an evil engineer. MUAHAHAH
-We only have bugs, features are an unintended side-effect
-There are 5 minutes from WTF to FIX in r2land
-Quantum disassemble: it's there as long as you don't observe it
-Ceci n'est pas une r2pipe
-Buy a mac
-(gdb) ^D
-((fn [f s n] (str (f f s n) "dare2")) (fn [f s n] (pr s) (if (> n 0) (f f (str s "ra") (dec n)) s)) "" (/ 1.0 0))
-There's no way you could crash radare2. No. Way.
-When in doubt, try 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa; pd;'
-.-. .- -.. .- .-. . ..---
-Disassemble?! No Disassemble Johnny No. 5!!!
-You crackme up!
-Welcome, "reenigne"
-Search returned no hits. Did you mean 'Misassemble'?
-º|<|<|  -( glu glu glu, im the r2 fish )
-Everybody hates warnings. Mr. Pancake, tear down this -Wall
-TIRED OF WAITING
-We fix bugs while you sleep.
-You find bugs while we sleep.
-The stripping process is not deep enough
-Come here, we are relatively friendly
-Don't wait for Travis
-Your problems are solved in an abandoned branch somewhere
-git blind --hard
-You need some new glasses
-aaaa is experimental
-We feed trolls
-Mind the tab
-Buy a Mac
-You have been designated for disassembly
-Helping siol merge? No way, that would be like.. way too much not lazy. - vifino
-What is the most complex r2 command? q - then you have to deal with real life /o\
-If you're having fun using radare2, odds are that you're doing something wrong.
-Don't trust what can't be compiled
-Coffee time!
-Can you challenge a perfect immortal machine?
-Add more blockchains to your life.
-Congratulations! You got the segfault 1.000.000! Click [here] to win a prize!
-Well, it looks like it's working.
-There's more than one way to skin a cat
-git pull now
-git checkout hamster
-Noot noot
-This is an unregistered copy.
-10 reasons you want to bt on all threads - you will be shocked by number 3!
-Place a cat on your keyboard while running r2, you'll not believe what will happen next
-This binary may contain traces of human
-Help subcommand will be eventually removed.
-Carpe noctum.
-Your mouse has moved. Radare2 NT must be restarted for the change to take effect. Reboot now? [ OK ]
-There is only one binary, and we are all just reversing pieces of it.
-Radare2 is like violence. If it doesn't solve your problem, you aren't using enough.
-Order pizza for $12.48? [Y/n]
-r2OS r2pad 0.1 SMP GENERIC r2_64 GNU/r2OS
-AHHHHH!!!! ASSEMBLY CODE!!!!!! HOLD ME I'M SCARED!!!!!!!!!!
-In radare we trust
-We don't make mistakes... just happy little segfaults.
-r2 is for the people
-Use headphones for best experience.
-Starting bitcoin miner in background...
-Downloading and verifying the blockchain...
-The anti-virus database has been updated.
-The motion picture contained in this videodisc is protected under the copyright laws.
-This software is sold for home use only and all other rights are expressly reversed by the copyleft owner.
-Any commercial use or duplication of this copylefted material without prior licensing is forbidden.
-Violators will be prosecuted.
-This shell has been seized by the Internet's Police.
-OpenBSD might pledge r2 but r2 unveils OpenBSD.
-Error: There's a missing space before the opening parenthesis '('
-WARNING: r_list_length: assertion 'list' failed (line 55)
-This accessory is not supported by this version of radare2.
-When can we have an official anime mascot for radare2?
-Radare2, we need you to ctrl+s the world.
-Sorry, radare2 has experienced an internal error.
-Segmentation fault (core dumped)
-Use rabin2 to discover the real TRUTH
-==1337== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
-**** COMMODORE 64 RADARE V2 ****  64K RAM SYSTEM  38911 DISASM BYTES FREE  READY.
-Most likely your core dump fell into a blackhole, can't see it.
-Long time no C
-Come to C me!
-Unable to locate package gdb
-You C it, you fix it!
-How good is your C?
-I C dead bugs everywhere!
-You will soon have an out of memory experience.
-This binary no good. Try another.
-BSOD!
-Mind the trap.
-For a full documentation see `r2 -qc iz /lib/libr_core.so`
-99 bugs, take one down pass it around. 100 bugs...
-I like my binary stripped.
-Now 8-bit clean with better ASCII!
-Please insert disc 2 and press any key to continue...
-DOOM all the things!
-Put some sugar before the release, attracts the bugs and makes it easier to squash them
-Stay indoors and await further instructions
-radare2 works best, when pirated.
-I could go up there about 11 at night, stay till 4 in the morning, and get all the computer runs I ever wanted.
-Safety third
-You should try our sister project, radar3!
-This pancake guy sure does know his way around r2.
-make: r2: Command not found
-rip and tear until it compiles
-The r emblem on the front is the legendary symbol for invincibility!
-Send PR or GTFO
-If it's stupid and it works, it is not stupid
-33 + 77 = 100
-radare2[15449] Corpse failure, too many 6
-Process[15449] crashed: radare2. Too many corpses being created.
-You can't sleep now there are monsters nearby
-Every journey begins with a choice
-Do 'r2pm -i r2premium; echo "e cfg.fortunes.type = nsfw" >> ~/.radare2rc' for a even more fun with r2
-pneumonic
-Click below to prove you are not a bot
-Sorry, not sorry.
-fix it or set the machine on fire
-burn it before the bug spreads to other installations
-The signals are strong tonight
-It's dangerous to go alone, take this.
-"If you gotta burn it all to the ground; Then let it burn"
-Watch until the end!
-Don't forget to subscribe!
-Ah shit, here we go again.
-Checking whether this software can be played...
-Will it blend?
-Are you still watching?
-Starting application, this might take some time...
-Do you want to restart to install these updates now or try tonight?
-Updates available
-This binary has not been analyzed. Would you like to analyze it now?
-The software is up to date. Just kidding, git pull again
-Caps lock is on.
-$10 or mistery box?
-INSERT COIN
-This program is not compatible with your device.
-Hey hey hey everyone! welcome to infoflash
-Rise and shine beyond the Black wall
-Relic malfunction detected
-It's now safe to turn off your computer.
-No newline at end of file
-Display output is not active.
-The Quick Brown Fox Jumped Over The Lazy Dog!
-gcc: error: no input files
-Now you're thinking with portals
-The bug you've just found it's fixed in git
-Plug me in, and I'll take you up.
-Plug me in, we're running out of time.
-Corrupted cores! We're in luck.
-You think I'll betray you. And on any other day, you'd be right
-I can't believe you came back.
-You don't have permission to access this resource.
-Sign in or head back to home.
-I'd love to help you solve the tests. But I can't.
-Did anything happen while I was out?
-You look great, by the way. Very healthy
-Press the button again.
-It's been a long time.
-Relic malfunction detected.
-You are offline. Some functionality may be unavailable.
-Patching instructions should be illegal
-Are you still watching?
-Downloading update 1 of 1 ...
-Embrace the failure
-It's like progress but backwards
-My other fortunes are funnier
-Please rotate your phone
diff --git a/doc/fortunes.tips b/doc/fortunes.tips
deleted file mode 100644 (file)
index 6dc1376..0000000
+++ /dev/null
@@ -1,89 +0,0 @@
-Tweak the disassembly output with `e asm.`
-Add custom Have you setup your ~/.radare2rc today?
-In visual mode press 'c' to toggle the cursor mode. Use tab to navigate
-You can mark an offset in visual mode with the cursor and the ',' key. Later press '.' to go back
-You can debug a program from the graph view ('ag') using standard radare2 commands
-Use the '[' and ']' keys in visual mode to adjust the screen width
-Select your architecture with: 'e asm.arch=<arch>' or r2 -a from the shell
-Move between your search hits in visual mode using the 'n' and 'N' keys
-Save your projects with 'Ps <project-filename>' and restore then with 'Po <project-filename>'
-Enable asm.trace to see the tracing information inside the disassembly
-Change the registers of the child process in this way: 'dr eax=0x333'
-Check your IO plugins with 'r2 -L'
-Change the size of the file with the 'r' (resize) command
-Calculate current basic block checksum with the ph command (ph md5, ph crc32, ..)
-Use +,-,*,/ to change the size of the block
-Change the block size with 'b <block-size>'. In visual mode you can also enter radare2 command pressing the ':' key (like vi does)
-If you want to open the file in read-write mode, invoke r2 with '-w'
-Print the contents of the current block with the 'p' command
-Command layout is: <repeat><command><bytes>@<offset>.  For example: 3x20@0x33 will show 3 hexdumps of 20 bytes at 0x33
-Press 'c' in visual mode to toggle the cursor mode
-Press 'C' in visual mode to toggle colors
-You can 'copy/paste' bytes using the cursor in visual mode 'c' and using the 'y' and 'Y' keys
-Move around the bytes with h,j,k,l! Arrow keys are neither portable nor efficient
-Seek at relative offsets with 's +<offset>' or 's -<offset>'
-Invert the block bytes using the 'I' key in visual mode
-Switch between print modes using the 'p' and 'P' keys in visual mode
-Add comments using the ';' key in visual mode or the 'CC' command from the radare2 shell
-Assemble opcodes with the 'a' and 'A' keys in visual mode, which are bindings to the 'wa' and 'wA' commands
-Find expanded AES keys in memory with '/ca'
-Find wide-char strings with the '/w <string>' command
-Enable ascii-art jump lines in disassembly by setting 'e asm.lines=true'. asm.lines.out and asm.linestyle may interest you as well
-Control the signal handlers of the child process with the 'dk' command
-Get a free shell with 'ragg2 -i exec -x'
-Interpret radare2 scripts with '. <path-to-script>'. Similar to the bash source alias command.
-Most of commands accept '?' as a suffix. Use it to understand how they work :)
-Find hexpairs with '/x a0 cc 33'
-Step through your seek history with the commands 'u' (undo) and 'U' (redo)
-Use hasher to calculate hashes of portion blocks of a file
-Use zoom.byte=entropy and press 'z' in visual mode to zoom out to see the entropy of the whole file
-Use 'zoom.byte=printable' in zoom mode ('z' in Visual mode) to find strings
-Add colors to your screen with 'e scr.color=X' where 1 is 16 colors, 2 is 256 colors and 3 is 16M colors
-Move the comments to the right changing their margin with asm.cmt.margin
-Execute a command on the visual prompt with cmd.vprompt
-Reduce the delta where flag resolving by address is used with cfg.delta
-Disable these messages with 'e cfg.fortunes = false' in your ~/.radare2rc
-Change your fortune types with 'e cfg.fortunes.type = fun,tips,nsfw' in your ~/.radare2rc
-Show offsets in graphs with 'e graph.offset = true'
-Execute a command every time a breakpoint is hit with 'e cmd.bp = !my-program'
-Disassemble in intel syntax with 'e asm.syntax = intel'.
-Change the UID of the debugged process with child.uid (requires root)
-Enhance your graphs by increasing the size of the block and graph.depth eval variable.
-Control the height of the terminal on serial consoles with e scr.height
-Emulate the base address of a file with e file.baddr.
-Bindiff two files with '$ radiff2 /bin/true /bin/false'
-Execute commands on a temporary offset by appending '@ offset' to your command.
-Temporally drop the verbosity prefixing the commands with ':'
-Change the graph block definition with graph.callblocks, graph.jmpblocks, graph.flagblocks
-Use the 'id' command to see the source line related to the current seek
-Analyze socket connections with the socket plugin: 'radare2 socket://www.foo.com:80'. Use 'w' to send data
-To debug a program, you can call r2 with 'dbg://<path-to-program>' or '-d <path..>'
-Use 'e' and 't' in Visual mode to edit configuration and track flags.
-Use 'rabin2 -ris' to get the import/export symbols of any binary.
-Remember to maintain your ~/.radare_history
-Enable the PAGER with 'e scr.pager=less -R'
-Use 'e asm.offset=true' to show offsets in 16bit segment addressing mode.
-The '?' command can be used to evaluate math expressions. Like this: '? (0x34+22)*4'
-Set 'e bin.dbginfo=true' to load debug information at startup.
-Rename a function using the 'afn <newname> @ <offset>' command.
-You can redefine descriptive commands in the hud file and using the 'V_' command.
-Pass '-j' to rabin2 to get the information of the binary in JSON format.
-Use rarun2 to launch your programs with a predefined environment.
-You are probably using an old version of r2, go checkout the git!
-Run your own r2 scripts in awk using the r2awk program.
-Use '-e bin.strings=false' to disable automatic string search when loading the binary.
-The unix-like reverse engineering framework.
-This code was intentionally left blank, try 'e asm.arch = ws'
-Thanks for using radare2!
-give | and > a try piping and redirection
-Run .dmm* to load the flags of the symbols of all modules loaded in the debugger
-Use V or v to enter visual or visual panels modes respectively
-Toggle between disasm and graph with the space key
-The more 'a' you add after 'aa' the more analysis steps are executed.
-Review all the subcommands of aa to see better ways to analyze your targets.
-Use /m to carve for known magic headers. speedup with search.
-You can use registers in math expressions. For example: 'wx 1234 @ esp - 2'
-For HTTP authentication 'e http.auth = 1', 'e http.authfile = <path>'
-Tip: do 'r2pm -i r2premium; echo "e cfg.fortunes.type = nsfw" >> ~/.radare2rc' for a premium r2 experience
-Use the `:` command To run the io plugin cmd callback, many io plugins provide useful features, find them out!
-Change asm.var.summary variable to 0 to display all local variables and argument types and names
diff --git a/doc/fortunes/fun.txt b/doc/fortunes/fun.txt
new file mode 100644 (file)
index 0000000..0578f45
--- /dev/null
@@ -0,0 +1,365 @@
+No disassemble!!!
+Deltify your life with radare2
+In soviet russia, radare2 debugs you!
+What do you want to debug today?
+I love the smell of bugs in the morning.
+I'm in your source securing your bits.
+radare2 contributes to the One Byte Per Child foundation.
+3nl4r9e y0\/r r4d4r3
+I did it for the pwnz.
+If you send the program you are debugging to 15 friends in 143 minutes and then step three times on the same opcode you will get the name of the person who loves you.
+Heisenbug: A bug that disappears or alters its behavior when one attempts to probe or isolate it.
+radare2 is for lulzhats
+Microloft Visual Radare.NET 2008. Now OOXML Powered!
+A C program is like a fast dance on a newly waxed dance floor by people carrying razors - Waldi Ravens
+radare2 is like windows 7 but even better.
+We are surrounded by the enemy. - Excellent, we can attack in any direction!
+radare2-built farm beats the facebook one.
+Thank you for using radare2. Have a nice night!
+Your r2 was built 20h ago. TOO OLD!
+Use radare2! Lemons included!
+rax2 -s 20e296b20ae296b220e296b20a
+Connection lost with the license server, your r2 session will terminate in 30 minutes.
+This is amazing ...
+I love gradients.
+Wait a moment ...
+Don't do this.
+No such file or directory.
+Default scripting languages are NodeJS and Python.
+-bash: r2: command not found
+Press any key to continue ...
+ilo ni li pona li pali e lipu. o musi!
+radare2 for FideOS, now with extra potato
+Your project name should contain an uppercase letter, 8 vowels, some numbers, and the first 5 characters of your private bitcoin key.
+This computer has gone to sleep.
+Have you ever ordered a pizza using radare2?
+I thought we were friends. :_
+Welcome back, lazy human!
+Yo dawg!
+---8<--------------------8<------------------8<-----------------8<------
+I accidentally the kernel with radare2.
+I endians swap.
+This page intentionally left blank.
+Here be dragons.
+Trust no one, nor a zero. Both lie.
+EIP = 0x41414141
+/dev/brain: No such file or directory.
+Virtual machines are great, but you lose the ability to kick the hardware.
+Charlie! We are here.
+The door is everything ...
+The door controls time and space.
+The door can see into your soul.
+I am Pentium of Borg. Division is futile. You will be approximated.
+Don't look at the code. Don't look.
+Dissasemble? No dissasemble, no dissassemble!!!!!
+Warning, your trial license is about to expire.
+Please register your copy of r2 today! Only £29.90!
+Welcome to IDA 10.0.
+It's not you, it's me.
+This software comes with no brain included. Please use your own.
+rm: /: Permission denied.
+That's embarrassing.
+In soviet Afghanistan, you debug radare2!
+Wow, my cat knows radare2 hotkeys better than me!
+Documentation is for weak people.
+PEBCAK ERROR: Documentation not found.
+License server overloaded (ETOOMUCHCASH)
+Error: cannot yank negative sleep
+If you're not satisfied by our product, you may ask for a refund.
+Already up-to-date.
+How about a nice game of chess?
+THE ONLY WINNING MOVE IS NOT TO PLAY.
+SHALL WE PLAY A GAME?
+sudo make me a pancake
+I nodejs so hard my exams. What a nodejs!
+Now featuring NoSQL!
+One does not simply write documentation.
+We are bleeding edge here. Can't you feel the razors?
+There's a branch for that.
+Everything up-to-date.
+Sharing your latest session to Facebook ...
+This should be documented, since it's not that obvious.
+It's working! Look at the door!
+This is an unacceptable million year dungeon.
+The Hard ROP Cafe
+Wait a minute! I found a bug, self-fixing ... OK
+Hold on, this should never happen!
+Well this is embarrassing ...
+THIS IS NOT FUNNY
+♥  --
+Can you stand on your head?
+May the segfault be with you.
+I script in C, because I can.
+EXPLICIT CONTENT
+Bindings are mostly powered by tears.
+In Soviet Russia, radare2 has documentation.
+Initial frame selected; you cannot go up.
+Unk, unk, unk, unk
+Experts agree, security holes suck, and we fixed some of them!
+This is just an existentialist experiment.
+Nothing to see here. Move along.
+Select your character: RBin Wizard, Master Anal Paladin, or Assembly Warrior
+I accidentally radared my filesystem today.
+No fix, no sleep
+You see it, you fix it!
+V is for Visual
+r2-goverity: found corruption - please eliminate!
+Stop debugging me!
+THIS IS NOT A BUG
+Polish reversers blame git
+vm is like a small cow in ascii
+Do you want to print 333.5K chars? (y/N)
+Now with more better English!
+:(){ :|:& };:
+All your base are belong to r2
+Ask not what r2 can do for you - ask what you can do for r2
+Try with ASAN, and be amazed
+bash: r3: command not found
+R2 loves everyone, even Java coders, but less than others
+It's not a bug, it's a work in progress
+Stop swearing!
+I didn't say that it was working, I said that it's implemented
+Wrong argument
+Remember that word: C H A I R
+what happens in #radare, stays in #radare
+For a full list of commands see `strings /dev/urandom`
+Good morning, pal *<:-)
+Of course r2 runs FreeBSD
+Reverser by Birth, r2 by Choice
+Radare2, what else?
+This incident will be reported
+command not found: calc.exe
+See you at the defcon CTF
+Don't waste your time
+WASTED
+getdruid to get eclectic uid
+Welcome to "IDA - the roguelike"
+255 shades of (truecolor) grey
+When you sold that exploit, what they really bought, was your silence.
+Greetings, human.
+nothing personal, just bitness
+Too old to crash
+Finished a beer
+ESIL ruined my life
+ESIL: The Aftersleep
+Insert coin to continue ...
+See you in shell
+Mess with the best, Die like the rest
+Sarah Connor?
+Log On. Hack In. Go Anywhere. Get Everything.
+phrack, better than java in the browser -- jvoisin
+Did you know that radare2 can decompile to assembly?
+Are you still there?
+Follow the white rabbit
+Do not try to sploit that binary - that's impossible. Instead, only try to realize the truth: there is no binary.
+Hello Mr. Anderson
+Try pressing the pigeon-shaped button
+What has been executed cannot be unexecuted
+What about taking a break? Here, have this nice 0xCC.
+r2 is meant to be read by machines.
+Prove you are a robot to continue ...
+This is fine.
+Using radare2 to generate intelligence ...
+Taking the file and moving it somewhere else
+It's the year of desktop on radare2
+💺
+It's the year of radare2 on the desktop
+SSAbotage from ISIL
+"a collection of garbage" -- an r2 pro user
+A git pull a day keeps the segfault away
+Are you a wizard?
+Learn pancake as if you were radare!
+r2 is a great OS, but a terrible hex editor
+THE CAKE IS A PIE
+radare2 0.9.7 is so old, my grandfather was using it with his enigma in WWII
+Have you seen the latest radare2 TV spot?
+scp ~/.idapro/ida.key radare.org:/var/www/radare.org/pub/losers/
+Too bad there is no gif support in r2. Yet. -- @r2gif
+Almost 5am, maybe you should go to bed.
+Jingle sploits, jingle sploits, ropchain all the way.
+Mind that the 'g' in radare is silent
+256 colors ought to be enough for anybody
+Hang in there, Baby!
+Run a command with unspecified long sequence of 'a', pancake will be summoned and do the analysis for you.
+In r2land usability is treated as a bug
+radare2 is WYSIWYF - what you see is what you fix
+Your endian swaps
+*(ut64*)buffer ought to be illegal
+How about Global Thermonuclear War?
+There is no F5 key in radare2 yet
+Did you know that r2 is 10 years old?
+Beer in mind.
+r2 -- leading options since 2006
+Don’t feed the bugs! (except delicious stacktraces)!
+Feed the bugs!
+You haxor! Me jane?
+r2 talks to you. tries to make you feel well.
+Now i'm like an evil engineer. MUAHAHAH
+We only have bugs, features are an unintended side-effect
+There are 5 minutes from WTF to FIX in r2land
+Quantum disassemble: it's there as long as you don't observe it
+Ceci n'est pas une r2pipe
+Buy a mac
+(gdb) ^D
+((fn [f s n] (str (f f s n) "dare2")) (fn [f s n] (pr s) (if (> n 0) (f f (str s "ra") (dec n)) s)) "" (/ 1.0 0))
+There's no way you could crash radare2. No. Way.
+When in doubt, try 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa; pd;'
+.-. .- -.. .- .-. . ..---
+Disassemble?! No Disassemble Johnny No. 5!!!
+You crackme up!
+Welcome, "reenigne"
+Search returned no hits. Did you mean 'Misassemble'?
+º|<|<|  -( glu glu glu, im the r2 fish )
+Everybody hates warnings. Mr. Pancake, tear down this -Wall
+TIRED OF WAITING
+We fix bugs while you sleep.
+You find bugs while we sleep.
+The stripping process is not deep enough
+Come here, we are relatively friendly
+Don't wait for Travis
+Your problems are solved in an abandoned branch somewhere
+git blind --hard
+You need some new glasses
+aaaa is experimental
+We feed trolls
+Mind the tab
+Buy a Mac
+You have been designated for disassembly
+Helping siol merge? No way, that would be like.. way too much not lazy. - vifino
+What is the most complex r2 command? q - then you have to deal with real life /o\
+If you're having fun using radare2, odds are that you're doing something wrong.
+Don't trust what can't be compiled
+Coffee time!
+Can you challenge a perfect immortal machine?
+Add more blockchains to your life.
+Congratulations! You got the segfault 1.000.000! Click [here] to win a prize!
+Well, it looks like it's working.
+There's more than one way to skin a cat
+git pull now
+git checkout hamster
+Noot noot
+This is an unregistered copy.
+10 reasons you want to bt on all threads - you will be shocked by number 3!
+Place a cat on your keyboard while running r2, you'll not believe what will happen next
+This binary may contain traces of human
+Help subcommand will be eventually removed.
+Carpe noctum.
+Your mouse has moved. Radare2 NT must be restarted for the change to take effect. Reboot now? [ OK ]
+There is only one binary, and we are all just reversing pieces of it.
+Radare2 is like violence. If it doesn't solve your problem, you aren't using enough.
+Order pizza for $12.48? [Y/n]
+r2OS r2pad 0.1 SMP GENERIC r2_64 GNU/r2OS
+AHHHHH!!!! ASSEMBLY CODE!!!!!! HOLD ME I'M SCARED!!!!!!!!!!
+In radare we trust
+We don't make mistakes... just happy little segfaults.
+r2 is for the people
+Use headphones for best experience.
+Starting bitcoin miner in background...
+Downloading and verifying the blockchain...
+The anti-virus database has been updated.
+The motion picture contained in this videodisc is protected under the copyright laws.
+This software is sold for home use only and all other rights are expressly reversed by the copyleft owner.
+Any commercial use or duplication of this copylefted material without prior licensing is forbidden.
+Violators will be prosecuted.
+This shell has been seized by the Internet's Police.
+OpenBSD might pledge r2 but r2 unveils OpenBSD.
+Error: There's a missing space before the opening parenthesis '('
+WARNING: r_list_length: assertion 'list' failed (line 55)
+This accessory is not supported by this version of radare2.
+When can we have an official anime mascot for radare2?
+Radare2, we need you to ctrl+s the world.
+Sorry, radare2 has experienced an internal error.
+Segmentation fault (core dumped)
+Use rabin2 to discover the real TRUTH
+==1337== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
+**** COMMODORE 64 RADARE V2 ****  64K RAM SYSTEM  38911 DISASM BYTES FREE  READY.
+Most likely your core dump fell into a blackhole, can't see it.
+Long time no C
+Come to C me!
+Unable to locate package gdb
+You C it, you fix it!
+How good is your C?
+I C dead bugs everywhere!
+You will soon have an out of memory experience.
+This binary no good. Try another.
+BSOD!
+Mind the trap.
+For a full documentation see `r2 -qc iz /lib/libr_core.so`
+99 bugs, take one down pass it around. 100 bugs...
+I like my binary stripped.
+Now 8-bit clean with better ASCII!
+Please insert disc 2 and press any key to continue...
+DOOM all the things!
+Put some sugar before the release, attracts the bugs and makes it easier to squash them
+Stay indoors and await further instructions
+radare2 works best, when pirated.
+I could go up there about 11 at night, stay till 4 in the morning, and get all the computer runs I ever wanted.
+Safety third
+You should try our sister project, radar3!
+This pancake guy sure does know his way around r2.
+make: r2: Command not found
+rip and tear until it compiles
+The r emblem on the front is the legendary symbol for invincibility!
+Send PR or GTFO
+If it's stupid and it works, it is not stupid
+33 + 77 = 100
+radare2[15449] Corpse failure, too many 6
+Process[15449] crashed: radare2. Too many corpses being created.
+You can't sleep now there are monsters nearby
+Every journey begins with a choice
+Do 'r2pm -i r2premium; echo "e cfg.fortunes.type = nsfw" >> ~/.radare2rc' for a even more fun with r2
+pneumonic
+Click below to prove you are not a bot
+Sorry, not sorry.
+fix it or set the machine on fire
+burn it before the bug spreads to other installations
+The signals are strong tonight
+It's dangerous to go alone, take this.
+"If you gotta burn it all to the ground; Then let it burn"
+Watch until the end!
+Don't forget to subscribe!
+Ah shit, here we go again.
+Checking whether this software can be played...
+Will it blend?
+Are you still watching?
+Starting application, this might take some time...
+Do you want to restart to install these updates now or try tonight?
+Updates available
+This binary has not been analyzed. Would you like to analyze it now?
+The software is up to date. Just kidding, git pull again
+Caps lock is on.
+$10 or mistery box?
+INSERT COIN
+This program is not compatible with your device.
+Hey hey hey everyone! welcome to infoflash
+Rise and shine beyond the Black wall
+Relic malfunction detected
+It's now safe to turn off your computer.
+No newline at end of file
+Display output is not active.
+The Quick Brown Fox Jumped Over The Lazy Dog!
+gcc: error: no input files
+Now you're thinking with portals
+The bug you've just found it's fixed in git
+Plug me in, and I'll take you up.
+Plug me in, we're running out of time.
+Corrupted cores! We're in luck.
+You think I'll betray you. And on any other day, you'd be right
+I can't believe you came back.
+You don't have permission to access this resource.
+Sign in or head back to home.
+I'd love to help you solve the tests. But I can't.
+Did anything happen while I was out?
+You look great, by the way. Very healthy
+Press the button again.
+It's been a long time.
+Relic malfunction detected.
+You are offline. Some functionality may be unavailable.
+Patching instructions should be illegal
+Are you still watching?
+Downloading update 1 of 1 ...
+Embrace the failure
+It's like progress but backwards
+My other fortunes are funnier
+Please rotate your phone
+Six seveeen bruh
diff --git a/doc/fortunes/tips.txt b/doc/fortunes/tips.txt
new file mode 100644 (file)
index 0000000..6dc1376
--- /dev/null
@@ -0,0 +1,89 @@
+Tweak the disassembly output with `e asm.`
+Add custom Have you setup your ~/.radare2rc today?
+In visual mode press 'c' to toggle the cursor mode. Use tab to navigate
+You can mark an offset in visual mode with the cursor and the ',' key. Later press '.' to go back
+You can debug a program from the graph view ('ag') using standard radare2 commands
+Use the '[' and ']' keys in visual mode to adjust the screen width
+Select your architecture with: 'e asm.arch=<arch>' or r2 -a from the shell
+Move between your search hits in visual mode using the 'n' and 'N' keys
+Save your projects with 'Ps <project-filename>' and restore then with 'Po <project-filename>'
+Enable asm.trace to see the tracing information inside the disassembly
+Change the registers of the child process in this way: 'dr eax=0x333'
+Check your IO plugins with 'r2 -L'
+Change the size of the file with the 'r' (resize) command
+Calculate current basic block checksum with the ph command (ph md5, ph crc32, ..)
+Use +,-,*,/ to change the size of the block
+Change the block size with 'b <block-size>'. In visual mode you can also enter radare2 command pressing the ':' key (like vi does)
+If you want to open the file in read-write mode, invoke r2 with '-w'
+Print the contents of the current block with the 'p' command
+Command layout is: <repeat><command><bytes>@<offset>.  For example: 3x20@0x33 will show 3 hexdumps of 20 bytes at 0x33
+Press 'c' in visual mode to toggle the cursor mode
+Press 'C' in visual mode to toggle colors
+You can 'copy/paste' bytes using the cursor in visual mode 'c' and using the 'y' and 'Y' keys
+Move around the bytes with h,j,k,l! Arrow keys are neither portable nor efficient
+Seek at relative offsets with 's +<offset>' or 's -<offset>'
+Invert the block bytes using the 'I' key in visual mode
+Switch between print modes using the 'p' and 'P' keys in visual mode
+Add comments using the ';' key in visual mode or the 'CC' command from the radare2 shell
+Assemble opcodes with the 'a' and 'A' keys in visual mode, which are bindings to the 'wa' and 'wA' commands
+Find expanded AES keys in memory with '/ca'
+Find wide-char strings with the '/w <string>' command
+Enable ascii-art jump lines in disassembly by setting 'e asm.lines=true'. asm.lines.out and asm.linestyle may interest you as well
+Control the signal handlers of the child process with the 'dk' command
+Get a free shell with 'ragg2 -i exec -x'
+Interpret radare2 scripts with '. <path-to-script>'. Similar to the bash source alias command.
+Most of commands accept '?' as a suffix. Use it to understand how they work :)
+Find hexpairs with '/x a0 cc 33'
+Step through your seek history with the commands 'u' (undo) and 'U' (redo)
+Use hasher to calculate hashes of portion blocks of a file
+Use zoom.byte=entropy and press 'z' in visual mode to zoom out to see the entropy of the whole file
+Use 'zoom.byte=printable' in zoom mode ('z' in Visual mode) to find strings
+Add colors to your screen with 'e scr.color=X' where 1 is 16 colors, 2 is 256 colors and 3 is 16M colors
+Move the comments to the right changing their margin with asm.cmt.margin
+Execute a command on the visual prompt with cmd.vprompt
+Reduce the delta where flag resolving by address is used with cfg.delta
+Disable these messages with 'e cfg.fortunes = false' in your ~/.radare2rc
+Change your fortune types with 'e cfg.fortunes.type = fun,tips,nsfw' in your ~/.radare2rc
+Show offsets in graphs with 'e graph.offset = true'
+Execute a command every time a breakpoint is hit with 'e cmd.bp = !my-program'
+Disassemble in intel syntax with 'e asm.syntax = intel'.
+Change the UID of the debugged process with child.uid (requires root)
+Enhance your graphs by increasing the size of the block and graph.depth eval variable.
+Control the height of the terminal on serial consoles with e scr.height
+Emulate the base address of a file with e file.baddr.
+Bindiff two files with '$ radiff2 /bin/true /bin/false'
+Execute commands on a temporary offset by appending '@ offset' to your command.
+Temporally drop the verbosity prefixing the commands with ':'
+Change the graph block definition with graph.callblocks, graph.jmpblocks, graph.flagblocks
+Use the 'id' command to see the source line related to the current seek
+Analyze socket connections with the socket plugin: 'radare2 socket://www.foo.com:80'. Use 'w' to send data
+To debug a program, you can call r2 with 'dbg://<path-to-program>' or '-d <path..>'
+Use 'e' and 't' in Visual mode to edit configuration and track flags.
+Use 'rabin2 -ris' to get the import/export symbols of any binary.
+Remember to maintain your ~/.radare_history
+Enable the PAGER with 'e scr.pager=less -R'
+Use 'e asm.offset=true' to show offsets in 16bit segment addressing mode.
+The '?' command can be used to evaluate math expressions. Like this: '? (0x34+22)*4'
+Set 'e bin.dbginfo=true' to load debug information at startup.
+Rename a function using the 'afn <newname> @ <offset>' command.
+You can redefine descriptive commands in the hud file and using the 'V_' command.
+Pass '-j' to rabin2 to get the information of the binary in JSON format.
+Use rarun2 to launch your programs with a predefined environment.
+You are probably using an old version of r2, go checkout the git!
+Run your own r2 scripts in awk using the r2awk program.
+Use '-e bin.strings=false' to disable automatic string search when loading the binary.
+The unix-like reverse engineering framework.
+This code was intentionally left blank, try 'e asm.arch = ws'
+Thanks for using radare2!
+give | and > a try piping and redirection
+Run .dmm* to load the flags of the symbols of all modules loaded in the debugger
+Use V or v to enter visual or visual panels modes respectively
+Toggle between disasm and graph with the space key
+The more 'a' you add after 'aa' the more analysis steps are executed.
+Review all the subcommands of aa to see better ways to analyze your targets.
+Use /m to carve for known magic headers. speedup with search.
+You can use registers in math expressions. For example: 'wx 1234 @ esp - 2'
+For HTTP authentication 'e http.auth = 1', 'e http.authfile = <path>'
+Tip: do 'r2pm -i r2premium; echo "e cfg.fortunes.type = nsfw" >> ~/.radare2rc' for a premium r2 experience
+Use the `:` command To run the io plugin cmd callback, many io plugins provide useful features, find them out!
+Change asm.var.summary variable to 0 to display all local variables and argument types and names
index 88417057a95f9b6947856f14e14c4675dee247d3..d1967977924cf296290ea78ad0013a0cca21fe3d 100644 (file)
@@ -1600,21 +1600,17 @@ static bool cb_completion_maxtab(void *user, void *data) {
        return true;
 }
 
-static bool cb_cfg_fortunes(void *user, void *data) {
-       RCore *core = (RCore *)user;
-       RConfigNode *node = (RConfigNode *)data;
-       if (*node->value == '?') {
-               r_core_fortune_list (core, false);
-               return false;
-       }
-       return true;
-}
-
 static bool cb_cfg_fortunes_type(void *user, void *data) {
        RCore *core = (RCore *)user;
        RConfigNode *node = (RConfigNode *)data;
        if (*node->value == '?') {
-               r_core_fortune_list (core, true);
+               RList *types = r_core_fortune_types (core);
+               char *typ;
+               RListIter *iter;
+               r_list_foreach (types, iter, typ) {
+                       r_cons_println (core->cons, typ);
+               }
+               r_list_free (types);
                return false;
        }
        return true;
@@ -4188,15 +4184,9 @@ R_API int r_core_config_init(RCore *core) {
        char *whoami = r_sys_whoami ();
        SETS ("cfg.user", whoami, "set current username/pid");
        free (whoami);
-       SETCB ("cfg.fortunes", "true", &cb_cfg_fortunes, "if enabled show tips at start");
-       RList *fortune_types = r_core_fortune_types ();
-       if (!fortune_types) {
-               fortune_types = r_list_newf (free);
-               if (fortune_types) {
-                       r_list_append (fortune_types, strdup ("tips"));
-                       r_list_append (fortune_types, strdup ("fun"));
-               }
-       }
+       SETS ("dir.fortunes", R2_DATDIR "/radare2/" R2_VERSION "/fortunes", "directory to load fortune files from");
+       SETB ("cfg.fortunes", "true", "if enabled show tips at start");
+       RList *fortune_types = r_core_fortune_types (core);
        char *fts = r_str_list_join (fortune_types, ",");
        r_list_free (fortune_types);
        char *fortune_desc = r_str_newf ("type of fortunes to show(%s)", fts);
index b5959eb8ee4ad14402a83205da3fb7d1ca18f86c..d6193ed9860ba095dcdb688b402432a9266012e2 100644 (file)
-/* radare2 - LGPL - Copyright 2009-2024 - pancake, condret */
+/* radare2 - LGPL - Copyright 2009-2025 - pancake, condret */
 
 #include <r_core.h>
 
-static char *getFortuneFile(RCore *core, const char *type) {
-       if (!r_sandbox_check (R_SANDBOX_GRAIN_FILES | R_SANDBOX_GRAIN_DISK)) {
-               return NULL;
-       }
-       r_strf_var (fname, 64, "fortunes.%s", type);
-       char *fortunedir = r_xdg_datadir ("fortunes");
-       char *path = r_file_new (fortunedir, fname, NULL);
-       free (fortunedir);
-       if (path && r_file_exists (path)) {
-               return path;
-       }
-       free (path);
-       path = r_file_new (r_sys_prefix (NULL), R2_FORTUNES, fname, NULL);
-       if (path && r_file_exists (path)) {
-               return path;
+static void collect_types(RList *types, const char *base_path) {
+       RList *files = r_sys_dir (base_path);
+       if (files) {
+               RListIter *iter;
+               char *file;
+               r_list_foreach (files, iter, file) {
+                       if (*file == '.') {
+                               continue;
+                       }
+                       // Check for .txt files (new format: <type>.txt)
+                       if (r_str_endswith (file, ".txt")) {
+                               size_t len = strlen (file) - 4;
+                               r_list_append (types, r_str_ndup (file, len));
+                       } else {
+                               // Check for directories (directory name is the type)
+                               char *full_path = r_file_new (base_path, file, NULL);
+                               if (r_file_is_directory (full_path)) {
+                                       r_list_append (types, strdup (file));
+                               }
+                               free (full_path);
+                       }
+               }
+               r_list_free (files);
        }
-       free (path);
-       return NULL;
 }
 
-static bool _push_types(RList *type_list, char *fortune_dir) {
-       RList *files = r_sys_dir (fortune_dir);
+static char *slurp_directory_contents(const char *dir_path) {
+       RList *files = r_sys_dir (dir_path);
        if (!files) {
-               return false;
+               return NULL;
        }
+       RStrBuf *sb = r_strbuf_new (NULL);
+       char *f;
        RListIter *iter;
-       char *file;
-       r_list_foreach (files, iter, file) {
-               if (r_str_startswith (file, "fortunes.") && file[9]) {
-                       r_list_push (type_list, strdup (file + 9));
+       r_list_foreach (files, iter, f) {
+               if (r_str_endswith (f, ".txt")) {
+                       char *file_path = r_file_new (dir_path, f, NULL);
+                       char *file_content = r_file_slurp (file_path, NULL);
+                       if (file_content) {
+                               r_strbuf_append (sb, file_content);
+                               free (file_content);
+                       }
+                       free (file_path);
                }
        }
        r_list_free (files);
-       return true;
+       return r_strbuf_drain (sb);
 }
 
-R_IPI RList *r_core_fortune_types(void) {
-       if (!r_sandbox_check (R_SANDBOX_GRAIN_FILES | R_SANDBOX_GRAIN_DISK)) {
-               return NULL;
-       }
-       RList *types = r_list_newf (free);
-       if (!types) {
-               return NULL;
-       }
-       char *fortune_dir = r_file_new (r_sys_prefix (NULL), R2_FORTUNES, NULL);
-       if (!fortune_dir) {
-               r_list_free (types);
-               return NULL;
-       }
-       if (!_push_types (types, fortune_dir)) {
-               free (fortune_dir);
-               r_list_free (types);
-               return NULL;
-       }
-       free (fortune_dir);
-       fortune_dir = r_xdg_datadir ("fortunes");
-       if (fortune_dir) {
-               _push_types (types, fortune_dir);
-               free (fortune_dir);
+static void collect_fortunes(RStrBuf *sb, const char *base_path, const char *type, const char *fname) {
+       char *path = r_file_new (base_path, type, NULL);
+       if (path) {
+               char *content = slurp_directory_contents (path);
+               if (!content) {
+                       free (path);
+                       path = r_file_new (base_path, fname, NULL);
+                       if (path && r_file_exists (path)) {
+                               content = r_file_slurp (path, NULL);
+                       }
+               }
+               if (content) {
+                       r_strbuf_append (sb, content);
+                       free (content);
+               }
+               free (path);
        }
-       return types;
 }
 
-static void core_fortune_list_types(RCore *core) {
-       RList *types = r_core_fortune_types ();
-       if (types) {
-               char *fts = r_str_list_join (types, "\n");
-               if (fts) {
-                       r_cons_println (core->cons, fts);
-                       free (fts);
-               }
-               r_list_free (types);
-       }
+static char *getFortuneContent(RCore *core, const char *type) {
+       char *xdg_fortunes = r_xdg_datadir ("fortunes");
+       const char *fortunes_dir = r_config_get (core->config, "dir.fortunes");
+       RStrBuf *sb = r_strbuf_new (NULL);
+       r_strf_var (fname, 64, "%s.txt", type);
+       collect_fortunes (sb, xdg_fortunes, type, fname);
+       collect_fortunes (sb, fortunes_dir, type, fname);
+       free (xdg_fortunes);
+       return r_strbuf_drain (sb);
 }
 
-R_API void r_core_fortune_list(RCore *core, bool list_types_instead_of_fortunes) {
-       R_RETURN_IF_FAIL (core);
-       if (list_types_instead_of_fortunes) {
-               core_fortune_list_types (core);
-               return;
-       }
+static char *getRandomLine(RCore *core) {
        if (!r_sandbox_check (R_SANDBOX_GRAIN_FILES | R_SANDBOX_GRAIN_DISK)) {
-               return;
-       }
-       const char *types = (char *)r_config_get (core->config, "cfg.fortunes.type");
-
-       RList *ftypes = r_core_fortune_types ();
-       if (!ftypes) {
-               return;
-       }
-       RListIter *iter;
-       char *fortunes;
-       r_list_foreach (ftypes, iter, fortunes) {
-               if (strstr (types, fortunes)) {
-                       char *file = getFortuneFile (core, fortunes);
-                       char *str = r_file_slurp (file, NULL);
-                       if (!str) {
-                               free (file);
-                               continue;
-                       }
-                       r_cons_println (core->cons, str);
-                       free (str);
-                       free (file);
-               }
+               return NULL;
        }
-       r_list_free (ftypes);
-}
-
-static char *getrandomline(RCore *core) {
-       RList *types = r_str_split_duplist (
-               r_config_get (core->config, "cfg.fortunes.type"), ",", false);
+       /* pick a random fortune type */
+       const char *ft = r_config_get (core->config, "cfg.fortunes.type");
+       RList *types = r_str_split_duplist (ft, ",", false);
        if (r_list_empty (types)) {
                r_list_free (types);
                return NULL;
        }
-       const char *file = (const char *)r_list_get_n (types, r_num_rand (r_list_length (types)));
-       char *type = strdup (file);
+       int rand_type_idx = r_num_rand (r_list_length (types));
+       char *type = r_list_get_n (types, rand_type_idx);
+       char *content = getFortuneContent (core, type);
        r_list_free (types);
-       if (!type) {
-               return NULL;
-       }
-       char *line = NULL, *templine;
-       RList *ftypes = r_core_fortune_types ();
-       if (!ftypes) {
-               free (type);
+       if (R_STR_ISEMPTY (content)) {
+               free (content);
                return NULL;
        }
-       RListIter *iter;
-       char *fortunes;
-       r_list_foreach (ftypes, iter, fortunes) {
-               if (!strcmp (type, fortunes)) {
-                       int lines = 0;
-                       char *file = getFortuneFile (core, fortunes);
-                       if (file) {
-                               templine = r_file_slurp_random_line_count (file, &lines);
-                               if (templine && *templine) {
-                                       free (line);
-                                       line = templine;
-                               }
-                               free (file);
-                       }
+       /* pick a random fortune message, filtering out empty lines */
+       RList *all_lines = r_str_split_list (content, "\n", false);
+       char *result = NULL;
+       int rand_idx = r_num_rand (r_list_length (all_lines));
+       char *line = r_list_get_n (all_lines, rand_idx);
+       if (line) {
+               result = strdup (line);
+       }
+       if (R_STR_ISEMPTY (result)) {
+               free (result); // hack because sometimes we pick empty lines
+               result = getRandomLine (core);
+       }
+       r_list_free (all_lines);
+       free (content);
+       return result;
+}
+
+R_API RList *r_core_fortune_types(RCore *core) {
+       RList *types = r_list_newf (free);
+       if (r_sandbox_check (R_SANDBOX_GRAIN_FILES | R_SANDBOX_GRAIN_DISK)) {
+               char *xdg_fortunes = r_xdg_datadir ("fortunes");
+               if (xdg_fortunes) {
+                       collect_types (types, xdg_fortunes);
+                       free (xdg_fortunes);
                }
+               collect_types (types, r_config_get (core->config, "dir.fortunes"));
+               r_list_uniq_inplace (types, (RListComparatorItem)r_str_hash64);
        }
-       free (type);
-       r_list_free (ftypes);
-       return line;
+       return types;
 }
 
 R_API void r_core_fortune_print_random(RCore *core) {
        R_RETURN_IF_FAIL (core);
-       if (!r_sandbox_check (R_SANDBOX_GRAIN_FILES | R_SANDBOX_GRAIN_DISK)) {
-               return;
-       }
-       char *line = getrandomline (core);
-       if (!line) {
-               line = getrandomline (core);
-       }
-       if (R_STR_ISNOTEMPTY (line)) {
-               if (r_config_get_b (core->config, "cfg.fortunes.clippy")) {
-                       r_core_clippy (core, line);
+       if (r_sandbox_check (R_SANDBOX_GRAIN_FILES | R_SANDBOX_GRAIN_DISK)) {
+               char *line = getRandomLine (core);
+               if (R_STR_ISEMPTY (line)) {
+                       r_cons_println (core->cons, " -- No cookie is also a cookie");
                } else {
-                       r_cons_printf (core->cons, " -- %s\n", line);
-               }
-               if (r_config_get_b (core->config, "cfg.fortunes.tts")) {
-                       r_sys_tts (line, true);
+                       if (r_config_get_b (core->config, "cfg.fortunes.clippy")) {
+                               r_core_clippy (core, line);
+                       } else {
+                               r_cons_printf (core->cons, " -- %s\n", line);
+                       }
+                       if (r_config_get_b (core->config, "cfg.fortunes.tts")) {
+                               r_sys_tts (line, true);
+                       }
                }
                free (line);
        }
index 563147fb8941b34fa0def526eee9ba9cb8b0fb43..64291817523970e5fe783a087ecdc6a13f10b290 100644 (file)
@@ -640,8 +640,7 @@ R_API void r_core_debug_rr(RCore *core, RReg *reg, int mode);
 
 /* fortune */
 R_IPI void cmd_aei(RCore *core);
-R_IPI RList *r_core_fortune_types(void);
-R_API void r_core_fortune_list(RCore *core, bool types);
+R_API RList *r_core_fortune_types(RCore *core);
 R_API void r_core_fortune_print_random(RCore *core);
 
 #define R_CORE_FOREIGN_ADDR -1
index b27ae7296f30bcbe6be8e98acb86d4e01c815328..e4552760f479bf4ca9126cb130da129753edf60c 100644 (file)
@@ -23,7 +23,7 @@ R_LIB_VERSION_HEADER (r_lib);
 // double-indirection required because cpp is crap
 #define STRINGIFY2(x) #x
 #define STRINGIFY(x) STRINGIFY2(x)
-#define R2_ABIVERSION 45
+#define R2_ABIVERSION 46
 #define R2_ABIVERSION_STRING STRINGIFY(R2_ABIVERSION)
 
 #define R_LIB_ENV "R2_LIBR_PLUGINS"
index 361867197b84c446a3afc66aae6dd2531e9fbd15..f53e356c076036fc02d449325e48971c82d98422 100644 (file)
@@ -280,20 +280,18 @@ R_API RList *r_sys_dir(const char *path) {
        WIN32_FIND_DATAW entry;
        char *cfname;
        HANDLE fh = r_sandbox_opendir (path, &entry);
-       if (fh == INVALID_HANDLE_VALUE) {
-               //IFDGB R_LOG_ERROR ("Cannot open directory %ls", wcpath);
-               return list;
-       }
-       list = r_list_newf (free);
-       if (list) {
-               do {
-                       if ((cfname = r_utf16_to_utf8 (entry.cFileName))) {
-                               r_list_append (list, strdup (cfname));
-                               free (cfname);
-                       }
-               } while (FindNextFileW (fh, &entry));
+       if (fh != INVALID_HANDLE_VALUE) {
+               list = r_list_newf (free);
+               if (list) {
+                       do {
+                               if ((cfname = r_utf16_to_utf8 (entry.cFileName))) {
+                                       r_list_append (list, strdup (cfname));
+                                       free (cfname);
+                               }
+                       } while (FindNextFileW (fh, &entry));
+               }
+               FindClose (fh);
        }
-       FindClose (fh);
 #else
        struct dirent *entry;
        DIR *dir = r_sandbox_opendir (path);
index 5fe26687adcef0160c5cef5f59d49cbf33db2776..a9ad257d8ea1d72c63a9e63dbd95b53b774f059a 100644 (file)
@@ -235,7 +235,7 @@ else
   r2_platform = join_paths(r2_datdir_r2, r2_version, 'platform')
   r2_themes = join_paths(r2_datdir_r2, r2_version, 'cons')
   r2_panels = join_paths(r2_datdir_r2, r2_version, 'panels')
-  r2_fortunes = join_paths(r2_datdir, 'doc', 'radare2')
+  r2_fortunes = join_paths(r2_datdir, r2_version, 'fortunes')
   r2_flags = join_paths(r2_datdir_r2, r2_version, 'flag')
   r2_hud = join_paths(r2_datdir_r2, r2_version, 'hud')
   r2_plugins = join_paths(r2_libdir, 'radare2', r2_version)
@@ -678,8 +678,8 @@ subdir('test/unit')
 subdir('test/fuzz')
 
 install_data(
-  'doc/fortunes.fun',
-  'doc/fortunes.tips',
+  'doc/fortunes/fun.txt',
+  'doc/fortunes/tips.txt',
   install_dir: r2_fortunes
 )