示例#1
0
文件: main.c 项目: davies/moosefs
static void mfs_fsinit (void *userdata, struct fuse_conn_info *conn) {
	int *piped = (int*)userdata;
	char s;
	conn->max_write = 131072;
	conn->max_readahead = 131072;
#if defined(FUSE_CAP_BIG_WRITES) || defined(FUSE_CAP_DONT_MASK) || defined(FUSE_CAP_FLOCK_LOCKS) || defined(FUSE_CAP_POSIX_LOCKS)
	conn->want = 0;
#endif
#ifdef FUSE_CAP_BIG_WRITES
	conn->want |= FUSE_CAP_BIG_WRITES;
#endif
#ifdef FUSE_CAP_DONT_MASK
	conn->want |= FUSE_CAP_DONT_MASK;
#endif
#ifdef FUSE_CAP_FLOCK_LOCKS
	if (mfsopts.nobsdlocks==0) {
		conn->want |= FUSE_CAP_FLOCK_LOCKS;
	}
#endif
#ifdef FUSE_CAP_POSIX_LOCKS
	if (mfsopts.noposixlocks==0) {
		conn->want |= FUSE_CAP_POSIX_LOCKS;
	}
#endif
	if (piped[1]>=0) {
		s=0;
		if (write(piped[1],&s,1)!=1) {
			syslog(LOG_ERR,"pipe write error: %s",strerr(errno));
		}
		close(piped[1]);
	}
}
示例#2
0
void
get_diskinfo(struct disk_info *dsk, int i)
{
    char path = DEVICE;

    path[strlen(path) - 1] = '0' + i;
    dsk->fd = open(path, O_RDONLY);
    if (dsk->fd < 0) {
        LOG_INFO("Error Opening %s. Error Code %X\n", path, strerr());
        break;
    }
    strcpy(dsk->device_file, path);
    dsk->sector_size = SECTOR_SIZE
}
示例#3
0
文件: devbios.c 项目: Akheon23/nix-os
/*
 * caller must zero or otherwise initialise *rp,
 * other than ax, bx, dx, si & ds.
 */
