As some DOS application, how to display a pull-down menus in C with ASCII?
(and can be controlled by arrow keys)
like this:
+-------------------- +--------------------
| File | Edit | Help ... | File | Edit | Help ...
+----------+--------- +------+----------+--
| New (N) | | Cut (X) |
| Open (O) | AND | Copy (C) |
| Save (S) | | Undo (U) |
+----------+ +----------+
Which library can I use?
I would suggest using a library like ncurses. Doing this from scratch is pretty tough, but, if you really want, you need to use a lot of printf's and functions to write a character at a certain position.
Here you will find more ncurses alternatives for windows: NCurses-Like System for Windows
Related
I'm working on an security oriented project based on Erlang. This application needs to access some parts of the system restricted to root or other privileged users. Currently, this project will only work on Unix/Linux/BSD systems and should not alter files (read-only access).
I've thought (and tested) some of these solutions, but, I don't know what should I take with Erlang. What is the worst? What is the best? What is the easiest to maintain?
Thanks!
1 node (as root)
This solution is the worst, and, I want to avoid it even on testing servers.
_____________________________
| |
| (root) |
| ___________ _______ |
| | | | | |
| | Erlang VM |<---| Files | |
| |___________| |_______| |
|_____________________________|
You can see here a big picture of what I don't currently want.
#!/usr/bin/env escript
main([]) ->
ok;
main([H|T]) ->
{ok, Data} = file:read_file(H),
io:format("~p: ~p~n", [H,Data]),
main(T).
Run it as root, and voilà.
su - root
${script_path}/readfile.escript /etc/shadow
1 node (as root) + 1 node (as restricted user)
I need to start 2 nodes, one running as root or with another privileged user and one other running node with restricted users, easily accessible from outside world. This method work pretty well but has many issue. Firstly, I can't connect to privileged user node with standard Erlang distributed protocol due to remote procedure call between connected nodes (restricted node can execute arbitrary commands on privileged node). I don't know if Erlang can actually filter RPC before executing them. Secondly, I need to manage two nodes on one host.
________________ ____________________________
| | | |
| (r_user) | | (root) |
| ___________ | | ___________ _______ |
| | | | | | | | | |
| | Erlang VM |<===[socket]===>| Erlang VM |<---| Files | |
| |___________| | | |___________| |_______| |
|________________| |____________________________|
In following examples, I will start two Erlang shell. The first shell will be in restricted mode:
su - myuser
erl -sname restricted -cookie ${mycookie}
The second one will run with a privileged user:
su - root
erl -sname privileged -cookie ${mycookie}
Standard Erlang RPC (not enough security)
Finally, on restricted node (via shell for this example), I can have access to all files:
{ok, Data} = rpc:call(privileged, file, read_file, ["/etc/shadow"]).
With "Firewall" Method
I'm using local unix socket in this example, supported only until R19/R20.
Restricted user need to have access to this socket, stored somewhere in
/var/run.
1 node (as restricted user) + external commands (with sudo)
I give the right to Erlang VM process to execute commands with sudo. I just need to execute specific program, get stdout and parse it. In this case, I need to use existing available programs from my system or create a new one.
________________ _______________________
| | | |
| (r_user) | | (root) |
| ___________ | | ______ _______ |
| | | | | | | | | |
| | Erlang VM |<===[stdin]===>| sudo |<---| Files | |
| |___________| | | |______| |_______| |
|________________| |_______________________|
1 node (as restricted user) + ports (setuid)
I create a ports set with setuid flag. This program has now right to read from files but, I need to place it in secure place on the server. If I want to make it dynamic, I should also define a strict protocol between Erlang VM and this ports. IMO, setuid is rarely a good answer.
________________ ________________________
| | | |
| (r_user) | | (root) [setuid] |
| ___________ | | _______/ _______ |
| | | | | | | | | |
| | Erlang VM |<===[stdin]===>| ports |<---| Files | |
| |___________| | | |_______| |_______| |
|________________| |________________________|
1 node (as restricted user) + NIF
I don't think I can give specific right to a NIF inside Erlang VM, maybe with capsicum or other non-portable/OS-specific kernel features.
_______________
| |
| (r_user) |
| ___________ |
| | | |
| | Erlang VM | |
| |___________| |
| | | |
| | NIF | |
| |___________| | _______
| | | | | |
| | ??? |<---| Files |
| |___________| | |_______|
|_______________|
1 node (as restricted user) + 1 daemon (as root)
I can create a daemon running as root, connected to Erlang VM with an Unix Socket or another methods. This solution is a bit like ports or external command with sudo, except I need to manage a long living daemon with privilege.
________________ _________________________
| | | |
| (r_user) | | (root) |
| ___________ | | ________ _______ |
| | | | | | | | | |
| | Erlang VM |<===[socket]==>| daemon |<---| Files | |
| |___________| | | |________| |_______| |
|________________| |_________________________|
Custom Erlang VM
OpenSSH and lot of other secure software runs as root and create 2 interconnected process with pipes. When starting Erlang VM as root, 2 processes are spawned, one as root, and another in restricted user. When some action require root privilege, restricted process send a request to root process and wait for its answer. I guess its the more complex solution currently, and I don't master enough C and Erlang VM to make this thing working well.
______________ _______________
| | | |
| (root) | | (r_user) |
| __________ | | ___________ |
| | | | | | | |
| | PrivProc |<===[pipe]===>| Erlang VM | |
| |__________| | | |___________| |
|______________| |_______________|
From security perspective your best option is to minimise the amount and complexity of code running with root privileges. So I would rule out all the options when you run a whole Erlang VM as root - there's simply too much code there to lock it down safely.
As long as you only need to read some files, the best option would be to write a small C program that you run from the Erlang VM with sudo. All this program has to do is to open the file for you and hand over the file descriptor to the Erlang process via a Unix socket. I used to work on a project that relied on this technique to open privileged TCP ports, and it worked like a charm. Unfortunately that wasn't an open source project, but with some googling I found this library that does exactly the same thing: https://github.com/msantos/procket
I'd advise you to fork procket and strip down it a bit (you don't seem to need icmp support, only regular files opened in read-only mode).
Once you have the file descriptor in the Erlang VM, you can read from it in different ways:
Using a NIF like procket:read/2 does.
Access the file descriptor as an Erlang port, see the network sniffing example in the procket docs.
I just asked a question here : previous question
Would a Tun/tap device avoid a netmap/pf_ring/dpdk installation ?
If tun/tap allow to bypass kernel, isn't it the same thing ?
Or those codes bring so many optimizations that they overclass tun os bypass strategy ?
I don't quite understand here.
Thanks
TUN/TAP interfaces are virtual network interfaces in which instead of sending and receiving packets from physical media, sends and receives them from user space program. They don't by pass kernel but it's common to set TAP interface as the default interface in order to have a user space program to intercept applications traffic.
Consider below diagram a typical interaction of an userspace program with network interface and network stack.
+--------------------------+
| Network Interface Driver |
+------------+-------------+
|
+------------+-------------+
| Network Stack |
+--------+---+---+---------+
| | | Kernel Space
+----------------------------------------+
| | | User Space
|Sockets|
| | |
+--------+---+---+---------+
| User Space Applications |
+--------------------------+
There’s no way to entirely bypass network stack in case of TAP interface. Userspace applications can still connect to physical interface. Only if a frame specifically is directed to the TAP interface the interceptor application can intercept frames.
+--------------------------+ +--------------------------+
| Network Interface Driver | | TAP Interface |
+------------+-------------+ +--------+----+------------+
| | |
+------------+-------------+ | |
| Network Stack +--------------+ |
+---+------------------+---+ |
| | | Kernel Space
+-------------------------------------------------------------------------+
| | | User Space
Sockets to NIC Sockets to TAP TAP File Descriptor
| | |
+---+------------------+---+ +-------------+------------+
| Normal Applications | | Interceptor Application |
+--------------------------+ +--------------------------+
In case of Netmap once userspace application exclusively acquired the NIC it is up to userspace application to decide which frames (if any) can be injected to the network stack. Therefore we can have the performance of direct packet capturing and take advantage of network stack services when we need them. The exclusive access to NIC is not a good feature always, consider the simple scenario when the NIC has to reply to ARP request.
+-----------------------------------------------------------+
| Netmap Enabled Network Interface Driver |
+-----+-----------------------------------------------------+
|
+-----+-----+ +-----------+ +--------------------------+
| NIC Rings | | Host Ring +------+ Network Stack |
+-----+-----+ +-----+-----+ +--------+---+---+---------+
| | | | | Kernel Space
+-------------------------------------------------------------------------+
| | | | | User Space
MMAP Access MMAP Access |Sockets|
| | | | |
+-----+-------------+------+ +--------+---+---+---------+
| Interceptor Application | | Normal Applications |
+--------------------------+ +--------------------------+
Unfortunatly DPDK doesn’t support “host rings” according to http://dpdk.org/doc/guides/sample_app_ug/netmap_compatibility.html
I’m not certain about PF_RING
Also note in order to utilize NETMAP/PF_RING/DPDK you must modify, recompile or even redesign your application to match to the frameworks.
I'm trying to rename all files that are of *_[m|f].txt to *.txt.
If an instance of _[m|f] appears in the file name, we can assume it always
appears right before the .txt extension.
Examples:
+-----------------------+---------------------+
| input | output |
+-----------------------+---------------------+
| hello_hi_wefwef_f.txt | hello_hi_wefwef.txt |
+-----------------------+---------------------+
| ya_yo_sup_m.txt | ya_yo_sup.txt |
+-----------------------+---------------------+
I am currently trying this:
for i in *_[m|f].txt ; do
mv "$i" "${i/-_[m|f].txt/.txt}"
done
but it's complaining there is no | operator for regex. Is there a simple way to do what I want?
Modify your script like this:
for i in *_[mf].txt; do
mv "$i" "${i/_[fm]\.txt/\.txt}"
done
I'd like to organize the C source code like this:
+ /
|
|___ + ext
| |
| |___ + native_extension
| |
| |___ + lib
| | |
| | |___ (Source files are kept in here - may contain sub-folders)
| |
| |___ native_extension.c
| |___ native_extension.h
| |___ extconf.rb
|
|___ + lib
| |
| |___ (Ruby source code)
|
|___ Rakefile
I'm having trouble getting this setup to work correctly with mkmf. The files in native_extension/lib, which are included by native_extension.c, are being completely ignored.
When I build the extension, only native_extension.{h,c} are compiled, and I get an incomplete native_extension.{so,dll} that gives me symbol lookup errors when I try to run it.
Any way to make this work?
You can use source files from another folders with "extconf.rb" like this:
require 'mkmf'
extension_name = 'native_extension'
dir_config(extension_name)
# enum all source files
$srcs = ["native_extension.c", "lib/file.c"]
# add include path to the internal folder
# $(srcdir) is a root folder, where "extconf.rb" is stored
$INCFLAGS << " -I$(srcdir)/lib"
# add folder, where compiler can search source files
$VPATH << "$(srcdir)/lib"
create_makefile(extension_name)
While you can pass a second argument to make_makefile to specify a different source directory (e.g., make_makfile('native_extension', 'lib')), that would cause it not to include your native_extension.c file. Looking at the source for mkmf.rb, it doesn't appear there's any way to make it look in both places short of rewriting the generated Makefile yourself.
I often have multiple viewports opened in vim, using the :vsp and :sp commands. After I've been editing for a while, I'll often run the :make command from within vim. When I get errors, vim will then show me the lines that gcc says caused my errors. However, vim will often open the file with errors in another viewport, even if that file is already open. An Example:
Before Make
--------------------
| | |
| file 1 | file 2 |
| | |
| | |
--------------------
Ok, assume there are errors in file 2
--------------------
| | |
| file 2 | file 2 |
| | |
| | |
--------------------
vim now jumps to the error line in the left viewport, even though the right viewport already had that file open.
Is there some way to tell vim not to use the file one viewport if the file that the error is in is already open in vim?
Try setting the option switchbuf=useopen.