DaemonForums  

Go Back   DaemonForums > Miscellaneous > Programming

Programming C, bash, Python, Perl, PHP, Java, you name it.

Reply
 
Thread Tools Display Modes
  #1   (View Single Post)  
Old 26th March 2011
kdu kdu is offline
Port Guard
 
Join Date: Jun 2009
Posts: 25
Thanked 0 Times in 0 Posts
Default Help with struct

I working on a file that invokes <sys/stat>. I've gotten a lot I needed but for the life of me I can't figure where:
Code:
struct stat sb;
Goes.

Here is the file in question:

Code:
#include "wifimgr.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <pwd.h>
#include <sys/stat.h>

#ifndef WITHOUT_NLS
#include <libintl.h>
#else
#define gettext(x)	(x)
#endif


#define	PATH		"/bin:/usr/bin:/sbin:/usr/sbin"

main(int argc, char ** argv) {
	char			line[1024];
	char			cmd[1024];
	int			auth = 0;
	int			copy_stdout;
	char *			arg;
	int			xst;
	

#ifndef WITHOUT_NLS
	/* set output character set */
	bind_textdomain_codeset("wifimgr", "UTF-8");

	/* set language catalog domain */
	textdomain("wifimgr");
#endif

	if (isatty(0) || isatty(1)) {
		fprintf(stderr, gettext("wifimgrsu: for invocation by wifimgr(8) only\n"));
		exit(1);
	}

	/* set line buffering */
	setvbuf(stdin, (char *) NULL, _IOLBF, 0);
	setvbuf(stdout, (char *) NULL, _IOLBF, 0);

	/* set safe PATH (required for shell scripts such as /etc/rc.d/netif) */
	setenv("PATH", PATH, 1);

	/* loop reading commands */
	while (fgets(line, sizeof(line), stdin) != NULL) {
		chop(line);
		if (strncmp(line, "password ", 9) == 0) {
			char *			pass;
			char *			su_pass;

			pass = strdup(index(line, ' ') + 1);
			su_pass = strdup(getpwnam("root")->pw_passwd);
			if (strcmp(crypt(pass, su_pass), su_pass) != 0)
				printf("FAIL %s\n", gettext("invalid password"));
			else {
				auth = 1;
				printf("OK\n");
			}
			continue;
		}

		/* go no further unless authorization passed */
		if (!auth) {
			printf("FAIL %s\n", gettext("not authorized"));
			continue;
		}

		/* flag for commands that produce stdout */
		copy_stdout = 0;
		if (strcmp(line, "cat_netfile") == 0) {
			if (stat(file, &sb) >= 0)
				sprintf(cmd, "%s %s", PATH_CAT, NETWORKS_FILE);
			else
				sprintf(cmd, "");
			copy_stdout = 1;
		}
		else if (strncmp(line, "write_netfile ", 14) == 0) {
			arg = index(line, ' ') + 1;
			sprintf(cmd, "%s %s %s", PATH_CP, arg, NETWORKS_FILE);
		}
		else if (strcmp(line, "diff_netfile") == 0)
			sprintf(cmd, "%s -q %s %s.save >/dev/null", PATH_DIFF, NETWORKS_FILE, NETWORKS_FILE);
		else if (strcmp(line, "backup_netfile") == 0)
			sprintf(cmd, "%s -p %s %s.save", PATH_CP, NETWORKS_FILE, NETWORKS_FILE);
		else if (strncmp(line, "restart_netif ", 14) == 0) {
			arg = index(line, ' ') + 1;
			sprintf(cmd, "%s restart %s >/dev/null 2>&1", PATH_NETIF, arg);
		}
		else if (strncmp(line, "start_netif ", 12) == 0) {
			arg = index(line, ' ') + 1;
			sprintf(cmd, "%s start %s >/dev/null 2>&1", PATH_NETIF, arg);
		}
		else if (strncmp(line, "stop_netif ", 11) == 0) {
			arg = index(line, ' ') + 1;
			sprintf(cmd, "%s stop %s >/dev/null 2>&1", PATH_NETIF, arg);
		}
		else {
			printf("FAIL %s\n", gettext("invalid command"));
			continue;
		}

		xst = system(cmd);

		if (copy_stdout)
			printf("EOF\n");

		if (WEXITSTATUS(xst) == 0)
			printf("OK\n");
		else
			printf("FAIL %s %d\n", gettext("exit status"), WEXITSTATUS(xst));
	}
}
Reply With Quote
  #2   (View Single Post)  
Old 26th March 2011
classicmanpro's Avatar
classicmanpro classicmanpro is offline
Real Name: Turea Alexandru Teodor
Fdisk Soldier
 
