System function in C language - creating user from CodeBlocks (C) program - c

I have a problem, i wanted to do a program which will be used to make an account on PC. I write from keyboard name and password which is used to create new user. Everything was okey to the time when i wanted to write command in code, I used "system("net user xxx /add")" where xxx == name of the new user, yes it is working like that, but i want to change xxx to the variable which is written from the keyboard. I mean that, the name of the new user which is creating, the user of program will choose. Any help?
int main()
{
char login;
printf("Login of the new user:");
scanf("%s",&login);
system("net user xxx /add");
return 0;
}

You can use the function sprintf to build a string. It works similar to printf but produces its output in a character array rather than as output to stdout.
For example:
char buffer[100], login[100];
printf("Login of the new user: ");
scanf("%s", login); // notice there is no & operator here
sprintf(buffer, "net user %s /add", login);
system(buffer);
Safer code would use snprintf, which also takes the length of the destination character array as a parameter to ensure that it does not overflow. Also, I'd use fgets rather than scanf as it is inherently safer for the same reason that snprintf is safer than sprintf.
As a side note, for what you're trying to do (add a new user on a Windows system), there are Windows APIs specifically designed for that purpose that you should use rather than calling the net command from system, because these methods will indicate success and failure of attempting to add the user. I concede that there is a very steep learning curve to the Windows API, but if it lets you avoid using the system function, it really is the way to go.