static int
biosdiskcall(Ureg *up, uchar op, ulong bx, ulong dx, ulong si)
{
	int s;
	uchar err;

	s = splhi();		/* don't let the bios call be interrupted */

	up->ax = op << 8;
	up->bx = bx;
	up->dx = dx;		/* often drive id */
	/*
	 * ensure that dap addr fits in a short.
	 */
	if((si & 0xffff0000) != 0)
		print("biosdiskcall: dap address %#lux not a short\n", si);

	/* assume si is in first 64K */
	if((si & 0xffff0000) != ((si + 512 - 1) & 0xffff0000))
		print("biosdiskcall: dap address %#lux too near segment boundary\n",
			si);
	up->si = si;		/* ds:si forms data access packet addr */
	up->ds = 0;
	up->di = 0;

	/*
	 * *up is copied into low memory (realmoderegs) and thence into
	 * the machine registers before the BIOS call, and the registers are
	 * copied into realmoderegs and thence into *up after.
	 *
	 * realmode loads these registers: di, si, ax, bx, cx, dx, ds, es.
	 */
	realmode(0x13, up);

	splx(s);

	if (up->flags & CF) {
		if (Debug && dx == Baseid) {
			err = up->ax >> 8;
			print("\nbiosdiskcall: int 0x13 op %#ux drive %#lux "
				"failed, ah error code %#ux (%s)\n",
				op, dx, err, strerr(err));
		}
		return -1;
	}
示例#4
0
int get_ndisks()
{
    int fd, ndisks = 0;
    char dev_file = DEVICE;
    do {
        fd = open(path, O_RDONLY);
        if (fd < 0) {
            LOG_INFO("Error Opening %s. Error Code %X\n", path, strerr());
            break;
        }

        close(fd);
        ndisks++;
        path[strlen(path) - 1] = (char)('0' + ndisks);
    } while (fd > 0);

    return ndisks;
}
示例#5
0
文件: main.c 项目: davies/moosefs
int mainloop(struct fuse_args *args,const char* mp,int mt,int fg) {
	struct fuse_session *se;
	struct fuse_chan *ch;
	struct rlimit rls;
	int piped[2];
	char s;
	int err;
	int i;
	md5ctx ctx;
	uint8_t md5pass[16];

	if (mfsopts.passwordask && mfsopts.password==NULL && mfsopts.md5pass==NULL) {
		mfsopts.password = getpass("MFS Password:"******"bad md5 definition (md5 should be given as 32 hex digits)\n");
				return 1;
			}
			p++;
			if (*p>='0' && *p<='9') {
				md5pass[i]+=(*p-'0');
			} else if (*p>='a' && *p<='f') {
				md5pass[i]+=(*p-'a'+10);
			} else if (*p>='A' && *p<='F') {
				md5pass[i]+=(*p-'A'+10);
			} else {
				fprintf(stderr,"bad md5 definition (md5 should be given as 32 hex digits)\n");
				return 1;
			}
			p++;
		}
		if (*p) {
			fprintf(stderr,"bad md5 definition (md5 should be given as 32 hex digits)\n");
			return 1;
		}
		memset(mfsopts.md5pass,0,strlen(mfsopts.md5pass));
	}

	if (mfsopts.delayedinit) {
		fs_init_master_connection(mfsopts.bindhost,mfsopts.masterhost,mfsopts.masterport,mfsopts.meta,mp,mfsopts.subfolder,(mfsopts.password||mfsopts.md5pass)?md5pass:NULL,mfsopts.donotrememberpassword,1);
	} else {
		if (fs_init_master_connection(mfsopts.bindhost,mfsopts.masterhost,mfsopts.masterport,mfsopts.meta,mp,mfsopts.subfolder,(mfsopts.password||mfsopts.md5pass)?md5pass:NULL,mfsopts.donotrememberpassword,0)<0) {
			return 1;
		}
	}
	memset(md5pass,0,16);

	if (fg==0) {
		openlog(STR(APPNAME), LOG_PID | LOG_NDELAY , LOG_DAEMON);
	} else {
#if defined(LOG_PERROR)
		openlog(STR(APPNAME), LOG_PID | LOG_NDELAY | LOG_PERROR, LOG_USER);
#else
		openlog(STR(APPNAME), LOG_PID | LOG_NDELAY, LOG_USER);
#endif
	}

	i = mfsopts.nofile;
	while (1) {
		rls.rlim_cur = i;
		rls.rlim_max = i;
		if (setrlimit(RLIMIT_NOFILE,&rls)<0) {
			i /= 2;
			if (i<1000) {
				break;
			}
		} else {
			break;
		}
	}
	if (i != (int)(mfsopts.nofile)) {
		fprintf(stderr,"can't set open file limit to %d\n",mfsopts.nofile);
		if (i>=1000) {
			fprintf(stderr,"open file limit set to: %d\n",i);
		}
	}

	setpriority(PRIO_PROCESS,getpid(),mfsopts.nice);
#ifdef MFS_USE_MEMLOCK
	if (mfsopts.memlock) {
		rls.rlim_cur = RLIM_INFINITY;
		rls.rlim_max = RLIM_INFINITY;
		if (setrlimit(RLIMIT_MEMLOCK,&rls)<0) {
			mfsopts.memlock=0;
		}
	}
#endif

	piped[0] = piped[1] = -1;
	if (fg==0) {
		if (pipe(piped)<0) {
			fprintf(stderr,"pipe error\n");
			return 1;
		}
		err = fork();
		if (err<0) {
			fprintf(stderr,"fork error\n");
			return 1;
		} else if (err>0) {
			close(piped[1]);
			err = read(piped[0],&s,1);
			if (err==0) {
				s=1;
			}
			return s;
		}
		close(piped[0]);
		s=1;
	}


#ifdef MFS_USE_MEMLOCK
	if (mfsopts.memlock) {
		if (mlockall(MCL_CURRENT|MCL_FUTURE)==0) {
			syslog(LOG_NOTICE,"process memory was successfully locked in RAM");
		}
	}