Join Date: Oct 2010
Location: Romania (SE Europe)
Posts: 49
Thanked 1 Time in 1 Post
Default

If I remember my C correctly, all variables must be declared at the beginning of the function they're used in. In your case it appears to be used in main.
__________________
A daemon in need is a daemon indeed.
Reply With Quote
  #3   (View Single Post)  
Old 26th March 2011
thirdm thirdm is offline
Package Pilot
 
Join Date: May 2009
Posts: 195
Thanked 3 Times in 3 Posts
Default

They can be declared at the start of a block too, though whether that style is acceptable depends on who you're coding with. I like it as a C++ programmer -- the principle being that the smaller the visibility of the variable the simpler the analysis of program when reading it over for errors -- but it doesn't seem like a principle many C programmers agree with. For instance, the OpenBSD style man page has this to say:

" Parts of a for loop may be left empty. Don't put declarations inside blocks unless the routine is unusually complicated."
Reply With Quote
  #4   (View Single Post)  
Old 26th March 2011
thirdm thirdm is offline
Package Pilot
 
Join Date: May 2009
Posts: 195
Thanked 3 Times in 3 Posts
Default

Oh and if you can use C99 the variable definitions can be intermixed with the statements like in C++, so if you wanted to you could wait to define it until the last possible place. But in the program above the last possible place is the same as the beginning of the if block enclosing the stat call, so there's no difference.
Reply With Quote
  #5   (View Single Post)  
Old 26th March 2011
thirdm thirdm is offline
Package Pilot
 
Join Date: May 2009
Posts: 195
Thanked 3 Times in 3 Posts
Default

One more thing. This code is rife with potential null pointer references and buffer overflows from trusting its input and assuming functions (e.g. index) don't fail and using error prone functions like sprintf.

Say, it wouldn't happen to come from the source code of PHP would it?
Reply With Quote
  #6   (View Single Post)  
Old 30th March 2011
ephemera's Avatar
ephemera ephemera is offline
Knuth's homeboy
 
Join Date: Apr 2008
Posts: 537
Thanked 49 Times in 43 Posts
Default

maybe its defined in "wifimgr.h"
Reply With Quote
  #7   (View Single Post)  
Old 30th March 2011
classicmanpro's Avatar
classicmanpro classicmanpro is offline
Real Name: Turea Alexandru Teodor
Fdisk Soldier
 
Join Date: Oct 2010
Location: Romania (SE Europe)
Posts: 49
Thanked 1 Time in 1 Post
Post

Quote:
Originally Posted by ephemera View Post
maybe its defined in "wifimgr.h"
It might be there but I sincerely hope it isn't. As far as I know, the only variable that should be declared/defined in a header is a constant and, in his case, it's not a constant and it shouldn't be global, not even file static, unless he wants to create some sort of global buffer.
__________________
A daemon in need is a daemon indeed.

Last edited by classicmanpro; 30th March 2011 at 07:10 PM. Reason: Made my reply more explicit
Reply With Quote
  #8   (View Single Post)  
Old 31st March 2011
thirdm thirdm is offline
Package Pilot
 
Join Date: May 2009
Posts: 195
Thanked 3 Times in 3 Posts
Default

Yeah, I think it being defined in the header or declared in the header and defined in some other module can be ruled out. The code isn't good, but it's not that out there.
Reply With Quote
  #9   (View Single Post)  
Old 31st March 2011
ephemera's Avatar
ephemera ephemera is offline
Knuth's homeboy
 
Join Date: Apr 2008
Posts: 537
Thanked 49 Times in 43 Posts
Default

@classicmanpro
like someone said: learn the rules then break them ;-)
Reply With Quote
Old 31st March 2011
thirdm thirdm is offline
Package Pilot
 
Join Date: May 2009
Posts: 195
Thanked 3 Times in 3 Posts
Default

Quote:
Originally Posted by ephemera View Post
@classicmanpro
like someone said: learn the rules then break them ;-)
By keeping a handy global variable around with a two letter name that happens to coincide with example parameter names in man pages maximizing the probability of local variables having the same name and cloaking your global in confusing ways should you ever actually want to look at its value? And this handy little variable is so you can call stat to check the existence of a file (though seemingly you don't care if it exists and is a non-file type like a directory or device node) without the onerous task of adding the variable definition in your block?

Code:
if (some_other_predicate(...)) {
   struct stat sb;
   if (stat(fname, &sb) == -1)
       handle the error.
   else
       act on file or directory or whatever thing is.
       maybe sb has something in it you want to look at, hmm.
}
else ...
Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT. The time now is 01:16 PM.


Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.
Content copyright © 2007-2010, the authors
Daemon image copyright ©1988, Marshall Kirk McKusick