Firstly, you do notscanf towards a variable which is only 1 byte (login). This will just result in buffer overflow and application crash. Since I have the feeling that this is a homework kind of assignment I recommend using an array of chars with help from Since we have snprintf, why we don't have a snscanf?. Otherwise, this answer: C - scanf() vs gets() vs fgets() will give some good directions on how to read (more) safely from the stdin.
Secondly you will need another buffer for creating the net add ... command. For this I recommend using snprintf (https://msdn.microsoft.com/en-us/library/2ts7cx93.aspx) in order to achieve the desired result in a safe manner.
Intentionally I do not post code here to solve this problem, in order to not to hinder your learning, feel free to ask more questions.

Related

How to definitely solve the scanf input stream problem

Suppose I want to run the following C snippet:
scanf("%d" , &some_variable);
printf("something something\n\n");
printf("Press [enter] to continue...")
getchar(); //placed to give the user some time to read the something something
This snippet will not pause! The problem is that the scanf will leave the "enter" (\n)character in the input stream1, messing up all that comes after it; in this context the getchar() will eat the \n and not wait for an actual new character.
Since I was told not to use fflush(stdin) (I don't really get why tho) the best solution I have been able to come up with is simply to redefine the scan function at the start of my code:
void nsis(int *pointer){ //nsis arconim of: no shenanigans integer scanf
scanf("%d" , pointer);
getchar(); //this will clean the inputstream every time the scan function is called
}
And then we simply use nsis in place of scanf. This should fly. However it seems like a really homebrew, put-together-with-duct-tape, solution. How do professional C developers handle this mess? Do they not use scanf at all? Do they simply accept to work with a dirty input stream? What is the standard here?
I wasn't able to find a definite answer on this anywhere! Every source I could find mentioned a different (and sketchy) solution...
EDIT: In response to all commenting some version of "just don't use scanf": ok, I can do that, but what is the purpose of scanf then? Is it simply an useless broken function that should never be used? Why is it in the libraries to begin with then?
This seems really absurd, especially considering all beginners are taught to use scanf...
[1]: The \n left behind is the one that the user typed when inputting the value of the variable some_variable, and not the one present into the printf.
but what is the purpose of scanf then?
An excellent question.
Is it simply a useless broken function that should never be used?
It is almost useless. It is, arguably, quite broken. It should almost never be used.
Why is it in the libraries to begin with then?
My personal belief is that it was an experiment. It tries to be the opposite of printf. But that turned out not to be such a good idea in practice, and the function never got used very much, and pretty much fell out of favor, except for one particular use case...
This seems really absurd, especially considering all beginners are taught to use scanf...
You're absolutely right. It is really quite absurd.
There's a decent reason why all beginners are taught to use scanf, though. During week 1 of your first C programming class, you might write the little program
#include <stdio.h>
int main()
{
int size = 5;
for(int i = 0; i < size; i++) {
for(int j = 0; j < size; j++)
putchar('*');
putchar('\n');
}
}
to print a square. And during that first week, to make a square of a different size, you just edit the line int size = 5; and recompile.
But pretty soon — say, during week 2 — you want a way for the user to enter the size of the square, without having to recompile. You're probably not ready to muck around with argv. You're probably not ready to read a line of text using fgets and convert it back to an integer using atoi. (You're probably not even ready to seriously contemplate the vast differences between the integer 5 and the string "5" at all.) So — during week 2 of your first C programming class — scanf seems like just the ticket.
That's the "one particular use case" I was talking about. And if you only used scanf to read small integers into simple C programs during the second week of your first C programming class, things wouldn't be so bad. (You'd still have problems forgetting the &, but that would be more or less manageable.)
The problem (though this is again my personal belief) is that it doesn't stop there. Virtually every instructor of beginning C classes teaches students to use scanf. Unfortunately, few or none of those instructors ever explicitly tell students that scanf is a stopgap, to be used temporarily during that second week, and to be emphatically graduated beyond in later weeks. And, even worse, many instructors go on to assign more advanced problems, involving scanf, for which it is absolutely not a good solution, such as trying to do robust or "user friendly" input validation.
scanf's only virtue is that it seems like a nice, simple way to get small integers and other simple input from the user into your early programs. But the problem — actually a big, shuddering pile of 17 separate problems — is that scanf turns out to be vastly complicated and full of exceptions and hard to use, precisely the opposite of what you'd want in order to make things easy for beginners. scanf is only useful for beginners, and it's almost perfectly useless for beginners. It has been described as being like square training wheels on a child's bicycle.
How do professional C developers handle this mess?
Quite simply: by not using scanf at all. For one thing, very few production C programs print prompts to a line-based screen and ask users to type something followed by Return. And for those programs that do work that way, professional C developers unhesitatingly use fgets or the like to read a full line of input as text, then use other techniques to break down the line to extract the necessary information.
In answer to your initial question, there's no good answer. One of the fundamental rules of scanf usage (a set of rules, by the way, that no instructor ever teaches) is that you should never try to mix scanf and getchar (or fgets) in the same program. If there were a good way to make your "Press [enter] to continue..." code work after having called scanf, we wouldn't need that rule.
If you do want to try to flush the extra newline, so that a later call to getchar might work, there are several questions here with a bunch of good answers:
scanf() leaves the newline character in the buffer
Using fflush(stdin)
How to properly flush stdin in fgets loop
There's one more unrelated point that ends up being pretty significant to your question. When C was invented, there was no such thing as a GUI with multiple windows. Therefore no C programmer ever had the problem of having their output disappear before they could read it. Therefore no C programmer ever felt the need to write printf("Press [enter] to continue..."); followed by getchar(). I believe (another personal belief) that it is egregiously bad behavior for any vendor of a GUI-based C compiler to rig things up so that the output disappears upon program exit. Persistent output windows ought to be the default, for the benefit of beginning C programmers, with some kind of non-default option to turn that behavior off for those who don't want it.
Is scanf broken? No it is not. It is an excellent input function when you want to parse free form input data where few errors are to be expected. Free form means here that new lines are not relevant exactly as when you read/write very long paragraphs on a normal screen. And few errors expected is common when you read from files.
The scanf family function has another nice point: you have the same syntax when reading from the standard input stream, a file stream or a character string. It can easily parse simple common types and provide a minimal return value to allow cautious programmers to know whether all or part of all the expected data could be decoded.
That being said, it has major drawbacks: first being a C function, it cannot directly control whether the programmer has passed types meeting the format specifications, and second, as beginners are not consistenly hit on their head when they forget to control its return value, it is really too easy to make fully broken programs using it.
But the rule is:
if input is expected to be line oriented, first use fgets to get lines and then sscanf testing return values of both
only if input is expect to be free form (irrelevant newlines), scanf should be used directly. But never without testing its return value except for trivial tests.
Another drawback is that beginners hope it to be clever. It can indeed parse simple input formats, but is only a poor man's parser: do not use it as a generic parser because that is not what it is intended for.
Provided those rules are observed, it is a nice tool consistent with most of C language and its standard library: a simple tool to do simple things. It is up to programmers or library implementers to build richer tools.
I have only be using C language for more than 30 years, and was never bitten by scanf (well I was when I was a beginner, but I now know that I was to blame). Simply I have just tried for decades to only use it for what it can do...

Extracting the domain extension of a URL stored in a string using scanf()

I am writing a code that takes a URL address as a string literal as input, then runs the domain extension of the URL through an array and returns the index if finds a match, -1 if does not.
For example, an input would be www.stackoverflow.com, in this case, I'd need to extract only the com part. In case of www.google.com.tr, I'd need only com again, ignoring the .tr part.
I can think of basically writing a function that'll do that just fine but I'm wondering if it is possible to do it using scanf() itself?
It's really an overhead to use scanf here. But you can do this to realize something similar
char a[MAXLEN],b[MAXLEN],c[MAXLEN];
scanf("%[^.].%[^.].%[^. \n]",a,b,c);
printf("Desired part is = %s\n",c);
To be sure that formatting is correct you can check whether this scanf call is successful or not. For example:
if( 3 != scanf("%[^.].%[^.].%[^. \n]",a,b,c)){
fprintf(stderr,"Format must be atleast sth.something.sth\n");
exit(EXIT_FAILURE);
}
What is the other way of achieving this same thing. Use fgets to read the whole line and then parse with strtok with delimiters ".". This way you will get parts of it. With fgets you can easily support different kind of rules. Instead of incorporating it in scanf (which will be a bit difficult in error case), you can use fgets,strtok to do the same.
With the solution provided above only the first three parts of the url is being considered. Rest are not parsed. But this is hardly the practical situation. Most the time we have to process the whole information, all the parts of the url (and we don't know how many parts can be there). Then you would be better using fgets/strtok as mentioned above.

Replace deprecated gets()

I am using the SLM toolkit by CMU-Cambridge for some baseline language modeling on language data, but when I run one of the built executables, my system detects a buffer overflow when it tries to execute one of the commands.
Based on this StackOverflow question I noticed that __gets_chk+0x179 caused the problem, and I've found two occurrences of gets/fgets in the source code (evallm.c, also available in this GitHub project someone made) but I do not know how to fix them in a proper/secure way.
The relevant parts of the error message:
*** buffer overflow detected ***: /home/CMU-Cam_Toolkit_v2/bin/evallm terminated
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(__gets_chk+0x179)[0x7f613bc719e9]
Aborted
The broken code
# declaration of input string variable
char input_string[500];
# occurence 1
...
while (fgets (wlist_entry, sizeof (wlist_entry),context_cues_fp)) { ... }
...
# occurence 2
...
while (!feof(stdin) && !told_to_quit) {
printf("evallm : ");
gets(input_string);
....
The error basically occurred when the input_string I gave to the evallm command was too long. Normally it is to be called from the command line and you can interactively pass arguments. However, I piped all arguments together with the command (as seen in the example of the docs) but apparently sometimes my argument names where taking too much bytes. When I changed the array length of input_string from 500 to 2000 the problem was solved (so I guess the error was due to occurence 2). But I really would like to fix it by replacing gets() by getline() since it seems to be the right way to go. Or is replacing it by fgets() also a solution? If so, what parameters should I use?
However, when trying to replace gets(), I always get compiling errors. I'm not a C-programmer (Python, Java) and I'm not familiar with the syntax of getline(), so I'm struggling to find the right parameters.
In your particular case, you know that input_string is an array of 500 bytes. (Of course, you could replace that 500 with e.g. 2048)
I am paranoid, adept of defensive programming, and I would zero that buffer before any input, e.g.
memset(input_string, 0, sizeof(input_string));
So the buffer is cleared, even when fgets has failed. In most cases that is in principle useless. But you have corner cases and the evil is in the details.
So read documentation of fgets(3) and replace the gets call with
fgets(input_string, sizeof(input_string), stdin);
(you actually should handle corner cases, e.g. failure of fgets and input line longer than input_string ....)
Of course, you may want to zero the terminating newline. For that, add
int input_len = strlen(input_string);
if (input_len>0) input_string[input_len-1] = '\0`;
(as commented, you might clear the input_string less often, e.g. at start and on fgets failure)
Notice that getline(3) is POSIX specific and is managing a heap-allocated buffer. Read about C dynamic memory allocation. If you are unfamiliar with C programming, that might be tricky to you. BTW, you could even consider using the Linux specific readline(3)
The main point is your familiarity with C programming.
NB: in C, # does not start a comment, but a preprocessor directive.
You replace gets with fgets.
It's almost that simple, the difference (besides the arguments) is that with fgets there might be a newline at the end of the buffer. (Note I say it might be there.)
I recommend this fgets reference.

Limit Console Input Length in C:

I am beginning to design a shell application to run within a Linux terminal for a class I am taking.
This, of course, will involve reading variable-length input strings (commands) from the user. I know that I can simply read each command into a buffer of a size that I would consider appropriate, but this has the potential to either a) truncate the command or b) cause a buffer overflow.
If possible, how can way limit the length of user input to the console?
Say, if I set the command length to 3, 123 would be allowed, but if 123 were already present in the input string (before the user has pressed enter) and the user attempted to add 4, no character would print to the console, perhaps even with an 'error ping'.
I realize that I could design such functionality, but if that is needed, I am not sure where to start to do such a thing.
Either a pre-existing solution or advice on implementing my own solution would be greatly appreciated.
Edit:
I suppose a cheap and easy solution would be to read a command on character at a time until an enter signal is reached or the maximum length is reached. Would problems arise with a solution of this sort?
I have little experience with readline, but here's what you could try:
Write a function that checks rl_end (the number of characters in rl_line_buffer)
If you want to allow more, just return rl_getc
If not, you can use rl_ding
Set the rl_getc_function to call your function as described above
As a side note, if you do use readline, you don't need to limit the input at all (the library manages its memory as it goes). Another (simpler) function you might be interested in is getline.
That kind of low-level control of the console is not something that's included in C's rather basic built-in I/O model.
You need to look into something platform-specific, such as ncurses for Unix-like systems.
Without digging into platform-specific controls, you cannot limit how many characters a used may type in a console before hitting "Enter".
What you can do is check for the presence of a newline character in your input buffer; if it isn't there, then the user typed in more characters than you're prepared to deal with. You can reject that input, and then read stdin repeatedly until you see the newline.
Example:
#include <stdio.h>
#include <string.h>
...
char buf[SIZE];
...
printf("Gimme something: ");
fflush(stdout);
if (fgets(buf, sizeof buf, stdin))
{
char *newline = strchr(buf, '\n');
if (!newline)
{
printf("Input too long: \"%s\"\n", buf);
while (!newline && fgets(buf, sizeof buf, stdin))
newline = strchr(buf, '\n');
}
else
{
// do something with buf
}
}
In response to your edit, terminals are usually line-buffered, allowing users to enter as much as they want before hitting enter without you even knowing about it. You could set the terminal to raw or cbreak mode, but then you're entering platform-specific territory.
Instead, I would suggest that you avoid this problem, and accept that a terminal is a silly vestige from 2 million years ago. Most platforms define LINE_MAX to be the maximum line size any program needs to handle. Beyond that, you can simply assume your user is messing with you, and truncate.

why gets() is not working?

I am programming in C in Unix,
and I am using gets to read the inputs from keyboard.
I always get this warning and the program stop running:
warning: this program uses gets(), which is unsafe.
Can anybody tell me the reason why this is happening?
gets is unsafe because you give it a buffer, but you don't tell it how big the buffer is. The input may write past the end of the buffer, blowing up your program fairly spectacularly. Using fgets instead is a bit better because you tell it how big the buffer is, like this:
const int bufsize = 4096; /* Or a #define or whatever */
char buffer[bufsize];
fgets(buffer, bufsize, stdin);
...so provided you give it the correct information, it doesn't write past the end of the buffer and blow things up.
Slightly OT, but:
You don't have to use a const int for the buffer size, but I would strongly recommend you don't just put a literal number in both places, because inevitably you'll change one but not the other later. The compiler can help:
char buffer[4096];
fgets(buffer, (sizeof buffer / sizeof buffer[0]), stdin);
That expression gets resolved at compile-time, not runtime. It's a pain to type, so I used to use a macro in my usual set of headers:
#define ARRAYCOUNT(a) (sizeof a / sizeof a[0])
...but I'm a few years out of date with my pure C, there's probably a better way these days.
As mentioned in the previous answers use fgets instead of gets.
But it is not like gets doesn't work at all, it is just very very unsafe. My guess is that you have a bug in your code that would appear with fgets as well so please post your source.
EDIT
Based on the updated information you gave in your comment I have a few suggestions.
I recommend searching for a good C tutorial in your native language, Google is your friend here. As a book I would recommend The C Programming Language
If you have new information it is a good idea to edit them into your original post, especially if it is code, it will make it easier for people to understand what you mean.
You are trying to read a string, basically an array of characters, into a single character, that will of course fail. What you want to do is something like the following.
char username[256];
char password[256];
scanf("%s%s", username, password);
Feel free to comment/edit, I am very rusty even in basic C.
EDIT 2 As jamesdlin warned, usage of scanf is as dangerous as gets.
man gets says:
Never use gets(). Because it is
impossible to tell without knowing the
data in advance how many characters
gets() will read, and because
gets() will continue to store
characters past the end of the buffer,
it is extremely dangerous to use. It
has been used to break computer
security. Use fgets() instead.
gets() is unsafe. It takes one parameter, a pointer to a char buffer. Ask yourself how big you have to make that buffer and how long a user can type input without hitting the return key.
Basically, there is no way to prevent a buffer overflow with gets() - use fgets().

Resources