Reaching a remote host through a gateway using Emacs and Tramp - emacs

I am attempting to edit a remote file in Emacs, and I'm having trouble getting from the documentation and previous SO questions to doing the thing I want.
I'm working remotely, from a variety of locations, and I want to edit files on server Foo. Server Foo isn't directly reachable from the Internet, but server Bar is, and Foo accepts connections from Bar. I can count on reaching Bar, and Bar can count on reaching Foo.
The Tramp documentation tells me that I need to add to Tramp's proxy list to do this, and that it should look like the following:
(add-to-list 'tramp-default-proxies-alist
("foo_host" "seanm" "/ssh:seanm#bar_host"))
However, when I try that, it doesn't work, and I get inscrutable error messages.
How can I unambiguously refer to Foo? There is no DNS server that knows how to find Foo from its hostname, and Foo's IP address is in the 10.0.0.0/8 private space. I don't want to refer to Foo by that IP address, because that risks colliding with hosts in other 10.0.0.0/8 networks I may visit. As a kludge, I added Foo to Bar's /etc/hosts file, but that didn't seem to work. Is there a better solution?
What quoting rules do I need to adhere to? The examples that I'm seeing use both "double quotes" and `tick-and-single' quotes, the latter apparently requiring double-backslash escaping. I don't understand what's going on there - it seems like there are multiple layers of parsing that this string is going to be shoved through.
While trying variations on this, I've gotten error messages that amount to "you can't use that remote-access method for that scenario." How can I set up a second proxy method that will let me do the equivalent of C-x C-f /su::/path/to/file ?
It all seems very painful compared to the previous multi-hop syntax.
Later: I was able to get the many layers of escaping right so that emacs correctly 'hears' the names of hosts. However, I can't get any hops beyond a second to work correctly, which is a very disappointing lapse in functionality.

The correct answer turned out to be modifying my SSH config with Host, HostAlias, and ProxyCommand directives.

Related

Nagios - adding spaces/tabs/newline Between arguments of Service Check Command

For more readability I would like to add spaces around the arguments in a service's check command. Running a nagios check outputs an error as it seems to want everything on one likeso:
One line check_command definition
However I would like to spcify the check command likeso:
separate lines check command
It’s not possible. Nagios parses configuration attributes by the logic “attribute value \n” so that’s how it has to look.
Other options include breaking it up into multiple check commands, thereby reducing the amount of macros. It’s hard to say since you don’t share the actual text.
On that note, do not share text in pictures. Ever. For any reason. Copy the text and format it as monospaced. If it contains sensitive information, redact it from the text, don’t draw on a picture. Sharing text as pictures is a great way to become very unpopular with colleagues, support personell, and anyone else you come in contact with who has to be able to access the actual text itself, or just want to be able to read it (they may use a screen reader).

Get a full list of TCP ports that exist on a particular (windows/mac) device?

I know the netstat command on both windows (powershell) and mac/linux will return information about the ports in use
Is there some command (or option) to retrieve a full list of all TCP ports that exist on a device, irrespective of whether or not they're in use?
Note: I see an excellent list of IANA assigned port numbers, which goes up to ~65000. But I can't see a specific max, and I'm not sure if all laptops/servers/VMs have that many ports.
Apologies in advance for my lack of knowledge around how ports work; they're something I rarely have need deal with directly.

PowerShell Script to confirm RCF compliant DN in AD