#endif

/* glibc malloc tuning */
#ifdef MFS_USE_MALLOPT
	if (mfsopts.limitarenas) {
		if (!getenv("MALLOC_ARENA_MAX")) {
			syslog(LOG_NOTICE,"setting glibc malloc arena max to 8");
			mallopt(M_ARENA_MAX, mfsopts.limitarenas);
		}
		if (!getenv("MALLOC_ARENA_TEST")) {
			syslog(LOG_NOTICE,"setting glibc malloc arena test to 1");
			mallopt(M_ARENA_TEST, 1);
		}
	} else {
		syslog(LOG_NOTICE,"setting glibc malloc arenas turned off");
	}
#endif /* glibc malloc tuning */

	syslog(LOG_NOTICE,"monotonic clock function: %s",monotonic_method());
	syslog(LOG_NOTICE,"monotonic clock speed: %"PRIu32" ops / 10 mili seconds",monotonic_speed());

	conncache_init(200);
	chunkloc_cache_init();
	symlink_cache_init();
	negentry_cache_init(mfsopts.negentrycacheto);
//	dir_cache_init();
	fs_init_threads(mfsopts.ioretries);
	if (masterproxy_init(mfsopts.proxyhost)<0) {
		fs_term();
//		dir_cache_term();
		negentry_cache_term();
		symlink_cache_term();
		chunkloc_cache_term();
		return 1;
	}

//	fs_term();
//	negentry_cache_term();
//	symlink_cache_term();
//	chunkloc_cache_term();
//	return 1;

	if (mfsopts.meta==0) {
		csdb_init();
		delay_init();
		read_data_init(mfsopts.readaheadsize*1024*1024,mfsopts.readaheadleng,mfsopts.readaheadtrigger,mfsopts.ioretries);
		write_data_init(mfsopts.writecachesize*1024*1024,mfsopts.ioretries);
	}

 	ch = fuse_mount(mp, args);
	if (ch==NULL) {
		fprintf(stderr,"error in fuse_mount\n");
		if (piped[1]>=0) {
			if (write(piped[1],&s,1)!=1) {
				fprintf(stderr,"pipe write error\n");
			}
			close(piped[1]);
		}
		if (mfsopts.meta==0) {
			write_data_term();
			read_data_term();
			delay_term();
			csdb_term();
		}
		masterproxy_term();
		fs_term();
//		dir_cache_term();
		negentry_cache_term();
		symlink_cache_term();
		chunkloc_cache_term();
		return 1;
	}

	if (mfsopts.meta) {
		mfs_meta_init(mfsopts.debug,mfsopts.entrycacheto,mfsopts.attrcacheto);
		se = fuse_lowlevel_new(args, &mfs_meta_oper, sizeof(mfs_meta_oper), (void*)piped);
	} else {
		mfs_init(mfsopts.debug,mfsopts.keepcache,mfsopts.direntrycacheto,mfsopts.entrycacheto,mfsopts.attrcacheto,mfsopts.xattrcacheto,mfsopts.groupscacheto,mfsopts.mkdircopysgid,mfsopts.sugidclearmode,1,mfsopts.fsyncbeforeclose,mfsopts.noxattrs,mfsopts.noposixlocks,mfsopts.nobsdlocks); //mfsopts.xattraclsupport);
		se = fuse_lowlevel_new(args, &mfs_oper, sizeof(mfs_oper), (void*)piped);
	}
	if (se==NULL) {
		fuse_unmount(mp,ch);
		fprintf(stderr,"error in fuse_lowlevel_new\n");
		portable_usleep(100000);	// time for print other error messages by FUSE
		if (piped[1]>=0) {
			if (write(piped[1],&s,1)!=1) {
				fprintf(stderr,"pipe write error\n");
			}
			close(piped[1]);
		}
		if (mfsopts.meta==0) {
			write_data_term();
			read_data_term();
			delay_term();
			csdb_term();
		}
		masterproxy_term();
		fs_term();
//		dir_cache_term();
		negentry_cache_term();
		symlink_cache_term();
		chunkloc_cache_term();
		return 1;
	}

//	fprintf(stderr,"check\n");
	fuse_session_add_chan(se, ch);

	if (fuse_set_signal_handlers(se)<0) {
		fprintf(stderr,"error in fuse_set_signal_handlers\n");
		fuse_session_remove_chan(ch);
		fuse_session_destroy(se);
		fuse_unmount(mp,ch);
		if (piped[1]>=0) {
			if (write(piped[1],&s,1)!=1) {
				fprintf(stderr,"pipe write error\n");
			}
			close(piped[1]);
		}
		if (mfsopts.meta==0) {
			write_data_term();
			read_data_term();
			delay_term();
			csdb_term();
		}
		masterproxy_term();
		fs_term();
//		dir_cache_term();
		negentry_cache_term();
		symlink_cache_term();
		chunkloc_cache_term();
		return 1;
	}

	if (mfsopts.debug==0 && fg==0) {
		setsid();
		setpgid(0,getpid());
		if ((i = open("/dev/null", O_RDWR, 0)) != -1) {
			(void)dup2(i, STDIN_FILENO);
			(void)dup2(i, STDOUT_FILENO);
			(void)dup2(i, STDERR_FILENO);
			if (i>2) close (i);
		}
	}

	if (mt) {
		err = fuse_session_loop_mt(se);
	} else {
		err = fuse_session_loop(se);
	}
	if (err) {
		if (piped[1]>=0) {
			if (write(piped[1],&s,1)!=1) {
				syslog(LOG_ERR,"pipe write error: %s",strerr(errno));
			}
			close(piped[1]);
		}
	}
	fuse_remove_signal_handlers(se);
	fuse_session_remove_chan(ch);
	fuse_session_destroy(se);
	fuse_unmount(mp,ch);
	if (mfsopts.meta==0) {
		write_data_term();
		read_data_term();
		delay_term();
		csdb_term();
	}
	masterproxy_term();
	fs_term();