First post!
This is an issue ive come across recently when an LDAP aware application that shall remain nameless is reporting an error in a DN in one of the 19 Domains in the forest but the vendor cant give me any further detail around what the object with the error is other than "We are pretty tight on RFC compliance so it could be anything and we see error 34"
Helpful right.
My other LDAP aware apps are perfectly fine so this is more of a "prove you wrong" type of exercise.
I have a list of DNs exported from every object that has changed in the last 10 days from every domain.
9 days ago is when the thing broke so would capture everything that they are trying to say it would be.
What im hoping to find out is if there is a way for me to run a PS script to check for RFC complaince in the DN string?
I have no ides whats involved with RFC, cant even find a clear explanation of what is and is not accepted.
Anyone have any pointers?
This is just a guess, but it's something that's burned me before: Do you have any accounts with forward slashes in their name? Even Microsoft's own code has problems with that.
The DN would look something like:
CN=test/user,OU=Users,DC=domain,DC=com
That's perfectly valid (at least AD allows it). But if you try to bind to that directly via LDAP, and you just drop it into an LDAP path, you get this:
LDAP://CN=test/user,OU=Users,DC=domain,DC=com
However, in an LDAP path, forward slashes are special characters, so it sees the path as just LDAP://CN=test, which of course won't work. The slash must be escaped (just replace / with \/):
LDAP://CN=test\/user,OU=Users,DC=domain,DC=com
To find out if you have any accounts with slashes in their name, you can do a query like this:
(&(objectClass=user)(cn=*/*))
In PowerShell, you could do that like this:
Get-ADUser -LDAPFilter "(cn=*/*)"
This could also happen if you have any OU's with slashes in their name.

What does internal mean in function names in Emacs Lisp?

Some people use double dash to indicate that the function is subject to change:
What does the double minus (--) convention in function names mean in Emacs Lisp
Does including internal in function names mean similar things?
Two examples
where-is-internal
internal-make-var-non-special
The function where-is-internal has a detailed docstring and is mentioned in the manual as well. Is where-is-internal an exception?
Is there a difference between having -internal as suffix and having internal- as prefix?
Adding to confusion, there are also function names with internal-- (with double dash) as prefix.
The confusion is not just in the naming convention (variability due to history and perhaps sometimes whim). The confusion is in the very notion of "internal" in free software, where the source code is open to everyone to use or modify (even fork) as they please.
To answer your question from (what I think is) the point of view of Emacs Dev, and thus in terms of the underlying intention: "internal" means that someone using such a function is perhaps more likely to encounter future changes in the Emacs-Dev implementation and use of that function than might be the case for a non-"internal" function. IOW, you might not want to count on it remaining as it is now. That's all.
But there's a lot of "perhaps", "more likely", and "might" in there. In practice, some non-"internal" functions change more radically or more quickly than some "internal" functions. It might be the case that for the former there will be a deprecation grace period, during which the pre-change situation is tolerated, i.e., still works. That might not be the case for something "internal". But again, in practice there is some gray between the black of "internal" and the white of non-"internal".
Someone from Emacs Dev (e.g. #Stefan) will perhaps put this differently or correct my interpretation.
My own take: there have sometimes (often) been functions and variables that the author did not expect users to make use of directly, and thus naturally thought of as "internal", which users have nevertheless put to good use, or even "had" to use (modulo rewriting lots of code). Some such have had their "internal" status removed (no, I don't have examples memorized). Or sometimes a new, non-"internal" function has been added to make the behavior available - e.g., a wrapper or function-valued argument has been added (again, I have no offhand examples to give).
IOW, for Emacs Dev too it is not always clear what should be considered "internal". Just take the label as a flag that you might not want to count too much on that function or variable.
Wrt the various notations: My impression is that the -- convention seems recently to be used more (though there is also some old code that uses it); using internal is an older convention, for the most part.
The "internal" and the "--" conventions are similar. Basically "internal" is used when there's no prefix after which to put a double dash (which is usually the case for functions implemented in C).
And yes, as Drew explains, the intention behind the notion of something being "internal" is just to recommend people not use it directly. IOW if they need the corresponding functionality, they should report a bug requesting to promote its status to "non-internal".

Argument passing strategy - environment variables vs. command line

Most of the applications we developers write need to be externally parametrized at startup. We pass file paths, pipe names, TCP/IP addresses etc. So far I've been using command line to pass these to the appplication being launched. I had to parse the command line in main and direct the arguments to where they're needed, which is of course a good design, but is hard to maintain for a large number of arguments. Recently I've decided to use the environment variables mechanism. They are global and accessible from anywhere, which is less elegant from architectural point of view, but limits the amount of code.
These are my first (and possibly quite shallow) impressions on both strategies but I'd like to hear opinions of more experienced developers -- What are the ups and downs of using environment variables and command line arguments to pass arguments to a process? I'd like to take into account the following matters:
design quality (flexibility/maintainability),
memory constraints,
solution portability.
Remarks:
Ad. 1. This is the main aspect I'm interested in.
Ad. 2. This is a bit pragmatic. I know of some limitations on Windows which are currently huge (over 32kB for both command line and environment block). I guess this is not an issue though, since you just should use a file to pass tons of arguments if you need.
Ad. 3. I know almost nothing of Unix so I'm not sure whether both strategies are as similarily usable as on Windows. Elaborate on this if you please.
1) I would recommend avoiding environmental variables as much as possible.
Pros of environmental variables
easy to use because they're visible from anywhere. If lots of independent programs need a piece of information, this approach is a whole lot more convenient.
Cons of environmental variables
hard to use correctly because they're visible (delete-able, set-able) from anywhere. If I install a new program that relies on environmental variables, are they going to stomp on my existing ones? Did I inadvertently screw up my environmental variables when I was monkeying around yesterday?
My opinion
use command-line arguments for those arguments which are most likely to be different for each individual invocation of the program (i.e. n for a program which calculates n!)
use config files for arguments which a user might reasonably want to change, but not very often (i.e. display size when the window pops up)
use environmental variables sparingly -- preferably only for arguments which are expected not to change (i.e. the location of the Python interpreter)
your point They are global and accessible from anywhere, which is less elegant from architectural point of view, but limits the amount of code reminds me of justifications for the use of global variables ;)
My scars from experiencing first-hand the horrors of environmental variable overuse
two programs we need at work, which can't run on the same computer at the same time due to environmental clashes
multiple versions of programs with the same name but different bugs -- brought an entire workshop to its knees for hours because the location of the program was pulled from the environment, and was (silently, subtly) wrong.
2) Limits
If I were pushing the limits of either what the command line can hold, or what the environment can handle, I would refactor immediately.
I've used JSON in the past for a command-line application which needed a lot of parameters. It was very convenient to be able to use dictionaries and lists, along with strings and numbers. The application only took a couple of command line args, one of which was the location of the JSON file.
Advantages of this approach
didn't have to write a lot of (painful) code to interact with a CLI library -- it can be a pain to get many of the common libraries to enforce complicated constraints (by 'complicated' I mean more complex than checking for a specific key or alternation between a set of keys)
don't have to worry about the CLI libraries requirements for order of arguments -- just use a JSON object!
easy to represent complicated data (answering What won't fit into command line parameters?) such as lists
easy to use the data from other applications -- both to create and to parse programmatically
easy to accommodate future extensions
Note: I want to distinguish this from the .config-file approach -- this is not for storing user configuration. Maybe I should call this the 'command-line parameter-file' approach, because I use it for a program that needs lots of values that don't fit well on the command line.
3) Solution portability: I don't know a whole lot about the differences between Mac, PC, and Linux with regard to environmental variables and command line arguments, but I can tell you:
all three have support for environmental variables
they all support command line arguments
Yes, I know -- it wasn't very helpful. I'm sorry. But the key point is that you can expect a reasonable solution to be portable, although you would definitely want to verify this for your programs (for example, are command line args case sensitive on any platforms? on all platforms? I don't know).
One last point:
As Tomasz mentioned, it shouldn't matter to most of the application where the parameters came from.
You should abstract reading parameters using Strategy pattern. Create an abstraction named ConfigurationSource having readConfig(key) -> value method (or returning some Configuration object/structure) with following implementations:
CommandLineConfigurationSource
EnvironmentVariableConfigurationSource
WindowsFileConfigurationSource - loading from a configuration file from C:/Document and settings...
WindowsRegistryConfigurationSource
NetworkConfigrationSource
UnixFileConfigurationSource - - loading from a configuration file from /home/user/...
DefaultConfigurationSource - defaults
...
You can also use Chain of responsibility pattern to chain sources in various configurations like: if command line argument is not supplied, try environment variable and if everything else fails, return defauls.
Ad 1. This approach not only allows you to abstract reading configuration, but you can easily change the underlying mechanism without any affect on client code. Also you can use several sources at once, falling back or gathering configuration from different sources.
Ad 2. Just choose whichever implementation is suitable. Of course some configuration entries won't fit for instance into command line arguments.
Ad 3. If some implementations aren't portable, have two, one silently ignored/skipped when not suitable for a given system.
I think this question has been answered rather well already, but I feel like it deserves a 2018 update. I feel like an unmentioned benefit of environmental variables is that they generally require less boiler plate code to work with. This makes for cleaner more readable code. However a major disadvatnage is that they remove a layers of isolation from different applications running on the same machine. I think this is where Docker really shines. My favorite design pattern is to exclusively use environment variables and run the application inside of a Docker container. This removes the isolation issue.
I generally agree with previous answers, but there is another important aspect: usability.
For example, in git you can create a repository with the .git directory outside of that. To specify that, you can use a command line argument --git-dir or an environmental variable GIT_DIR.
Of course, if you change the current directory to another repository or inherit environmental variables in scripts, you get a mistake. But if you need to type several git commands in a detached repository in one terminal session, this is extremely handy: you don't need to repeat the git-dir argument.
Another example is GIT_AUTHOR_NAME. It seems that it even doesn't have a command line partner (however, git commit has an --author argument). GIT_AUTHOR_NAME overrides the user.name and author.name configuration settings.
In general, usage of command line or environmental arguments is equally simple on UNIX: one can use a command line argument
$ command --arg=myarg
or an environmental variable in one line:
$ ARG=myarg command
It is also easy to capture command line arguments in an alias:
alias cfg='git --git-dir=$HOME/.cfg/ --work-tree=$HOME' # for dotfiles
alias grep='grep --color=auto'
In general most arguments are passed through the command line. I agree with the previous answers that this is more functional and direct, and that environmental variables in scripts are like global variables in programs.
GNU libc says this:
The argv mechanism is typically used to pass command-line arguments specific to the particular program being invoked. The environment, on the other hand, keeps track of information that is shared by many programs, changes infrequently, and that is less frequently used.
Apart from what was said about dangers of environmental variables, there are good use cases of them. GNU make has a very flexible handling of environmental variables (and thus is very integrated with shell):
Every environment variable that make sees when it starts up is transformed into a make variable with the same name and value. However, an explicit assignment in the makefile, or with a command argument, overrides the environment. (-- and there is an option to change this behaviour) ...
Thus, by setting the variable CFLAGS in your environment, you can cause all C compilations in most makefiles to use the compiler switches you prefer. This is safe for variables with standard or conventional meanings because you know that no makefile will use them for other things.
Finally, I would stress that the most important for a program is not programmer, but user experience. Maybe you included that into the design aspect, but internal and external design are pretty different entities.
And a few words about programming aspects. You didn't write what language you use, but let's imagine your tools allow you the best possible argument parsing. In Python I use argparse, which is very flexible and rich. To get the parsed arguments, one can use a command like
args = parser.parse_args()
args can be further split into parsed arguments (say args.my_option), but I can also pass them as a whole to my function. This solution is absolutely not "hard to maintain for a large number of arguments" (if your language allows that). Indeed, if you have many parameters and they are not used during argument parsing, pass them in a container to their final destination and avoid code duplication (which leads to inflexibility).
And the very final comment is that it's much easier to parse environmental variables than command line arguments. An environmental variable is simply a pair, VARIABLE=value. Command line arguments can be much more complicated: they can be positional or keyword arguments, or subcommands (like git push). They can capture zero or several values (recall the command echo and flags like -vvv). See argparse for more examples.
And one more thing. Your worrying about memory is a bit disturbing. Don't write overgeneral programs. A library should be flexible, but a good program is useful without any arguments. If you need to pass a lot, this is probably data, not arguments. How to read data into a program is a much more general question with no single solution for all cases.