//	dir_cache_term();
	negentry_cache_term();
	symlink_cache_term();
	chunkloc_cache_term();
	return err ? 1 : 0;
}
示例#6
0
文件: main.c 项目: twonly/grad
void mainloop() {
	uint32_t prevtime = 0;
	struct timeval tv;
	pollentry *pollit;
	struct pollfd pdesc[MFSMAXFILES];
	timeentry *timeit;
	uint32_t ndesc;
	int i;

	while (!exiting){
		ndesc=0;
		for (pollit = pollhead ; pollit != NULL ; pollit = pollit->next) {
			pollit->desc(pdesc,&ndesc);
		}

		i = poll(pdesc,ndesc,50);
		gettimeofday(&tv,NULL);
		usecnow = tv.tv_sec;
		usecnow *= 1000000;
		usecnow += tv.tv_usec;
		now = tv.tv_sec;

		if (i<0) {
			if (errno==EAGAIN) {
				syslog(LOG_WARNING,"poll returned EAGAIN");
				usleep(100000);
				continue;
			}
			if (errno!=EINTR) {
				syslog(LOG_WARNING,"poll error: %s",strerr(errno));
				break;
			}
		} else {
			for (pollit = pollhead ; pollit != NULL ; pollit = pollit->next) {
				pollit->serve(pdesc);
			}
		}

		if (now<prevtime) {
			// time went backward !!! - recalculate "nextevent" time
			// adding previous_time_to_run prevents from running next event too soon.
			for (timeit = timehead ; timeit != NULL ; timeit = timeit->next) {
				uint32_t previous_time_to_run = timeit->nextevent - prevtime;
				if (previous_time_to_run > timeit->seconds) {
					previous_time_to_run = timeit->seconds;
				}
				timeit->nextevent = ((now / timeit->seconds) * timeit->seconds) + timeit->offset;
				while (timeit->nextevent <= now+previous_time_to_run) {
					timeit->nextevent += timeit->seconds;
				}
			}
		} else if (now>prevtime+3600) {
			// time went forward !!! - just recalculate "nextevent" time
			for (timeit = timehead ; timeit != NULL ; timeit = timeit->next) {
				timeit->nextevent = ((now / timeit->seconds) * timeit->seconds) + timeit->offset;
				while (now >= timeit->nextevent) {
					timeit->nextevent += timeit->seconds;
				}
			}
		}

		for (timeit = timehead ; timeit != NULL ; timeit = timeit->next) {
			if (now >= timeit->nextevent) {
				if (timeit->mode == TIMEMODE_RUN_LATE) {
					while (now >= timeit->nextevent) {
						timeit->nextevent += timeit->seconds;
					}
					timeit->fun();
				} else { /* timeit->mode == TIMEMODE_SKIP_LATE */
					if (now == timeit->nextevent) {
						timeit->fun();
					}
					while (now >= timeit->nextevent) {
						timeit->nextevent += timeit->seconds;
					}
				}
			}
		}

		prevtime = now;
	}
}
示例#7
0
文件: main.c 项目: bhohbaum/moosefs
void makedaemon() {
	int f;
	uint8_t pipebuff[1000];
	ssize_t r;
	size_t happy;
	int piped[2];

	fflush(stdout);
	fflush(stderr);
	if (pipe(piped)<0) {
		fprintf(stderr,"pipe error\n");
		exit(1);
	}
	f = fork();
	if (f<0) {
		syslog(LOG_ERR,"first fork error: %s",strerr(errno));
		exit(1);
	}
	if (f>0) {
		wait(&f);	// just get child status - prevents child from being zombie during initialization stage
		if (f) {
			fprintf(stderr,"Child status: %d\n",f);
			exit(1);
		}
		close(piped[1]);
//		printf("Starting daemon ...\n");
		while ((r=read(piped[0],pipebuff,1000))) {
			if (r>0) {
				if (pipebuff[r-1]==0) {	// zero as a last char in the pipe means error
					if (r>1) {
						happy = fwrite(pipebuff,1,r-1,stderr);
						(void)happy;
					}
					exit(1);
				}
				happy = fwrite(pipebuff,1,r,stderr);
				(void)happy;
			} else {
				fprintf(stderr,"Error reading pipe: %s\n",strerr(errno));
				exit(1);
			}
		}
		exit(0);
	}
	setsid();
	setpgid(0,getpid());
	f = fork();
	if (f<0) {
		syslog(LOG_ERR,"second fork error: %s",strerr(errno));
		if (write(piped[1],"fork error\n",11)!=11) {
			syslog(LOG_ERR,"pipe write error: %s",strerr(errno));
		}
		close(piped[1]);
		exit(1);
	}
	if (f>0) {
		exit(0);
	}
	set_signal_handlers(1);

	close(STDIN_FILENO);
	sassert(open("/dev/null", O_RDWR, 0)==STDIN_FILENO);
	close(STDOUT_FILENO);
	sassert(dup(STDIN_FILENO)==STDOUT_FILENO);
	close(STDERR_FILENO);
	sassert(dup(piped[1])==STDERR_FILENO);
	close(piped[1]);
//	setvbuf(stderr,(char *)NULL,_IOLBF,0);
}
示例#8
0
文件: main.c 项目: bhohbaum/moosefs
void mainloop() {
	uint32_t prevtime = 0;
	struct timeval tv;
	pollentry *pollit;
	eloopentry *eloopit;
	timeentry *timeit;
	ceentry *ceit;
	weentry *weit;
	rlentry *rlit;
	struct pollfd pdesc[MFSMAXFILES];
	uint32_t ndesc;
	int i;
	int t,r;

	t = 0;
	r = 0;
	while (t!=3) {
		ndesc=1;
		pdesc[0].fd = signalpipe[0];
		pdesc[0].events = POLLIN;
		pdesc[0].revents = 0;
		for (pollit = pollhead ; pollit != NULL ; pollit = pollit->next) {
			pollit->desc(pdesc,&ndesc);
		}
		i = poll(pdesc,ndesc,50);
		gettimeofday(&tv,NULL);
		usecnow = tv.tv_sec;
		usecnow *= 1000000;
		usecnow += tv.tv_usec;
		now = tv.tv_sec;
		if (i<0) {
			if (errno==EAGAIN) {
				syslog(LOG_WARNING,"poll returned EAGAIN");
				usleep(100000);
				continue;
			}
			if (errno!=EINTR) {
				syslog(LOG_WARNING,"poll error: %s",strerr(errno));
				break;
			}
		} else {
			if ((pdesc[0].revents)&POLLIN) {
				uint8_t sigid;
				if (read(signalpipe[0],&sigid,1)==1) {
					if (sigid=='\001' && t==0) {
						syslog(LOG_NOTICE,"terminate signal received");
						t = 1;
					} else if (sigid=='\002') {
						syslog(LOG_NOTICE,"reloading config files");
						r = 1;
					}
				}
			}
			for (pollit = pollhead ; pollit != NULL ; pollit = pollit->next) {
				pollit->serve(pdesc);
			}
		}
		for (eloopit = eloophead ; eloopit != NULL ; eloopit = eloopit->next) {
			eloopit->fun();
		}
		if (now<prevtime) {
			// time went backward !!! - recalculate "nextevent" time
			// adding previous_time_to_run prevents from running next event too soon.
			for (timeit = timehead ; timeit != NULL ; timeit = timeit->next) {
				uint32_t previous_time_to_run = timeit->nextevent - prevtime;
				if (previous_time_to_run > timeit->seconds) {
					previous_time_to_run = timeit->seconds;
				}
				timeit->nextevent = ((now / timeit->seconds) * timeit->seconds) + timeit->offset;
				while (timeit->nextevent <= now+previous_time_to_run) {
					timeit->nextevent += timeit->seconds;
				}
			}
		} else if (now>prevtime+3600) {
			// time went forward !!! - just recalculate "nextevent" time
			for (timeit = timehead ; timeit != NULL ; timeit = timeit->next) {
				timeit->nextevent = ((now / timeit->seconds) * timeit->seconds) + timeit->offset;
				while (now >= timeit->nextevent) {
					timeit->nextevent += timeit->seconds;
				}
			}
		}
		for (timeit = timehead ; timeit != NULL ; timeit = timeit->next) {
			if (now >= timeit->nextevent) {
				if (timeit->mode == TIMEMODE_RUN_LATE) {
					while (now >= timeit->nextevent) {
						timeit->nextevent += timeit->seconds;
					}
					timeit->fun();
				} else { /* timeit->mode == TIMEMODE_SKIP_LATE */
					if (now == timeit->nextevent) {
						timeit->fun();
					}
					while (now >= timeit->nextevent) {
						timeit->nextevent += timeit->seconds;
					}
				}
			}
		}
		prevtime = now;
		if (t==0 && r) {
			cfg_reload();
			for (rlit = rlhead ; rlit!=NULL ; rlit=rlit->next ) {
				rlit->fun();
			}
			r = 0;
		}
		if (t==1) {
			for (weit = wehead ; weit!=NULL ; weit=weit->next ) {
				weit->fun();
			}
			t = 2;
		}
		if (t==2) {
			i = 1;
			for (ceit = cehead ; ceit!=NULL && i ; ceit=ceit->next ) {
				if (ceit->fun()==0) {
					i=0;
				}
			}
			if (i) {
				t = 3;
			}
		}
	}
}
示例#9
0
parse()
	{int i,j,found,current, someread;
	char c;

	hash_init();
	routinit();
	line_init();

	someread = 0;			/* indicates haven't read part of a routine */

	empseek(0);
	endbuf = getline(&endline, &endchar, &endcom, & comchar);
	if (progress && endbuf != -1) fprintf(stderr,"parsing\n");
	while(endbuf != -1)			/* getline returns -1 when no more input */
		{
		someread = 1;
		if (progress > 0)
			{
			for (i = begline; i <= endline; i++)
				if (!(i % progress)) fprintf(stderr,"parsing line %d\n",i);
			}
		current = 0;
		for (i = 0; i < endbuf; i++)
			{

			c = buffer[i];
			if(c != '~') 
				{
				found = 0;
				if ( (current < 0 || current >= snum) && current != ABORT)
					{
					strerr("in parsing:","","");
					fprintf(stderr,"line %d of file, parser in invalid state", begline,current);
					fprintf(stderr,"treating it as straight line code\n");
					current = ABORT;
					}
				else
					for (j = match[current];  j < match[current + 1]; j++)
						{
						if ((symclass[j] == 0 && c == symbol[j]) ||
						    (symclass[j] != 0 && classmatch(c,symclass[j]) ))
							{found = 1;  break;
							}
						}
				if (!found)
					{
					error("in syntax:","","");
					fprintf(stderr,"between lines %d and %d of file\n",begline, endline);
					if (debug)
					fprintf(stderr,"symbol '%c' does not match entries for state %d\n",c,current);
					fprintf(stderr,"treating it as straight line code\n");
					current = ABORT;
					}
				else if (!action[j])  
					current = newstate[j];
				else
					{
					current = act(action[j],c,i);
					if (current == nulls)  current = newstate[j];
					}
				if (current == ABORT)  break;
				if (current == endrt)
					{
					return(1);
					}
				}
			}
		line_init();
		endbuf = getline(&endline, &endchar, &endcom,&comchar);
		}
	if (someread) return(1);
	else return(0);
	}
示例#10
0
文件: conf.c 项目: rikiel/crontab
struct list *
read_config(const char *filename)
{
	APP_DEBUG_FNAME;

	struct list *beg_cmd;
	struct list *beg_var;
	struct list *l;
	FILE *in;
	char *line;
	size_t len;
	ssize_t read_len;

	beg_cmd = NULL;
	beg_var = NULL;

	len = CONF_LINE_MAXLENGTH;
	line = alloc_string_size(len);

	in = fopen(filename, "r");
	if (in == NULL) {
		ERR("fopen('%s'): %s", filename, strerr());
		myabort();
	}
	else
	{
		while ((read_len = getline(&line, &len, in)) != -1) {
			// remove \n from the end
			if (read_len > 0)
				line[read_len - 1] = '\0';

			switch (check_line(line)) {
				case LINE_VARIABLE:
					l = malloc(sizeof (struct list));
					l->next = beg_var;
					l->item = create_var(line, beg_var);
					beg_var = l;
					break;
				case LINE_COMMAND:
					l = malloc(sizeof (struct list));
					l->next = beg_cmd;
					l->item = create_cmd(line, beg_var);
					beg_cmd = l;
					break;
				case LINE_BAD:
					WARN("bad line structure '%s'", line);
					break;
				case LINE_IGNORE:
					DEBUG("ignoring line '%s'", line);
					break;
			}
			l = NULL;
		}
		if (ferror(in))
			WARN("ferror while reading '%s', try to continue",
					filename);

		fclose(in);

		print_cfg(beg_var, beg_cmd);
	}
	free(line);
	delete_list(&beg_var);

	return (beg_cmd);
}
示例#11
0
文件: tftp.c 项目: solb/nettftp
// Runs the interactive loop and all file transfers.
// Returns: exit status
int main(void)
{
    // Used to control DNS resolution requests:
    struct addrinfo hints;
    memset(&hints, 0, sizeof hints);
    hints.ai_family = AF_INET;
    hints.ai_socktype = SOCK_DGRAM;

    // Bind to an ephemeral network port:
    struct addrinfo *server = NULL;
    int sfd = openudp(0);
    if(sfd < 0)
        handle_error("bind()");

    // Allocate (small) space to store user input:
    char *buf = malloc(1);
    size_t cap = 1;
    char *cmd; // First word of buf
    size_t len; // Length of cmd

    // Main input loop, which normally only breaks upon a GFO:
    do
    {
        // Keep prompting until the user brings us back something good:
        do
        {
            printf("%s", SHL_PS1);
            readin(&buf, &cap);
        }
        while(homog(buf, ' '));

        // Cleave off the command (first word):
        cmd = strtok(buf, " ");
        len = strlen(cmd);

        if(strncmp(cmd, CMD_CON, len) == 0)
        {
            // Read the arguments:
            const char *hostname = strtok(NULL, " ");
            const char *tmp = strtok(NULL, " ");
            in_port_t port = PORT_UNPRIVILEGED;
            if(tmp)
                port = atoi(tmp);

            // Ensure a hostname or IP has been provided:
            if(!hostname)
            {
                usage(CMD_CON, "hostname", "port");
                continue;
            }

            // Avoid leaking any existing address:
            if(server)
            {
                freeaddrinfo(server);
                server = NULL;
            }

            // Try to resolve the requested hostname:
            if(getaddrinfo(hostname, NULL, &hints, &server))
            {
                fprintf(stderr, "Unable to resolve hostname\n");
                freeaddrinfo(server);
                server = NULL;
                continue;
            }
            ((struct sockaddr_in *)server->ai_addr)->sin_port = htons(port);
        }
        else if(strncmp(cmd, CMD_GET, len) == 0 || strncmp(cmd, CMD_PUT, len) == 0)
        {
            bool putting = strncmp(cmd, CMD_PUT, 1) == 0;

            // Ensure we're already connected to a server:
            if(!server)
            {
                noconn(cmd);
                continue;
            }

            // Make sure we were given a path argument:
            char *pathname = strtok(NULL, "");
            if(!pathname)
            {
                usage(putting ? CMD_PUT : CMD_GET, "pathname", NULL);
                continue;
            }

            // Since basename() might modify pathname, copy it:
            char filename[strlen(pathname)+1];
            memcpy(filename, pathname, sizeof filename);

            int fd;
            if(putting)
            {
                // Try opening the file for reading:
                if((fd = open(pathname, O_RDONLY)) < 0)
                {
                    fprintf(stderr, "local: Unable to read specified file\n");
                    continue;
                }

                // Send a request and record the port used to acknowledge:
                struct sockaddr_in dest_addr;
                sendreq(sfd, basename(filename), OPC_WRQ, server->ai_addr);
                uint8_t *rmtack = recvpkta(sfd, &dest_addr);
                if(iserr(rmtack))
                {
                    fprintf(stderr, "remote: %s\n", strerr(rmtack));
                    free(rmtack);
                    continue;
                }
                free(rmtack);

                // Transmit the file:
                sendfile(sfd, fd, &dest_addr);
            }
            else // getting
            {
                // Try opening a file of that name for writing:
                if((fd = open(basename(filename), O_WRONLY|O_CREAT|O_EXCL, 0666)) < 0)
                {
                    fprintf(stderr, "local: Unable to create the new file\n");
                    continue;
                }

                // Send a request and await the incoming file:
                sendreq(sfd, pathname, OPC_RRQ, server->ai_addr);
                const char *res = recvfile(sfd, fd);
                if(res)
                {
                    fprintf(stderr, "remote: %s\n", res);
                    close(fd);
                    fd = -1;
                    unlink(basename(filename));
                }
            }

            if(fd >= 0)
                close(fd);
        }
        else if(strncmp(cmd, CMD_HLP, len) == 0)
        {
            printf("Commands may be abbreviated.  Commands are:\n\n");
            printf("%s\t\tconnect to remote tftp\n", CMD_CON);
            printf("%s\t\tsend file\n", CMD_PUT);
            printf("%s\t\treceive file\n", CMD_GET);
            printf("%s\t\texit tftp\n", CMD_GFO);
            printf("%s\t\tprint help information\n", CMD_HLP);
        }
        else if(strncmp(cmd, CMD_GFO, len) != 0)
        {
            fprintf(stderr, "%s: unknown directive\n", cmd);
            fprintf(stderr, "Try ? for help.\n");
        }
    }
    while(strncmp(cmd, CMD_GFO, len) != 0);

    free(buf);
    if(server)
        freeaddrinfo(server);

    return 0;
}