signed evse_cm_slac_match (struct session * session, struct channel * channel, struct message * message)

{
	struct cm_slac_match_request * request = (struct cm_slac_match_request *) (message);
	struct cm_slac_match_confirm * confirm = (struct cm_slac_match_confirm *) (message);
	while (readmessage (channel, message, HOMEPLUG_MMV, (CM_SLAC_MATCH | MMTYPE_REQ)) > 0)
	{
		if (! memcmp (session->RunID, request->MatchVarField.RunID, sizeof (session->RunID)))
		{
			slac_debug (session, 0, __func__, "<-- CM_SLAC_MATCH.REQ");
			memcpy (session->PEV_ID, request->MatchVarField.PEV_ID, sizeof (session->PEV_ID));
			memcpy (session->PEV_MAC, request->MatchVarField.PEV_MAC, sizeof (session->PEV_MAC));
			memcpy (session->RunID, request->MatchVarField.RunID, sizeof (session->RunID));

#if SLAC_DEBUG

			if (_anyset (session->flags, SLAC_VERBOSE))
			{
				char string [256];
				slac_debug (session, 0, __func__, "CM_SLAC_MATCH.REQ.APPLICATION_TYPE %d", request->APPLICATION_TYPE);
				slac_debug (session, 0, __func__, "CM_SLAC_MATCH.REQ.SECURITY_TYPE %d", request->SECURITY_TYPE);
				slac_debug (session, 0, __func__, "CM_SLAC_MATCH.REQ.MVFLength %d", LE16TOH (request->MVFLength));
				slac_debug (session, 0, __func__, "CM_SLAC_MATCH.REQ.PEV_ID %s", HEXSTRING (string, request->MatchVarField.PEV_ID));
				slac_debug (session, 0, __func__, "CM_SLAC_MATCH.REQ.PEV_MAC %s", HEXSTRING (string, request->MatchVarField.PEV_MAC));
				slac_debug (session, 0, __func__, "CM_SLAC_MATCH.REQ.EVSE_ID %s", HEXSTRING (string, request->MatchVarField.EVSE_ID));
				slac_debug (session, 0, __func__, "CM_SLAC_MATCH.REQ.EVSE_MAC %s", HEXSTRING (string, request->MatchVarField.EVSE_MAC));
				slac_debug (session, 0, __func__, "CM_SLAC_MATCH.REQ.RunID %s", HEXSTRING (string, request->MatchVarField.RunID));
			}

#endif

			slac_debug (session, 0, __func__, "--> CM_SLAC_MATCH.CNF");
			memset (message, 0, sizeof (* message));
			EthernetHeader (& confirm->ethernet, session->PEV_MAC, channel->host, channel->type);
			HomePlugHeader1 (& confirm->homeplug, HOMEPLUG_MMV, (CM_SLAC_MATCH | MMTYPE_CNF));
			confirm->APPLICATION_TYPE = session->APPLICATION_TYPE;
			confirm->SECURITY_TYPE = session->SECURITY_TYPE;
			confirm->MVFLength = HTOLE16 (sizeof (confirm->MatchVarField));
			memcpy (confirm->MatchVarField.PEV_ID, session->PEV_ID, sizeof (confirm->MatchVarField.PEV_ID));
			memcpy (confirm->MatchVarField.PEV_MAC, session->PEV_MAC, sizeof (confirm->MatchVarField.PEV_MAC));
			memcpy (confirm->MatchVarField.EVSE_ID, session->EVSE_ID, sizeof (confirm->MatchVarField.EVSE_ID));
			memcpy (confirm->MatchVarField.EVSE_MAC, session->EVSE_MAC, sizeof (confirm->MatchVarField.EVSE_MAC));
			memcpy (confirm->MatchVarField.RunID, session->RunID, sizeof (confirm->MatchVarField.RunID));
			memcpy (confirm->MatchVarField.NID, session->NID, sizeof (confirm->MatchVarField.NID));
			memcpy (confirm->MatchVarField.NMK, session->NMK, sizeof (confirm->MatchVarField.NMK));
			if (sendmessage (channel, message, sizeof (* confirm)) <= 0)
			{
				return (slac_debug (session, 1, __func__, CHANNEL_CANTSEND));
			}
			return (0);
		}
	}
	return (slac_debug (session, session->exit, __func__, "<-- CM_SLAC_MATCH.REQ ?"));
}
Esempio n. 2
0
int attack(int s, char *user, char *password, int idx, char *exec) {
fd_set fs;
int selret, state, len, code;
char buffer[2048] = "";

FD_ZERO(&fs);
FD_SET(s, &fs);

state = SENDUSER;

do {
selret = select(s + 1, &fs, NULL, NULL, NULL);
if (selret > 0 && FD_ISSET(s, &fs)) {
memset(buffer, 0, sizeof(buffer));
len = read(s, buffer, sizeof(buffer));
printf("<<< %s\n", buffer);
sscanf(buffer, "%d", &code);
switch(state) {
case SENDUSER: sendlogin(s, user);
state = SENDPASS;
break;
case SENDPASS: sendpassword(s, password);
state = DELMESSAGE;
break;
case DELMESSAGE: delmessage(s);
state = PURGEMESSAGE;
break;
case PURGEMESSAGE: purgemessage(s);
state = SENDMESSAGE;
break;
case SENDMESSAGE: if (code > 500) {
fprintf(stderr, "[*] login failed\n");
len = -1;
} else if (code == 230) {
fprintf(stderr, "[*] sending exploit code ...\n");
sendexploit(s, user, idx, exec);
state = READMESSAGE;
}
break;
case READMESSAGE: sleep(5);
readmessage(s);
state = READING;
break; 
case READING: if (code == 200 && strstr(buffer, "00000") && strstr(buffer, exec)) {
printf("[*] done\n");
}
break;
}
}
} while (len > 0);
}
signed evse_cm_atten_char (struct session * session, struct channel * channel, struct message * message)

{
	struct cm_atten_char_indicate * indicate = (struct cm_atten_char_indicate *) (message);
	struct cm_atten_char_response * response = (struct cm_atten_char_response *) (message);
	slac_debug (session, 0, __func__, "--> CM_ATTEN_CHAR.IND");
	memset (message, 0, sizeof (* message));
	EthernetHeader (& indicate->ethernet, session->PEV_MAC, channel->host, channel->type);
	HomePlugHeader1 (& indicate->homeplug, HOMEPLUG_MMV, (CM_ATTEN_CHAR | MMTYPE_IND));
	indicate->APPLICATION_TYPE = session->APPLICATION_TYPE;
	indicate->SECURITY_TYPE = session->SECURITY_TYPE;
	memcpy (indicate->ACVarField.SOURCE_ADDRESS, session->PEV_MAC, sizeof (indicate->ACVarField.SOURCE_ADDRESS));
	memcpy (indicate->ACVarField.RunID, session->RunID, sizeof (indicate->ACVarField.RunID));
	memset (indicate->ACVarField.SOURCE_ID, 0, sizeof (indicate->ACVarField.SOURCE_ID));
	memset (indicate->ACVarField.RESP_ID, 0, sizeof (indicate->ACVarField.RESP_ID));
	indicate->ACVarField.NUM_SOUNDS = session->sounds;
	indicate->ACVarField.ATTEN_PROFILE.NumGroups = session->NumGroups;
	memcpy (indicate->ACVarField.ATTEN_PROFILE.AAG, session->AAG, session->NumGroups);
	if (sendmessage (channel, message, sizeof (* indicate)) <= 0)
	{
		return (slac_debug (session, 1, __func__, CHANNEL_CANTSEND));
	}
	if (readmessage (channel, message, HOMEPLUG_MMV, (CM_ATTEN_CHAR | MMTYPE_RSP)) > 0)
	{
		if (! memcmp (session->RunID, response->ACVarField.RunID, sizeof (session->RunID)))
		{
			slac_debug (session, 0, __func__, "<-- CM_ATTEN_CHAR.RSP");

#if SLAC_DEBUG

			if (_anyset (session->flags, SLAC_VERBOSE))
			{
				char string [256];
				slac_debug (session, 0, __func__, "CM_ATTEN_CHAR.RSP.APPLICATION_TYPE %d", response->APPLICATION_TYPE);
				slac_debug (session, 0, __func__, "CM_ATTEN_CHAR.RSP.SECURITY_TYPE %d", response->SECURITY_TYPE);
				slac_debug (session, 0, __func__, "CM_ATTEN_CHAR.RSP.ACVarfield.SOURCE_ADDRESS %s", HEXSTRING (string, response->ACVarField.SOURCE_ADDRESS));
				slac_debug (session, 0, __func__, "CM_ATTEN_CHAR.RSP.ACVarFIeld.RunID %s", HEXSTRING (string, response->ACVarField.RunID));
				slac_debug (session, 0, __func__, "CM_ATTEN_CHAR.RSP.ACVarField.SOURCE_ID %s", HEXSTRING (string, response->ACVarField.SOURCE_ID));
				slac_debug (session, 0, __func__, "CM_ATTEN_CHAR.RSP.ACVarField.RESP_ID %s", HEXSTRING (string, response->ACVarField.RESP_ID));
				slac_debug (session, 0, __func__, "CM_ATTEN_CHAR.RSP.ACVarField.Result %d", response->ACVarField.Result);
			}

#endif

			return (0);
		}
	}
	return (slac_debug (session, session->exit, __func__, "<-- CM_ATTEN_CHAR.RSP ?"));
}
signed evse_cm_start_atten_char (struct session * session, struct channel * channel, struct message * message) 

{ 
	struct cm_start_atten_char_indicate * indicate = (struct cm_start_atten_char_indicate *) (message); 
	if (readmessage (channel, message, HOMEPLUG_MMV, (CM_START_ATTEN_CHAR | MMTYPE_IND)) > 0) 
	{ 
		if (! memcmp (session->RunID, indicate->ACVarField.RunID, sizeof (session->RunID))) 
		{ 
			slac_debug (session, 0, __func__, "<-- CM_START_ATTEN_CHAR.IND"); 

#if SLAC_DEBUG

			if (_anyset (session->flags, SLAC_VERBOSE)) 
			{ 
				char string [256]; 
				slac_debug (session, 0, __func__, "CM_START_ATTEN_CHAR.IND.APPLICATION_TYPE %d", indicate->APPLICATION_TYPE); 
				slac_debug (session, 0, __func__, "CM_START_ATTEN_CHAR.IND.SECURITY_TYPE %d", indicate->SECURITY_TYPE); 
				slac_debug (session, 0, __func__, "CM_START_ATTEN_CHAR.IND.ACVarField.NUM_SOUNDS %d", indicate->ACVarField.NUM_SOUNDS); 
				slac_debug (session, 0, __func__, "CM_START_ATTEN_CHAR.IND.ACVarField.TIME_OUT %d", indicate->ACVarField.TIME_OUT); 
				slac_debug (session, 0, __func__, "CM_START_ATTEN_CHAR.IND.ACVarField.RESP_TYPE %d", indicate->ACVarField.RESP_TYPE); 
				slac_debug (session, 0, __func__, "CM_START_ATTEN_CHAR.IND.ACVarField.FORWARDING_STA %s", HEXSTRING (string, indicate->ACVarField.FORWARDING_STA)); 
				slac_debug (session, 0, __func__, "CM_START_ATTEN_CHAR.IND.ACVarField.RunID %s", HEXSTRING (string, indicate->ACVarField.RunID)); 
			} 

#endif

			if (indicate->APPLICATION_TYPE != session->APPLICATION_TYPE) 
			{ 
				slac_debug (session, session->exit, __func__, "%s: APPLICATION_TYPE", __func__); 
			} 
			if (indicate->SECURITY_TYPE != session->SECURITY_TYPE) 
			{ 
				slac_debug (session, session->exit, __func__, "%s: SECURITY_TYPE", __func__); 
			} 
			session->NUM_SOUNDS = indicate->ACVarField.NUM_SOUNDS; 
			session->TIME_OUT = indicate->ACVarField.TIME_OUT; 
			if (indicate->ACVarField.RESP_TYPE != session->RESP_TYPE) 
			{ 
				slac_debug (session, session->exit, __func__, "%s: RESP_TYPE", __func__); 
			} 
			memcpy (session->FORWARDING_STA, indicate->ACVarField.FORWARDING_STA, sizeof (session->FORWARDING_STA)); 
			return (0); 
		} 
	} 
	return (slac_debug (session, session->exit, __func__, "CM_START_ATTEN_CHAR.IND ?")); 
} 
Esempio n. 5
0
/* ----------------- 
   if dsi->in_write is set attention, tickle (and close?) msg
   aren't sent. We don't care about tickle 
*/
static void pending_request(DSI *dsi)
{
    /* send pending attention */

    /* read msg if any, it could be done in afp_getsrvrmesg */
    if (dsi->msg_request) {
        if (dsi->msg_request == 2) {
            /* didn't send it in signal handler */
            dsi_attention(AFPobj->handle, AFPATTN_MESG | AFPATTN_TIME(5));
        }
        dsi->msg_request = 0;
        readmessage(AFPobj);
    }
    if (dsi->down_request) {
        dsi->down_request = 0;
        dsi_attention(AFPobj->handle, AFPATTN_SHUTDOWN | AFPATTN_NORECONNECT |
                  AFPATTN_MESG | AFPATTN_TIME(5));
    }
}
Esempio n. 6
0
//
//  read in the mailbox and parse into messages.
//
static char*
_readmbox(Mailbox *mb, int doplumb, Mlock *lk)
{
	int fd, n;
	String *tmp;
	Dir *d;
	static char err[128];
	Message *m, **l;
	Inbuf *inb;
	char *x;

	l = &mb->root->part;

	/*
	 *  open the mailbox.  If it doesn't exist, try the temporary one.
	 */
	n = 0;
retry:
	fd = open(mb->path, OREAD);
	if(fd < 0){
		rerrstr(err, sizeof(err));
		if(strstr(err, "exclusive lock") != 0 && n++ < 20){
			sleep(500);	/* wait for lock to go away */
			goto retry;
		}
		if(strstr(err, "exist") != 0){
			tmp = s_copy(mb->path);
			s_append(tmp, ".tmp");
			if(sysrename(s_to_c(tmp), mb->path) == 0){
				s_free(tmp);
				goto retry;
			}
			s_free(tmp);
		}
		return err;
	}

	/*
	 *  a new qid.path means reread the mailbox, while
	 *  a new qid.vers means read any new messages
	 */
	d = dirfstat(fd);
	if(d == nil){
		close(fd);
		errstr(err, sizeof(err));
		return err;
	}
	if(mb->d != nil){
		if(d->qid.path == mb->d->qid.path && d->qid.vers == mb->d->qid.vers){
			close(fd);
			free(d);
			return nil;
		}
		if(d->qid.path == mb->d->qid.path){
			while(*l != nil)
				l = &(*l)->next;
			seek(fd, mb->d->length, 0);
		}
		free(mb->d);
	}
	mb->d = d;
	mb->vers++;
	henter(PATH(0, Qtop), mb->name,
		(Qid){PATH(mb->id, Qmbox), mb->vers, QTDIR}, nil, mb);

	inb = emalloc(sizeof(Inbuf));
	inb->rptr = inb->wptr = inb->data;
	inb->fd = fd;

	//  read new messages
	snprint(err, sizeof err, "reading '%s'", mb->path);
	logmsg(err, nil);
	for(;;){
		if(lk != nil)
			syslockrefresh(lk);
		m = newmessage(mb->root);
		m->mallocd = 1;
		m->inmbox = 1;
		if(readmessage(m, inb) < 0){
			delmessage(mb, m);
			mb->root->subname--;
			break;
		}

		// merge mailbox versions
		while(*l != nil){
			if(memcmp((*l)->digest, m->digest, SHA1dlen) == 0){
				// matches mail we already read, discard
				logmsg("duplicate", *l);
				delmessage(mb, m);
				mb->root->subname--;
				m = nil;
				l = &(*l)->next;
				break;
			} else {
				// old mail no longer in box, mark deleted
				logmsg("disappeared", *l);
				if(doplumb)
					mailplumb(mb, *l, 1);
				(*l)->inmbox = 0;
				(*l)->deleted = 1;
				l = &(*l)->next;
			}
		}
		if(m == nil)
			continue;

		x = strchr(m->start, '\n');
		if(x == nil)
			m->header = m->end;
		else
			m->header = x + 1;
		m->mheader = m->mhend = m->header;
		parseunix(m);
		parse(m, 0, mb, 0);
		logmsg("new", m);

		/* chain in */
		*l = m;
		l = &m->next;
		if(doplumb)
			mailplumb(mb, m, 0);

	}
	logmsg("mbox read", nil);

	// whatever is left has been removed from the mbox, mark deleted
	while(*l != nil){
		if(doplumb)
			mailplumb(mb, *l, 1);
		(*l)->inmbox = 0;
		(*l)->deleted = 1;
		l = &(*l)->next;
	}

	close(fd);
	free(inb);
	return nil;
}
Esempio n. 7
0
/**********************************************************************
* edit room description
* Ask user if they want to edit <R>oom aide only, <D>escription only,
* <B>oth, or <Q>uit.
* Contingent on option chosen, edit the item(s).  When done, write
* the description to the descfile.
* raname is taken either from reading the description or set anew.
* If a new aide is chosen, read his/her user file and assign ->usernum
* to be roomaide.
**********************************************************************/
void
editdesc(void)
{
char    choice = '0';
char    descfile[100];
char    newdescfile[100];
int     dfd;		/* desc file descriptor */
int     dummy;		/* readmsg() needs this: returns YES/NO */
int     err;		/* makemessage returns this */
char    raname[MAXALIAS+1];
int	upload;
char   *cp;
struct mheader *mh;
int size;
unsigned char *infop;
struct user *tmpuser;

  sprintf(descfile, "%sroom%d", DESCDIR, curr);
  sprintf(newdescfile, "%sroom%d.NEW", DESCDIR, curr);

  size = 0;
  if (!(infop = (unsigned char *)mymmap(descfile, &size, 0)) || !size)
  {
    colorize("@RDescription doesn't yet exist@G\n");
    choice = 'B';
  }
  else
  {
    readmessage(infop, &dummy, raname, FALSE, 0);
    munmap((void *)infop, size);
  }

  /* if it's a new description, don't bother prompting for choice */
  if (choice != 'B')
  {
    printf("\nEdit <F>orum moderator only, <D>escription only, <B>oth, <Q>uit -> ");
    choice = get_single_quiet("FDBQ \n");
    putchar('\n');
  }
  if (choice == 'Q' || choice == ' ' || choice == '\n')
    return;

  if (choice == 'B' || choice == 'F')
  {
    cp = get_name("\nNew forum moderator -> ", 2);
    if (!*cp)
      return;

    if (!strcmp(cp, "Sysop"))
      msg->room[curr].roomaide = 0;
    else
      if (!(tmpuser = getuser(cp)) || tmpuser->f_invisible)
      {
	if (tmpuser)
	  freeuser(tmpuser);
	printf("\nThere is no user %s on this BBS.\n", cp);
        return;
      }
      else
      {
        msg->room[curr].roomaide = tmpuser->usernum;
	freeuser(tmpuser);
      }

    if (choice == 'F')
      return;
  }

  printf("\nHit Y to upload a description or N to enter it normally (Y/N) -> ");
  if ((upload = yesno(-1)))
    printf("\n(Use control-D to end!)\n");

  printf("\nEnter a new forum description...\n\n");

  err = makemessage(NULL, MES_DESC, upload);

  if (err == ABORT)
    colorize("@RDescription not entered\n@G");
  else if (err != SAVE)
    colorize("@RSome mystical error - can't make description\n@G");
  else if ((dfd = open(newdescfile, O_WRONLY | O_CREAT | O_EXCL, 0640)) < 0)
    printf("error opening desc file to make final copy\n");
  else
  {
    mh = (struct mheader *)(void *)tmpstart;
    write(dfd, tmpstart, mh->hlen + mh->len + 1);
    close(dfd);
    rename(newdescfile, descfile);
  }
  munmap((void *)tmpstart, 53248);
  if (err == SAVE)
  {
    printf("\nMark forum info as having been updated? (Y/N) -> ");
    if (yesno(-1))
      msg->room[curr].descupdate = msg->room[curr].highest;
  }
}
Esempio n. 8
0
signed pev_cm_slac_param (struct session * session, struct channel * channel, struct message * message) 

{ 
	extern byte const broadcast [ETHER_ADDR_LEN]; 
	struct cm_slac_param_request * request = (struct cm_slac_param_request *) (message); 
	struct cm_slac_param_confirm * confirm = (struct cm_slac_param_confirm *) (message); 
	slac_debug (session, 0, __func__, "--> CM_SLAC_PARAM.REQ"); 
	memset (message, 0, sizeof (* message)); 
	EthernetHeader (& request->ethernet, broadcast, channel->host, channel->type); 
	HomePlugHeader1 (& request->homeplug, HOMEPLUG_MMV, (CM_SLAC_PARAM | MMTYPE_REQ)); 
	request->APPLICATION_TYPE = session->APPLICATION_TYPE; 
	request->SECURITY_TYPE = session->SECURITY_TYPE; 
	memcpy (request->RunID, session->RunID, sizeof (request->RunID)); 
	request->CipherSuite [0] = HTOLE16 ((uint16_t) (session->counter)); 
	if (sendmessage (channel, message, (ETHER_MIN_LEN - ETHER_CRC_LEN)) <= 0) 
	{ 
		return (slac_debug (session, 1, __func__, CHANNEL_CANTSEND)); 
	} 
	while (readmessage (channel, message, HOMEPLUG_MMV, (CM_SLAC_PARAM | MMTYPE_CNF)) > 0) 
	{ 
		if (! memcmp (session->RunID, confirm->RunID, sizeof (session->RunID))) 
		{ 
			slac_debug (session, 0, __func__, "<-- CM_SLAC_PARAM.CNF"); 
			if (confirm->APPLICATION_TYPE != session->APPLICATION_TYPE) 
			{ 
				slac_debug (session, session->exit, __func__, "Unexpected APPLICATION_TYPE"); 
			} 
			if (confirm->SECURITY_TYPE != session->SECURITY_TYPE) 
			{ 
				slac_debug (session, session->exit, __func__, "Unexpected SECURITY_TYPE"); 
			} 
			if (_anyset (session->flags, SLAC_COMPARE)) 
			{ 
				if (LE16TOH (confirm->CipherSuite) != (uint16_t) (session->counter)) 
				{ 
					slac_debug (session, session->exit, __func__, "session->counter mismatch! PEV=(%d) EVSE=(%d)", LE16TOH (confirm->CipherSuite), session->counter); 
				} 
			} 

#if SLAC_DEBUG

			if (_anyset (session->flags, SLAC_VERBOSE)) 
			{ 
				char string [256]; 
				slac_debug (session, 0, __func__, "CM_SLAC_PARAM.CNF.MSOUND_TARGET %s", HEXSTRING (string, confirm->MSOUND_TARGET)); 
				slac_debug (session, 0, __func__, "CM_SLAC_PARAM.CNF.NUM_SOUNDS %d", confirm->NUM_SOUNDS); 
				slac_debug (session, 0, __func__, "CM_SLAC_PARAM.CNF.TIME_OUT %d", confirm->TIME_OUT); 
				slac_debug (session, 0, __func__, "CM_SLAC_PARAM.CNF.RESP_TYPE %d", confirm->RESP_TYPE); 
				slac_debug (session, 0, __func__, "CM_SLAC_PARAM.CNF.FORWARDING_STA %s", HEXSTRING (string, confirm->FORWARDING_STA)); 
				slac_debug (session, 0, __func__, "CM_SLAC_PARAM.CNF.APPLICATION_TYPE %d", confirm->APPLICATION_TYPE); 
				slac_debug (session, 0, __func__, "CM_SLAC_PARAM.CNF.SECURITY_TYPE %d", confirm->SECURITY_TYPE); 
				slac_debug (session, 0, __func__, "CM_SLAC_PARAM.CNF.RunID %s", HEXSTRING (string, confirm->RunID)); 
				slac_debug (session, 0, __func__, "CM_SLAC_PARAM.CNF.CipherSuite %d", confirm->CipherSuite); 
			} 

#endif

			memcpy (session->FORWARDING_STA, confirm->FORWARDING_STA, sizeof (session->FORWARDING_STA)); 
			memcpy (session->MSOUND_TARGET, confirm->MSOUND_TARGET, sizeof (session->MSOUND_TARGET)); 
			session->NUM_SOUNDS = confirm->NUM_SOUNDS; 
			session->TIME_OUT = confirm->TIME_OUT; 
			session->RESP_TYPE = confirm->RESP_TYPE; 
			return (0); 
		} 
	} 
	return (slac_debug (session, 0, __func__, "<-- CM_SLAC_PARAM.CNF ?")); 
} 
Esempio n. 9
0
int bbftp_list(char *line,char **filelist,int *filelistlen,int *errcode)
{

    char    minbuffer[MINMESSLEN] ;
    int     msglen ;
    int     code ;
    struct  message *msg ;
    struct  mess_integer *msg_integer ;
    fd_set  selectmask ; /* Select mask */
    int     nfds ; /* Max number of file descriptor */
    char    *buffer ;
    int     retcode ;
    
    if ( verbose) printmessage(stdout,CASE_NORMAL,0,timestamp,">> COMMAND : list %s\n",line) ;

    msg = (struct message *)minbuffer ;
    msg->code = MSG_LIST_V2 ;
#ifndef WORDS_BIGENDIAN
    msg->msglen = ntohl(strlen(line)+sizeof(int)) ;
#else
    msg->msglen = strlen(line)+sizeof(int) ;
#endif

    if ( writemessage(outcontrolsock,minbuffer,MINMESSLEN,sendcontrolto,0) < 0 ) {
        /*
        ** We were not able to send the minimum message so
        ** we are going to close the control socket and to 
        ** tell the calling program to restart a connection
        */
        printmessage(stderr,CASE_ERROR,64,timestamp,"Error sending %s message\n","MSG_LIST_V2");
        *errcode = 64 ;
        bbftp_free_all_var() ;
        bbftp_close_control() ;
        return BB_RET_CONN_BROKEN ; /* restart connection */
    }
    /* 
    ** Sending transfer options
    */
    msg_integer = (struct mess_integer*)minbuffer ;
    msg_integer->myint =  transferoption ;
    if ( writemessage(outcontrolsock,minbuffer,sizeof(int),sendcontrolto,0) < 0 ) {
        printmessage(stderr,CASE_ERROR,64,timestamp,"Error sending %s message\n","MSG_LIST_V2 (transferoption)");
        *errcode = 64 ;
        bbftp_close_control() ;
        return BB_RET_CONN_BROKEN ; /* restart connection */
    }
    /* 
    ** Directory name
    */
    if ( writemessage(outcontrolsock,line,strlen(line),sendcontrolto,0) < 0 ) {
        printmessage(stderr,CASE_ERROR,64,timestamp,"Error sending %s message\n","MSG_LIST_V2 (directory name)");
        *errcode = 64 ;
        bbftp_close_control() ;
        return BB_RET_CONN_BROKEN ; /* restart connection */
    }
     /*
    ** Now we are going to wait for the message on the control 
    ** connection
    */
waitcontrol:
    nfds = sysconf(_SC_OPEN_MAX) ;
    FD_ZERO(&selectmask) ;
    FD_SET(incontrolsock,&selectmask) ;
    retcode = select(FD_SETSIZE,&selectmask,0,0,0) ;
    if ( retcode < 0 ) {
        /*
        ** Select error
        */
        if ( errno != EINTR ) {
            /*
            ** we have got an error so close the connection
            ** and restart
            */
            printmessage(stderr,CASE_ERROR,66,timestamp,"Error select on control connection : %s\n",strerror(errno));
            *errcode = 66 ;
            bbftp_close_control() ;
            return BB_RET_CONN_BROKEN ;
        } else {
            /*
            ** Interrupted by a signal
            */
            FD_ZERO(&selectmask) ;
            FD_SET(incontrolsock,&selectmask) ;
            goto waitcontrol ;
        }
    } else if ( retcode == 0 ) {
        /*
        ** Impossible we do not set any timer
        */
        FD_ZERO(&selectmask) ;
        FD_SET(incontrolsock,&selectmask) ;
        goto waitcontrol ;
    } else {
        /*
        ** read the message
        */
        if ( readmessage(incontrolsock,minbuffer,MINMESSLEN,recvcontrolto,0) < 0 ) {
            printmessage(stderr,CASE_ERROR,61,timestamp,"Error waiting %s message\n","MSG_OK (on MSG_LIST_V2)");
            *errcode = 61 ;
            bbftp_close_control() ;
            return BB_RET_CONN_BROKEN ;
        }
        code = msg->code ;
        if ( code == MSG_BAD || code == MSG_BAD_NO_RETRY) {
            /*
            ** The change directory has failed so ...
            */
#ifndef WORDS_BIGENDIAN
            msglen = ntohl(msg->msglen) ;
#else
            msglen = msg->msglen ;
#endif
            if ( (buffer = (char *) malloc(msglen+1) ) == NULL) {
                printmessage(stderr,CASE_ERROR,35,timestamp,"Error allocating memory for %s : %s\n","buffer (bbftp_list)",strerror(errno)) ;
                *errcode = 35 ;
                bbftp_close_control() ;
                return BB_RET_CONN_BROKEN ;
            }
            if ( readmessage(incontrolsock,buffer,msglen,recvcontrolto,0) < 0 ) {
                printmessage(stderr,CASE_ERROR,67,timestamp,"Error reading data for %s message\n","MSG_BAD (on MSG_LIST_V2)");
                *errcode = 67 ;
                bbftp_close_control() ;
                free(buffer) ;
                if ( code == MSG_BAD ) {
                    return BB_RET_CONN_BROKEN ;
                } else {
                    return BB_RET_FT_NR_CONN_BROKEN ;
                }
            } else {
                buffer[msglen] = '\0' ;
                printmessage(stderr,CASE_ERROR,100,timestamp,"%s\n",buffer) ;
                if (verbose) printmessage(stdout,CASE_NORMAL,0,timestamp,"<< %s\n",buffer) ;
                free(buffer) ;
                if ( code == MSG_BAD ) {
                    *errcode = 100 ;
                    return BB_RET_ERROR;
                } else {
                    /*
                    ** In case of no retry we are going to wait 2 seconds
                    ** in order for the server to finish its cleaning (in
                    ** fact if the error message is du to a server child
                    ** abnormal termination, the message is sent on the death
                    ** of the first child and the server has some cleaning
                    ** to do).
                    */
                    sleep(2) ;
                    *errcode = 100 ;
                    return BB_RET_FT_NR ;
                }
            }
        } else if (msg->code == MSG_LIST_REPL_V2 ) {
            /*
            ** At this stage the transfer is OK but we need
            ** the answer because it gives all file names
            */
#ifndef WORDS_BIGENDIAN
            msglen = ntohl(msg->msglen) ;
#else
            msglen = msg->msglen ;
#endif
            if ( msglen == 0 ) {
                /*
                ** There was no file corresponding
                */
                if ( verbose) printmessage(stdout,CASE_NORMAL,0,timestamp,"<< OK : no file\n") ;
                *filelistlen = 0 ; 
                return BB_RET_OK ;
            } else {
                if ( ((*filelist) = (char *) malloc(msglen+1) ) == NULL) {
                    printmessage(stderr,CASE_ERROR,35,timestamp,"Error allocating memory for %s : %s\n","filelist (bbftp_list)",strerror(errno)) ;
                    *errcode = 35 ;
                    bbftp_close_control() ;
                    return BB_RET_CONN_BROKEN ;
                }
                if ( readmessage(incontrolsock,*filelist,msglen,recvcontrolto,0) < 0) {
                    printmessage(stderr,CASE_ERROR,67,timestamp,"Error reading data for %s message\n","MSG_LIST_REPL_V2 (on MSG_LIST_V2)");
                    *errcode = 67 ;
                    bbftp_close_control() ;
                    free(*filelist) ;
                    return BB_RET_CONN_BROKEN ;
                }
                (*filelist)[msglen] = '\0' ;
                *filelistlen = msglen ; 
                if ( verbose ) printmessage(stdout,CASE_NORMAL,0,timestamp,"<< OK\n") ;
                return BB_RET_OK ;
            }
        } else {
            /*
            ** Receive unkwown message so something is
            ** going wrong. close the control socket
            ** and restart
            */
            printmessage(stderr,CASE_ERROR,62,timestamp,"Unknown message while waiting for %s message\n","MSG_OK (on MSG_MKDIR_V2)");
            *errcode = 62 ;
            bbftp_close_control() ;
            return BB_RET_CONN_BROKEN ;
        }
    }
}
Esempio n. 10
0
int
main(int argc, char **argv)
{
	bool noheader = FALSE;	/* set if don't want header */
	bool headeronly = FALSE; /* set if only want header */
	bool examine = FALSE;	/* set if examine a character */
	time_t seconds;		/* for time of day */
	double dtemp;		/* for temporary calculations */

	initialstate();		/* init globals */

	/* process arguments */
	while (--argc && (*++argv)[0] == '-')
		switch ((*argv)[1]) {
		case 's':	/* short */
			noheader = TRUE;
			break;

		case 'H':	/* Header */
			headeronly = TRUE;
			break;

		case 'a':	/* all users */
			activelist();
			cleanup(TRUE);
			/* NOTREACHED */

		case 'p':	/* purge old players */
			purgeoldplayers();
			cleanup(TRUE);
			/* NOTREACHED */

		case 'S':	/* set 'Wizard' */
			Wizard = !getuid();
			break;

		case 'x':	/* examine */
			examine = TRUE;
			break;

		case 'm':	/* monsters */
			monstlist();
			cleanup(TRUE);
			/* NOTREACHED */

		case 'b':	/* scoreboard */
			scorelist();
			cleanup(TRUE);
			/* NOTREACHED */
		}

	if (!isatty(0))		/* don't let non-tty's play */
		cleanup(TRUE);
	/* NOTREACHED */

	playinit();		/* set up to catch signals, init curses */

	if (examine) {
		changestats(FALSE);
		cleanup(TRUE);
		/* NOTREACHED */
	}

	if (!noheader) {
		titlelist();
		purgeoldplayers();	/* clean up old characters */
	}

	if (headeronly)
		cleanup(TRUE);
	/* NOTREACHED */

	do {
		/* get the player structure filled */
		Fileloc = -1L;

		mvaddstr(22, 17, "Do you have a character to run [Q = Quit] ? ");

		switch (getanswer("NYQ", FALSE)) {
		case 'Y':
			Fileloc = recallplayer();
			break;

		case 'Q':
			cleanup(TRUE);
			/* NOTREACHED */

		default:
			Fileloc = rollnewplayer();
			break;
		}
		clear();
	} while (Fileloc < 0L);

	if (Player.p_level > 5.0)
		/* low level players have long timeout */
		Timeout = TRUE;

	/* update some important player statistics */
	strcpy(Player.p_login, Login);
	time(&seconds);
	Player.p_lastused = localtime(&seconds)->tm_yday;
	Player.p_status = S_PLAYING;
	writerecord(&Player, Fileloc);

	Statptr = &Stattable[Player.p_type];	/* initialize pointer */

	/* catch interrupts */
#ifdef  BSD41
	sigset(SIGINT, interrupt);
#endif
#ifdef  BSD42
	signal(SIGINT, interrupt);
#endif
#ifdef  SYS3
	signal(SIGINT, interrupt);
#endif
#ifdef  SYS5
	signal(SIGINT, interrupt);
#endif

	altercoordinates(Player.p_x, Player.p_y, A_FORCED);	/* set some flags */

	clear();

	for (;;) {
		/* loop forever, processing input */

		adjuststats();	/* cleanup stats */

		if (Throne && Player.p_crowns == 0 && Player.p_specialtype != SC_KING) {
			/* not allowed on throne -- move */
			mvaddstr(5, 0, "You're not allowed in the Lord's Chamber without a crown.\n");
			altercoordinates(0.0, 0.0, A_NEAR);
		}

		checktampered();	/* check for energy voids, etc. */

		if (Player.p_status != S_CLOAKED
		/* not cloaked */
		    && (dtemp = fabs(Player.p_x)) == fabs(Player.p_y)
		/* |x| = |y| */
		    && !Throne) {
			/* not on throne */
			dtemp = sqrt(dtemp / 100.0);
			if (floor(dtemp) == dtemp) {
				/* |x| / 100 == n*n; at a trading post */
				tradingpost();
				clear();
			}
		}

		checkbattle();	/* check for player to player battle */
		neatstuff();	/* gurus, medics, etc. */

		if (Player.p_status == S_CLOAKED) {
			/* costs 3 mana per turn to be cloaked */
			if (Player.p_mana > 3.0)
				Player.p_mana -= 3.0;
			else {
				/* ran out of mana, uncloak */
				Player.p_status = S_PLAYING;
				Changed = TRUE;
			}
		}

		if (Player.p_status != S_PLAYING && Player.p_status != S_CLOAKED) {
			/* change status back to S_PLAYING */
			Player.p_status = S_PLAYING;
			Changed = TRUE;
		}

		if (Changed) {
			/* update file only if important stuff has changed */
			writerecord(&Player, Fileloc);
			Changed = FALSE;
			continue;
		}

		readmessage();	/* read message, if any */

		displaystats();	/* print statistics */

		move(6, 0);

		if (Throne)
			/* maybe make king, print prompt, etc. */
			throneroom();

		/* print status line */
		addstr("1:Move  2:Players  3:Talk  4:Stats  5:Quit  ");
		if (Player.p_level >= MEL_CLOAK && Player.p_magiclvl >= ML_CLOAK)
			addstr("6:Cloak  ");
		if (Player.p_level >= MEL_TELEPORT && Player.p_magiclvl >= ML_TELEPORT)
			addstr("7:Teleport  ");
		if (Player.p_specialtype >= SC_COUNCIL || Wizard)
			addstr("8:Intervene  ");

		procmain();	/* process input */
	}
}
Esempio n. 11
0
int createadir(int code, int msglen) {

    char    receive_buffer[MAXMESSLEN] ;
    int        savederrno ;
    char    logmessage[256] ;

#ifndef WORDS_BIGENDIAN
    msglen = ntohl(msglen) ;
#endif
    if ( msglen > MAXMESSLEN ) {
        /*
        ** In order to avoid buffer overflow we reject message to
        ** big
        */
        syslog(BBFTPD_ERR,"Message to big in createdir (%d,%d)",msglen,MAXMESSLEN) ;
        reply(MSG_BAD_NO_RETRY,"Directory too long") ;
        return -1 ;
    }
    /*
    ** Read the characteristics of the directory
    */
    if ( readmessage(msgsock,receive_buffer,msglen,recvcontrolto) < 0 ) {
        /*
        ** Error ...
        */
        return -1 ;
    }
    /*
    ** receive_buffer contains the directory to create
    */
    receive_buffer[msglen] = '\0' ;
    if ( code == MSG_MKDIR ) {
        syslog(BBFTPD_DEBUG,"Creating directory %s",receive_buffer) ;
    }
    /*
    ** We create the directory
    */
    if ( mkdir(receive_buffer,S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP) < 0 ) {
        /*
        ** Depending on errno we are going to tell the client to 
        ** retry or not
        */
        savederrno = errno ;
        sprintf(logmessage,"Error creation directory %s : %s",receive_buffer,strerror(errno)) ;
        syslog(BBFTPD_ERR,"Error creation directory %s : %s",receive_buffer,strerror(errno)) ;
        /*
        ** We tell the client not to retry in the following case (even in waiting
        ** WAITRETRYTIME the problem will not be solved) :
        **        EACCES        : Search permission denied
        **        EDQUOT        : No more quota 
        **        ENOSPC        : No more space
        **        ELOOP        : To many symbolic links on path
        **        ENAMETOOLONG: Path argument too long
        **        ENOTDIR        : A component in path is not a directory
        **        EROFS        : The path prefix resides on a read-only file system.
        **        ENOENT      : A component of the path prefix does not exist or is a null pathname.
        **        EEXIST      : The named file already exists.
        */
        if ( savederrno == EACCES ||
                savederrno == EDQUOT ||
                savederrno == ENOSPC ||
                savederrno == ELOOP ||
                savederrno == ENAMETOOLONG ||
                savederrno == ENOTDIR ||
                savederrno == EROFS ||
                savederrno == ENOENT ||
                savederrno == EEXIST ) {
            reply(MSG_BAD_NO_RETRY,logmessage) ;
        } else {
            reply(MSG_BAD,logmessage) ;
        }
        return 0 ;
    }
    reply(MSG_OK,"OK") ;
    return 0 ;
}
Esempio n. 12
0
/*main loop, message sender, etc.pp.*/
int main(int argc,char**argv)
{
	int c,optindex=1;
	struct dhcp_msg *msg;
	/*parse options*/
	argv0=*argv;
        while(1){
                c=getopt_long(argc,argv,shortopt,longopt,&optindex);
                if(c==-1)break;
                switch(c){
                        case 'p':getprefix=1;break;
                        case 'P':getprefix=0;break;
                        case 'a':getaddress=1;break;
                        case 'A':getaddress=0;break;
                        case 'd':getdns=1;break;
                        case 'D':getdns=0;break;
                        case 'r':retries=atoi(optarg);break;
                        case 'l':localid=optarg;break;
                        case 'u':setduid(optarg);break;
                        case 'c':userapid=1;break;
                        case 'C':userapid=0;break;
                        case 'L':setloglevel(optarg);break;
                        default:
                                fprintf(stderr,"Syntax error in arguments.\n");
                                printhelp();
                                return 1;
                                break;
                        case 'h':
                                printhelp();
                                return 0;
                                break;
                }
        }
        if((optind+2)!=argc){
        	fprintf(stderr,"Syntax error.\n");
        	printhelp();
        	return 1;
	}
	device=argv[optind];
	script=argv[optind+1];

	if(DUIDLEN==0){
		if(localid)
			setlocalid(localid);
		else
			initlocalid();
	}
	/*init socket*/
	initsocket(DHCP_CLIENTPORT,device);
	if(sockfd<0){
		td_log(LOGERROR,"unable to allocate socket, exiting.");
		exit(1);
	}
	/*init my own stuff*/
	inititems();
	/*init SOLICIT/IREQ msg*/
	if(!getaddress && !getprefix){
		msg=newmessage(MSG_IREQUEST);
		addrecvfilter(MSG_REPLY);
	}else{
		msg=newmessage(MSG_SOLICIT);
		addrecvfilter(MSG_ADVERTISE);
	}
	COMPAREMSGID=1;
	settargetserver(&msg->msg_peer);
	messageaddopt(msg,OPT_CLIENTID);
	if(getdns){
		messageaddoptrequest(msg,OPT_DNS_SERVER);
		messageaddoptrequest(msg,OPT_DNS_NAME);
	}
	if(getaddress)messageaddopt(msg,OPT_IANA);
	if(getprefix)messageaddopt(msg,OPT_IAPD);
	if(userapid&&(getaddress||getprefix))messageaddopt(msg,OPT_RAPIDCOMMIT);
	/*start main loop*/
	for(c=0;c<retries;c++){
		sendmessage(msg);
		fd_set rfd,xfd;
		struct timeval tv;
		int sret;
		//wait for event
		FD_ZERO(&rfd);
		FD_ZERO(&xfd);
		FD_SET(sockfd,&rfd);
		FD_SET(sockfd,&xfd);
		tv.tv_sec=1;
		tv.tv_usec=0;
		sret=select(sockfd+1,&rfd,0,&xfd,&tv);
		//check for errors
		if(sret<0){
			int e=errno;
			if(e==EAGAIN)continue;
			td_log(LOGERROR,"Error caught: %s\n",strerror(e));
			return 1;
		}
		//check for event
		if(sret>0){
			if(FD_ISSET(sockfd,&rfd)){
				struct dhcp_msg*msg2;
				msg2=readmessage();
				if(msg2)
					if(handlemessage(msg2,msg)==0)break;
			}
			if(FD_ISSET(sockfd,&xfd)){
				td_log(LOGERROR,"Exception on socket caught.\n");
				return 1;
			}
		}else
			td_log(LOGDEBUG,"timeout, iteration %i",c);
	}
	/*execute script*/
	return execscript();
}
Esempio n. 13
0
int sendafile(int code) {

    char    receive_buffer[MAXMESSLEN] ;
    char    receive_buffer_sup[MAXMESSLEN] ;
    char    send_buffer[MAXMESSLEN] ;
    int        savederrno ;

    char    readbuffer[READBUFLEN] ;
    char    buffercomp[READBUFLEN] ;
    struct    mess_compress *msg_compress ;
#ifdef WITH_GZIP
    uLong    buflen ;
    uLong    bufcomplen ;
#endif
    my64_t    filelen64 ;
    my64_t    toprint64 ;
    
#ifdef STANDART_FILE_CALL
    off_t         nbperchild ;
    off_t         nbtosend ;
    off_t         nbread ;
    off_t         nbsent ;
    off_t         numberread ;
    off_t         startpoint ;
    off_t        realnbtosend ;
    off_t        filelen ;
    struct stat statbuf ;
#else
    off64_t     nbperchild ;
    off64_t     nbtosend ;
    off64_t     nbread ;
    off64_t     nbsent ;
    off64_t     numberread ;
    off64_t     startpoint ;
    off64_t        realnbtosend ;
    off64_t        filelen ;
    struct stat64 statbuf ;
#endif

    int        lentosend ;

    char    readfilename[MAXLENFILE] ;
    
    int        retcode ;
    int        fd ;
    int        i ;
    int        sendsock ;
    char    logmessage[256] ;
    int        compressiontype ;
    
    struct message *msg ;
    struct mess_store *msg_store ;
    struct mess_retr_ok *msg_retr_ok ;
    
    int        nfds ;
    fd_set    selectmask ; /* Select mask */
    struct timeval    wait_timer;
    
    
    /*
    ** Initilize the pid array
    */
     for ( i=0 ; i< MAXPORT ; i++) {
        pid_child[i] = 0 ;
    }
    childendinerror = 0 ; /* No child so no error */

    strcpy(currentfilename,"") ;
    if ( (retcode = readmessage(msgsock,receive_buffer,STORMESSLEN,recvcontrolto) ) < 0 ) {
        syslog(BBFTPD_ERR,"Error receiving file char") ;
        return retcode ;
    }
    msg_store = (struct mess_store *) receive_buffer ;
    strcpy(readfilename,msg_store->filename) ;
#ifndef WORDS_BIGENDIAN
    msg_store->nbport = ntohl(msg_store->nbport) ;
    for (i = 0 ; i< MAXPORT ; i++ ) {
        msg_store->port[i] = ntohl(msg_store->port[i]) ;
    }
#endif
    if ( code == MSG_RETR ) {
        compressiontype = NOCOMPRESSION ;
        syslog(BBFTPD_DEBUG,"Retreiving file %s with %d children",readfilename,msg_store->nbport) ;
    } else {
        compressiontype = COMPRESSION ;
        syslog(BBFTPD_DEBUG,"Retreiving file %s with %d children in compressed mode",readfilename,msg_store->nbport) ;
    }
    /*
    ** WARNING ----------
    **
    ** Do not use the receive buffer in father before having forked
    ** because all data related to the ports are in it
    **
    ** WARNING ----------
    */
    /*
    ** First stat the file in order to know if it is a directory
    */
#ifdef STANDART_FILE_CALL
    if ( stat(readfilename,&statbuf) < 0 ) {
#else
    if ( stat64(readfilename,&statbuf) < 0 ) {
#endif
        /*
        ** We tell the client not to retry in the following case (even in waiting
        ** WAITRETRYTIME the problem will not be solved) :
        **        EACCES        : Search permission denied
        **        ELOOP        : To many symbolic links on path
        **        ENAMETOOLONG: Path argument too long
        **        ENOENT        : The file does not exists
        **        ENOTDIR        : A component in path is not a directory
        */
        savederrno = errno ;
        sprintf(logmessage,"Error stating file %s : %s ",readfilename,strerror(savederrno)) ;
        syslog(BBFTPD_ERR,"Error stating file %s : %s ",readfilename,strerror(savederrno)) ;
        if ( savederrno == EACCES ||
            savederrno == ELOOP ||
            savederrno == ENAMETOOLONG ||
            savederrno == ENOENT ||
            savederrno == ENOTDIR ) {
            reply(MSG_BAD_NO_RETRY,logmessage) ;
            return 0 ;
        } else {
            reply(MSG_BAD,logmessage) ;
            return 0 ;
        }
    } else {
        /*
        ** The file exists so check if it is a directory
        */
        if ( (statbuf.st_mode & S_IFDIR) == S_IFDIR) {
            syslog(BBFTPD_ERR,"file %s is a directory",readfilename) ;
            sprintf(logmessage,"File %s is a directory",readfilename) ;
            reply(MSG_BAD_NO_RETRY,logmessage) ;
            return 0 ;
        }
    }                
    /*
    ** Getting filesize in order to send it to the client
    */
#ifdef STANDART_FILE_CALL
    if ( (fd = open(readfilename,O_RDONLY)) < 0 ) {
#else
    if ( (fd = open64(readfilename,O_RDONLY)) < 0 ) {
#endif
        /*
        ** An error on openning the local file is considered
        ** as fatal. Maybe this need to be improved depending
        ** on errno
        */
        savederrno = errno ;
        syslog(BBFTPD_ERR,"Error opening local file %s : %s",readfilename,strerror(errno)) ;
        sprintf(logmessage,"Error opening local file %s : %s ",readfilename,strerror(errno)) ;
        /*
        ** We tell the client not to retry in the following case (even in waiting
        ** WAITRETRYTIME the problem will not be solved) :
        **        EACCES        : Search permission denied
        **        ELOOP        : To many symbolic links on path
        **        ENOENT        : No such file or directory
        **        ENAMETOOLONG: Path argument too long
        **        ENOTDIR        : A component in path is not a directory
        */
        if ( savederrno == EACCES ||
                savederrno == ELOOP ||
                savederrno == ENOENT ||
                savederrno == ENAMETOOLONG ||
                savederrno == ENOTDIR ) {
            reply(MSG_BAD_NO_RETRY,logmessage) ;
        } else {
            reply(MSG_BAD,logmessage) ;
        }
        return 0 ;
    }
#ifdef STANDART_FILE_CALL
    if ( (filelen = lseek(fd,0,SEEK_END) ) < 0 ) {
#else
    if ( (filelen = lseek64(fd,0,SEEK_END) ) < 0 ) {
#endif
        /*
        ** An error on seekin the local file is considered
        ** as fatal. lseek error  in this case is completly
        ** abnormal
        */
        close(fd) ;
        syslog(BBFTPD_ERR,"Error seeking local file %s : %s",readfilename,strerror(errno)) ;
        sprintf(logmessage,"Error seeking local file %s : %s ",readfilename,strerror(errno)) ;
        reply(MSG_BAD,logmessage) ;
        return 0 ;
    }
    filelen64 = filelen ;
    /*
    ** Close the file as the only interresting thing was the length
    */
    close(fd) ;
    /*
    ** We are going to send the file length 
    */
    msg = (struct message *) send_buffer ;
    msg->code = MSG_RETR_OK ;
#ifndef WORDS_BIGENDIAN
    msg->msglen = ntohl(RETROKMESSLEN) ;
#else
    msg->msglen = RETROKMESSLEN ;
#endif
    if ( writemessage(msgsock,send_buffer,MINMESSLEN,recvcontrolto) < 0 ) {
        /*
        ** Something wrong in sending message
        ** tell calling to close the connection
        */
        syslog(BBFTPD_ERR,"Error sending RETROK part 1") ;
        return -1 ;
    }
    msg_retr_ok = (struct mess_retr_ok *) send_buffer ;
#ifndef WORDS_BIGENDIAN
    msg_retr_ok->filesize = ntohll(filelen64) ;
#else
    msg_retr_ok->filesize = filelen64 ;
#endif
    if ( writemessage(msgsock,send_buffer,RETROKMESSLEN,recvcontrolto) < 0 ) {
        /*
        ** Something wrong in sending message
        ** tell calling to close the connection
        */
        syslog(BBFTPD_ERR,"Error sending RETROK part 2") ;
        return -1 ;
    }
    /*
    ** Wait for the START message
    */
    if ( readmessage(msgsock,receive_buffer_sup,MINMESSLEN,RETRSTARTTO) < 0 ) {
        /*
        ** Something wrong in receiving message
        ** tell calling to close the connection
        */
        syslog(BBFTPD_ERR,"Error receiving RETRSTART") ;
        return -1 ;
    }
    msg = (struct message *) receive_buffer_sup ;
    if ( msg->code == MSG_ABR) {
        /*
        ** In this case the client will not close the connection
        ** so do the same
        */
        syslog(BBFTPD_ERR,"Receive ABORT message") ;
        return 0 ;
    } else if ( msg->code == MSG_CREATE_ZERO ) {
        syslog(BBFTPD_INFO,"Send zero length file") ;
        return 0 ;
    } else if ( msg->code != MSG_RETR_START ) {
        syslog(BBFTPD_ERR,"Receive Unknown message code while waiting RETRSTART %d",msg->code) ;
        return -1 ;
    }
    /*
    ** So we receive the start message ...
    */
    /*
    ** Now start all our children
    */
    nbperchild = filelen/msg_store->nbport ;
    for (i = 1 ; i <= msg_store->nbport ; i++) {
        if ( i == msg_store->nbport) {
            startpoint = (i-1)*nbperchild;
            nbtosend = filelen-(nbperchild*(msg_store->nbport-1)) ;
        } else {
            startpoint = (i-1)*nbperchild;
            nbtosend = nbperchild ;
        }
        /*
        ** Now create the socket to send
        */
        sendsock = 0 ;
        while (sendsock == 0 ) {
            sendsock = createreceivesock(msg_store->port[i-1],i,logmessage) ;
        }
        if ( sendsock < 0 ) {
            /*
            ** We set childendinerror to 1 in order to prevent the father
            ** to send a BAD message which can desynchronize the client and the
            ** server (We need only one error message)
            ** Bug discovered by amlutz on 2000/03/11
            */
            if ( childendinerror == 0 ) {
                childendinerror = 1 ;
                reply(MSG_BAD,logmessage) ;
            }
            clean_child() ;
            return 0 ;
        }
        /*
        ** Set flagsighup to zero in order to be able in child
        ** not to wait STARTCHILDTO if signal was sent before 
        ** entering select. (Seen on Linux with one child)
        */
        flagsighup = 0 ;
        /*
        ** At this stage we are ready to receive packets
        ** So we are going to fork
        */
        if ( (retcode = fork()) == 0 ) {
            /*
            ** We are in child
            */
            /*
            ** Pause until father send a SIGHUP in order to prevent
            ** child to die before father has started all children
            */
            if ( flagsighup == 0) {
                nfds = sysconf(_SC_OPEN_MAX) ;
                wait_timer.tv_sec  = STARTCHILDTO ;
                wait_timer.tv_usec = 0 ;
                select(nfds,0,0,0,&wait_timer) ;
            }
            syslog(BBFTPD_DEBUG,"Child Starting") ;
            /*
            ** Close all unnecessary stuff
            */
            close(msgsock) ;
            /*
            ** And open the file 
            */
#ifdef STANDART_FILE_CALL
            if ( (fd = open(readfilename,O_RDONLY)) < 0 ) {
#else
            if ( (fd = open64(readfilename,O_RDONLY)) < 0 ) {
#endif
                /*
                ** An error on openning the local file is considered
                ** as fatal. Maybe this need to be improved depending
                ** on errno
                */
                i = errno ;
                syslog(BBFTPD_ERR,"Error opening local file %s : %s",readfilename,strerror(errno)) ;
                close(sendsock) ;
                exit(i) ;
            }
#ifdef STANDART_FILE_CALL
            if ( lseek(fd,startpoint,SEEK_SET) < 0 ) {
#else
            if ( lseek64(fd,startpoint,SEEK_SET) < 0 ) {
#endif
                i = errno ;
                close(fd) ;
                syslog(BBFTPD_ERR,"Error seeking file : %s",strerror(errno)) ;
                close(sendsock) ;
                exit(i)  ;
            }
            /*
            ** Start the sending loop
            */
            nbread = 0 ;
            while ( nbread < nbtosend ) {
                if ( (numberread = read ( fd, readbuffer, (sizeof(readbuffer) <= nbtosend - nbread) ? sizeof(readbuffer) : nbtosend-nbread) ) > 0 ) {
                    nbread = nbread+numberread ;
#ifdef WITH_GZIP
                    if ( compressiontype == COMPRESSION ) {
                        /*
                        ** In case of compression we are going to use
                        ** a temporary buffer
                        */
                        bufcomplen = READBUFLEN ;
                        buflen = numberread ;
                        msg_compress = ( struct mess_compress *) send_buffer;
                        retcode = compress((Bytef *)buffercomp,&bufcomplen,(Bytef *)readbuffer,buflen) ;
                        if ( retcode != 0 ) {
                            /*
                            ** Compress error, in this cas we are sending the
                            ** date uncompressed
                            */
                            msg_compress->code = DATA_NOCOMPRESS ;
                            lentosend = numberread ;
#ifndef WORDS_BIGENDIAN
                            msg_compress->datalen = ntohl(lentosend) ;
#else
                            msg_compress->datalen = lentosend ;
#endif
                            realnbtosend = numberread ;
                        } else {
                            msg_compress->code = DATA_COMPRESS ;
                            lentosend = bufcomplen ;
#ifndef WORDS_BIGENDIAN
                            msg_compress->datalen = ntohl(lentosend) ;
#else
                            msg_compress->datalen = lentosend ;
#endif
                            realnbtosend =  bufcomplen ;
                            memcpy(readbuffer,buffercomp,READBUFLEN) ;
                        }
                        /*
                        ** Send the header
                        */
                        if ( writemessage(sendsock,send_buffer,COMPMESSLEN,datato) < 0 ) {
                            i = ETIMEDOUT ;
                            syslog(BBFTPD_ERR,"Error sending header data") ;
                            close(sendsock) ;
                            exit(i) ;
                        }
                    } else {
                        realnbtosend = numberread ;
                    }
#else
                    realnbtosend = numberread ;
#endif
                    /*
                    ** Send the data
                    */
                    nbsent = 0 ;
                    while ( nbsent < realnbtosend ) {
                        lentosend = realnbtosend-nbsent ;
                        nfds = sysconf(_SC_OPEN_MAX) ;
                        FD_ZERO(&selectmask) ;
                        FD_SET(sendsock,&selectmask) ;
                        wait_timer.tv_sec  = datato  ;
                        wait_timer.tv_usec = 0 ;
                        if ( (retcode = select(nfds,0,&selectmask,0,&wait_timer) ) == -1 ) {
                            /*
                            ** Select error
                            */
                            i = errno ;
                            syslog(BBFTPD_ERR,"Error select while sending : %s",strerror(errno)) ;
                            close(fd) ;
                            close(sendsock) ;
                            exit(i) ;
                        } else if ( retcode == 0 ) {
                            syslog(BBFTPD_ERR,"Time out while sending") ;
                            close(fd) ;
                            i=ETIMEDOUT ;
                            close(sendsock) ;
                            exit(i) ;
                        } else {
                            retcode = send(sendsock,&readbuffer[nbsent],lentosend,0) ;
                            if ( retcode < 0 ) {
                                i = errno ;
                                syslog(BBFTPD_ERR,"Error while sending %s",strerror(i)) ;
                                close(sendsock) ;
                                exit(i) ;
                            } else if ( retcode == 0 ) {
                                i = ECONNRESET ;
                                syslog(BBFTPD_ERR,"Connexion breaks") ;
                                close(fd) ;
                                close(sendsock) ;
                                exit(i) ;
                            } else {
                                nbsent = nbsent+retcode ;
                            }
                        }
                    }
                } else {
                    i = errno ;
                    syslog(BBFTPD_ERR,"Child Error reading : %s",strerror(errno)) ;
                    close(sendsock) ;
                    exit(i) ;
                }
            }
            /*
            ** All data has been sent so wait for the acknoledge
            */
            if ( readmessage(sendsock,receive_buffer,MINMESSLEN,ackto) < 0 ) {
                syslog(BBFTPD_ERR,"Error waiting ACK") ;
                close(sendsock) ;
                exit(ETIMEDOUT) ;
            }
            msg = (struct message *) receive_buffer ;
            if ( msg->code != MSG_ACK) {
                syslog(BBFTPD_ERR,"Error unknown messge while waiting ACK %d",msg->code) ;
                close(sendsock) ;
                exit(1) ;
            }
            toprint64 = nbtosend ;
            syslog(BBFTPD_DEBUG,"Child send %" LONG_LONG_FORMAT " bytes ; end correct ",toprint64) ;
            close(sendsock) ;
            exit(0) ;
        } else {
            /*
            ** We are in father
            */
            if ( retcode == -1 ) {
                /*
                ** Fork failed ...
                */
                syslog(BBFTPD_ERR,"fork failed : %s",strerror(errno)) ;
                sprintf(logmessage,"fork failed : %s ",strerror(errno)) ;
                if ( childendinerror == 0 ) {
                    childendinerror = 1 ;
                    reply(MSG_BAD,logmessage) ;
                }
                clean_child() ;
                return 0 ;
            } else {
                syslog(BBFTPD_DEBUG,"Started child pid %d",retcode) ;
                pid_child[i-1] = retcode ;
                close(sendsock) ;
            }
        }
    }
    /*
    ** Set the state before starting children because if the file was
    ** small the child has ended before state was setup to correct value
    */
    state = S_SENDING ;
    /*
    ** Start all children
    */
    for (i = 0 ; i<MAXPORT ; i++) {
        if (pid_child[i] != 0) {
            kill(pid_child[i],SIGHUP) ;
        }
    }
    return 0 ;
}
Esempio n. 14
0
int bbftp_retrlistdir(char *pattern,char **filelist,int *filelistlen,char *logmessage,int *errcode)
{
    int     lastslash ;
    char    *pointer ;
    char    *dirpath ;
    DIR     *curdir ;
#ifdef STANDART_FILE_CALL
    struct dirent *dp ;
    struct stat statbuf;
#else
#ifdef STANDART_READDIR_CALL
    struct dirent *dp ;
#else
    struct dirent64 *dp ;
#endif
    struct stat64 statbuf ;
#endif
    int     lengthtosend;
    int     numberoffile ;
    /*
    ** Structure to keep the filenames
    */
    struct keepfile {
        char    *filename ;
        char    filechar[3] ;
        struct  keepfile *next ;
    } ;
    struct keepfile *first_item ;
    struct keepfile *current_item ;
    struct keepfile *used_item ;
    char    *filepos ;
    int     i ;
    /*
    ** Check if it is a rfio creation
    */
#if defined(WITH_RFIO) || defined(WITH_RFIO64)    
    if ( (transferoption & TROPT_RFIO_O) == TROPT_RFIO_O ) {
        return bbftp_retrlistdir_rfio(pattern,filelist,filelistlen,logmessage,errcode) ;
    }
#endif
    if ( (dirpath = (char *) malloc ( strlen(pattern) + 1 + 3 )) == NULL ) {
        sprintf(logmessage,"Error allocating memory for dirpath %s",strerror(errno)) ;
        *errcode = 35 ;
        return -1 ;
    } 
    pointer = pattern ;
    lastslash = strlen(pointer) - 1 ;
    while ( lastslash >= 0 && pointer[lastslash] != '/') lastslash-- ;
    if ( lastslash == -1 ) {
        /*
        ** No slash in the path, so this is a pattern and we have
        ** to opendir .
        */
        if ( (curdir = opendir(".")) == NULL ) {
            sprintf(logmessage,"opendir . failed : %s ",strerror(errno)) ;
            *errcode = 86 ;
            free(dirpath) ;
            return -1 ;
        }
        strcpy(dirpath,"./") ;
    } else if ( lastslash == 0 ) {
        /*
        ** A slash in first position so we are going to open the
        ** / directory
        */
        if ( (curdir = opendir("/")) == NULL ) {
            sprintf(logmessage,"opendir / failed : %s ",strerror(errno)) ;
            *errcode = 86 ;
            free(dirpath) ;
            return -1 ;
        }
        strcpy(dirpath,"/") ;
        pointer++ ;
    } else if ( lastslash == strlen(pointer) - 1 ) {
        /*
        ** The filename end with a slash ..... error
        */
        sprintf(logmessage,"Pattern %s ends with a /",pattern) ;
        *errcode = 87 ;
        free(dirpath) ;
        return -1;
    } else {
        pointer[lastslash] = '\0';
        /*
        ** Srip unnecessary / at the end of dirpath and reset 
        ** only one
        */
        strcpy(dirpath,pointer) ;
        strip_trailing_slashes(dirpath) ;
        dirpath[strlen(dirpath)+1] = '\0';
        dirpath[strlen(dirpath)] = '/';
        if ( (curdir = opendir(dirpath)) == NULL ) {
            sprintf(logmessage,"opendir %s failed : %s ",dirpath,strerror(errno)) ;
            *errcode = 86 ;
            free(dirpath) ;
            return -1 ;
        }
        for ( i = 0 ; i <= lastslash ; i++ ) pointer++ ;
    }
    /*
    ** At this stage pointer point to the pattern and curdir
    ** is the opened directory and dirpath contain the
    ** directory name
    */
    /*
    ** As we are using the fnmatch routine we are obliged to
    ** first count the number of bytes we are sending.
    */
    lengthtosend = 0 ;
    numberoffile = 0 ;
    errno = 0 ;
    first_item = NULL ;
#ifdef STANDART_FILE_CALL
    while ( (dp = readdir(curdir) ) != NULL) {
#else
#ifdef STANDART_READDIR_CALL 
    while ( (dp = readdir(curdir) ) != NULL) {
#else
    while ( (dp = readdir64(curdir) ) != NULL) {
#endif
#endif
        if ( fnmatch(pointer, dp->d_name,0) == 0) {
            numberoffile++ ;
            lengthtosend = lengthtosend +  strlen(dirpath) + strlen(dp->d_name) + 1 + 3 ;
            if ( ( current_item = (struct keepfile *) malloc( sizeof(struct keepfile)) ) == NULL ) {
                sprintf(logmessage,"Error getting memory for structure : %s",strerror(errno)) ;
                *errcode = 35 ;
                current_item = first_item ;
                while ( current_item != NULL ) {
                    free(current_item->filename) ;
                    used_item = current_item->next ;
                    free(current_item) ;
                    current_item = used_item ;
                }
                closedir(curdir) ;
                free(dirpath) ;
                return -1 ;
            }
            if ( ( current_item->filename = (char *) malloc( strlen(dirpath) + strlen(dp->d_name) + 1) ) == NULL ) {
                sprintf(logmessage,"Error getting memory for filename : %s",strerror(errno)) ;
                *errcode = 35 ;
                /*
                ** Clean memory
                */
                free(current_item) ;
                current_item = first_item ;
                while ( current_item != NULL ) {
                    free(current_item->filename) ;
                    used_item = current_item->next ;
                    free(current_item) ;
                    current_item = used_item ;
                }
                closedir(curdir) ;
                free(dirpath) ;
                return -1 ;
            }
            current_item->next = NULL ;
            if ( first_item == NULL ) {
                first_item = current_item ;
                used_item = first_item ;
            } else {
                used_item = first_item ;
                while ( used_item->next != NULL ) used_item = used_item->next ;
                used_item->next = current_item ;
            }
            sprintf(current_item->filename,"%s%s",dirpath,dp->d_name) ;
#ifdef STANDART_FILE_CALL
            if ( lstat(current_item->filename,&statbuf) < 0 ) {
#else
            if ( lstat64(current_item->filename,&statbuf) < 0 ) {
#endif
                sprintf(logmessage,"Error lstating file %s",current_item->filename) ;
                *errcode = 89 ;
                current_item = first_item ;
                while ( current_item != NULL ) {
                    free(current_item->filename) ;
                    used_item = current_item->next ;
                    free(current_item) ;
                    current_item = used_item ;
                }
                closedir(curdir) ;
                free(dirpath) ;
                return -1 ;
            }
            if ( (statbuf.st_mode & S_IFLNK) == S_IFLNK) {
                current_item->filechar[0] = 'l' ;
#ifdef STANDART_FILE_CALL
                if ( stat(current_item->filename,&statbuf) < 0 ) {
#else
                if ( stat64(current_item->filename,&statbuf) < 0 ) {
#endif
                    /*
                    ** That means that the link refer to an unexisting file
                    */
                    current_item->filechar[1] = 'u' ;
                } else {
                    if ( (statbuf.st_mode & S_IFDIR) == S_IFDIR) {
                        current_item->filechar[1] = 'd' ;
                    } else {
                        current_item->filechar[1] = 'f' ;
                    }
                }
            } else {
                current_item->filechar[0] = ' ' ;
                if ( (statbuf.st_mode & S_IFDIR) == S_IFDIR) {
                    current_item->filechar[1] = 'd' ;
                } else {
                    current_item->filechar[1] = 'f' ;
                }
            }
            current_item->filechar[2] = '\0' ;
        }
        errno = 0 ;
    }
    /*
    ** Check errno in case of error during readdir
    ** for the following readir we are not going to check
    ** so that may be a cause of problem
    */
    if ( errno != 0 ) {
        sprintf(logmessage,"Error on readdir %s : %s ",dirpath,strerror(errno)) ;
        *errcode = 88 ;
        closedir(curdir) ;
        current_item = first_item ;
        while ( current_item != NULL ) {
            free(current_item->filename) ;
            used_item = current_item->next ;
            free(current_item) ;
            current_item = used_item ;
        }
        free(dirpath) ;
        return -1 ;
    }

    /*
    ** Check if numberoffile is zero and reply now in this
    ** case 
    */
    if ( numberoffile == 0 ) {
        *filelistlen = 0 ;
        closedir(curdir) ;
        current_item = first_item ;
        while ( current_item != NULL ) {
            free(current_item->filename) ;
            used_item = current_item->next ;
            free(current_item) ;
            current_item = used_item ;
        }
        free(dirpath) ;
        return 0 ;
    }
    /*
    ** Now everything is ready so prepare the answer
    */
    if ( ( *filelist = (char *) malloc (lengthtosend) ) == NULL ) {
        sprintf(logmessage,"Error allocating memory for filelist %s",strerror(errno)) ;
        *errcode = 35 ;
        closedir(curdir) ;
        current_item = first_item ;
        while ( current_item != NULL ) {
            free(current_item->filename) ;
            used_item = current_item->next ;
            free(current_item) ;
            current_item = used_item ;
        }
        free(dirpath) ;
        return -1 ;
    }
    current_item = first_item ;
    filepos = *filelist ;
    while ( current_item != NULL ) {
        sprintf(filepos,"%s",current_item->filename) ;
        filepos = filepos + strlen(filepos) + 1 ;
        sprintf(filepos,"%s",current_item->filechar) ;
        filepos = filepos + strlen(filepos) + 1 ;
        current_item = current_item->next ;
    }
    *filelistlen = lengthtosend ;
    closedir(curdir) ;
    current_item = first_item ;
    while ( current_item != NULL ) {
        free(current_item->filename) ;
        used_item = current_item->next ;
        free(current_item) ;
        current_item = used_item ;
    }
    free(dirpath) ;
    return 0 ;   
}

/*******************************************************************************
** bbftp_retrcheckdir :                                                        *
**                                                                             *
**      Routine to check a directory                                           *
**                                                                             *
**      OUPUT variable :                                                       *
**          logmessage :  to write the error message in case of error          *
**                                                                             *
**      GLOBAL VARIABLE USED :                                                 *                                                                      *
**                                                                             *
**      RETURN:                                                                *
**          -1  Unrecoverable error                                            *
**           0  OK                                                             *
**           1  recoverable error                                              *
**                                                                             *
*******************************************************************************/

int bbftp_retrcheckdir(char *filename,char *logmessage,int *errcode)
{
#ifdef STANDART_FILE_CALL
    struct stat statbuf;
#else
    struct stat64 statbuf ;
#endif
    int     savederrno ;
    /*
    ** Check if it is a rfio creation
    */
#if defined(WITH_RFIO) || defined(WITH_RFIO64)    
    if ( (transferoption & TROPT_RFIO_O) == TROPT_RFIO_O ) {
        return bbftp_retrcheckdir_rfio(filename,logmessage,errcode) ;
    }
#endif

#ifdef STANDART_FILE_CALL
    if ( stat(filename,&statbuf) < 0 ) {
#else
    if ( stat64(filename,&statbuf) < 0 ) {
#endif
        /*
        ** It may be normal to get an error if the dir
        ** does not exist but some error code must lead
        ** to the interruption of the transfer:
        **        EACCES         : Search permission denied
        **        ELOOP          : To many symbolic links on path
        **        ENAMETOOLONG   : Path argument too long
        **        ENOTDIR        : A component in path is not a directory
        */
        savederrno = errno ;
        if ( savederrno == EACCES ||
            savederrno == ELOOP ||
            savederrno == ENAMETOOLONG ||
            savederrno == ENOTDIR ) {
            sprintf(logmessage,"Error stating file %s : %s",filename,strerror(savederrno)) ;
            *errcode = 72 ;
            return -1 ;
        } else {
            return 0 ;
        }
    } else {
        /*
        ** The file exists so check if it is a directory
        */
        if ( (statbuf.st_mode & S_IFDIR) != S_IFDIR) {
            sprintf(logmessage,"File %s is not a directory",filename) ;
            *errcode = 76 ;
            return -1 ;
        }
    }
    return 0 ;   
}

/*******************************************************************************
** bbftp_retrcheckfile :                                                       *
**                                                                             *
**      Routine to check a file and set the global parameters                  *
**                                                                             *
**      OUPUT variable :                                                       *
**          logmessage :  to write the error message in case of error          *
**                                                                             *
**      GLOBAL VARIABLE USED :                                                 *                                                                      *
**          transferoption                      NOT MODIFIED                   * 
**          filemode                            MODIFIED                       *
**          lastaccess                          MODIFIED                       *
**          lastmodif                           MODIFIED                       *
**          filesize                            MODIFIED                       *
**          requestedstreamnumber               POSSIBLY MODIFIED              *
**                                                                             *
**      RETURN:                                                                *
**          -1  Unrecoverable error                                            *
**           0  OK                                                             *
**           1  recoverable error                                              *
**                                                                             *
*******************************************************************************/

int bbftp_retrcheckfile(char *filename,char *logmessage,int *errcode)
{
#ifdef STANDART_FILE_CALL
    struct stat statbuf;
#else
    struct stat64 statbuf ;
#endif
    int     tmpnbport ;
    int     savederrno ;
    /*
    ** Check if it is a rfio creation
    */
#if defined(WITH_RFIO) || defined(WITH_RFIO64)    
    if ( (transferoption & TROPT_RFIO_O) == TROPT_RFIO_O ) {
        return bbftp_retrcheckfile_rfio(filename,logmessage,errcode) ;
    }
#endif

#ifdef STANDART_FILE_CALL
    if ( stat(filename,&statbuf) < 0 ) {
#else
    if ( stat64(filename,&statbuf) < 0 ) {
#endif
        /*
        ** It may be normal to get an error if the file
        ** does not exist but some error code must lead
        ** to the interruption of the transfer:
        **        EACCES        : Search permission denied
        **        ELOOP         : To many symbolic links on path
        **        ENAMETOOLONG  : Path argument too long
        **        ENOENT        : The file does not exists
        **        ENOTDIR       : A component in path is not a directory
        */
        savederrno = errno ;
        sprintf(logmessage,"Error stating file %s : %s ",filename,strerror(savederrno)) ;
        *errcode = 72 ;
        if ( savederrno == EACCES ||
            savederrno == ELOOP ||
            savederrno == ENAMETOOLONG ||
            savederrno == ENOENT ||
            savederrno == ENOTDIR ) {
            return -1 ;
        } else {
            return 1 ;
        }
    } else {
        /*
        ** The file exists so check if it is a directory
        */
        if ( (statbuf.st_mode & S_IFDIR) == S_IFDIR) {
            sprintf(logmessage,"File %s is a directory",filename) ;
            *errcode = 73 ;
            return -1 ;
        }
    }
    if (S_ISREG(statbuf.st_mode)) {
        filemode = statbuf.st_mode & ~S_IFREG;
    } else {
        filemode = statbuf.st_mode;
    }
    sprintf(lastaccess,"%08x",statbuf.st_atime) ;
    sprintf(lastmodif,"%08x",statbuf.st_mtime) ;
    lastaccess[8] = '\0' ;
    lastmodif[8]  = '\0' ;
    filesize = statbuf.st_size ;
    tmpnbport = filesize/(buffersizeperstream*1024) ;
    if ( tmpnbport == 0 ) {
        requestedstreamnumber = 1 ;
    } else if ( tmpnbport < nbport ) {
        requestedstreamnumber = tmpnbport ;
    } else {
        requestedstreamnumber = nbport ;
    }
    return 0 ;   
}
/*******************************************************************************
** bbftp_retrtransferfile :                                                    *
**                                                                             *
**      Routine to transfer a file                                             *
**                                                                             *
**      INPUT variable :                                                       *
**          filename    :  file to send    NOT MODIFIED                        *
**                                                                             *
**      OUTPUT variable :                                                      *
**          logmessage :  to write the error message in case of error          *
**                                                                             *
**      GLOBAL VARIABLE USED :                                                 *                                                                      *
**                                                                             *
**      RETURN:                                                                *
**          -1  transfer failed unrecoverable error                            *
**           0  Keep the connection open (does not mean that the file has been *
**              successfully transfered)                                       *
**          >0  Recoverable error but calling has the cleaning to do           *
**                                                                             *
*******************************************************************************/
 
int bbftp_retrtransferfile(char *filename,char *logmessage,int *errcode) 
{
#ifdef STANDART_FILE_CALL
    off_t       nbperchild ;
    off_t       nbtosend;
    off_t       startpoint ;
    off_t       nbread ;
    off_t       numberread ;
    off_t       nbsent ;
    off_t       realnbtosend ;
#else
    off64_t     nbperchild ;
    off64_t     nbtosend;
    off64_t     startpoint ;
    off64_t     nbread ;
    off64_t     numberread ;
    off64_t     nbsent ;
    off64_t     realnbtosend ;
#endif
#ifdef WITH_GZIP
    uLong   buflen ;
    uLong   bufcomplen ;
#endif
    int     lentosend ;
    int     retcode ;

    int     *pidfree ;
    int     *socknumber ;
    int     i ;

    int     nfds ; 
    fd_set  selectmask ;
    struct timeval    wait_timer;
    int     fd ;

    struct mess_compress *msg_compress ;
    struct message *msg ;
    int     compressionon ;
    int     sendsock ;
    int     *portnumber ;
    extern  int     simulation_mode ;

    /*
    ** Check if it is a rfio transfer
    */
#if defined(WITH_RFIO) || defined(WITH_RFIO64)    
    if ( (transferoption & TROPT_RFIO_O) == TROPT_RFIO_O ) {
        return bbftp_retrtransferfile_rfio(filename,logmessage,errcode) ;
    }
#endif
    if (protocol == 2) { /* Active mode */
      socknumber = mysockets ;
	} else { /* Passive mode */
	  portnumber = myports ;
	}
    nbperchild = filesize/requestedstreamnumber ;
    pidfree = mychildren ;

    /*
    ** Now start all our children
    */
    for (i = 1 ; i <= requestedstreamnumber ; i++) {
        if ( i == requestedstreamnumber ) {
            startpoint = (i-1)*nbperchild;
            nbtosend = filesize-(nbperchild*(requestedstreamnumber-1)) ;
        } else {
            startpoint = (i-1)*nbperchild;
            nbtosend = nbperchild ;
        }
        if (protocol == 2) {
		  sendsock = *socknumber ;
		  socknumber++ ;
		} else { /* Passive mode */
          /*
          ** Now create the socket to send
          */
          sendsock = 0 ;
          while (sendsock == 0 ) {
            sendsock = bbftp_createdatasock(*portnumber/*,logmessage*/) ;
          }
          if ( sendsock < 0 ) {
            /*
            ** We set childendinerror to 1 in order to prevent the father
            ** to send a BAD message which can desynchronize the client and the
            ** server (We need only one error message)
            ** Bug discovered by amlutz on 2000/03/11
            */
		  /*            if ( childendinerror == 0 ) {
                childendinerror = 1 ;
                reply(MSG_BAD,logmessage) ;
				}
				clean_child() ;*/
            return 1 ;
          }
          portnumber++ ;
          /*
          ** Set flagsighup to zero in order to be able in child
          ** not to wait STARTCHILDTO if signal was sent before 
          ** entering select. (Seen on Linux with one child)
          */
          /*flagsighup = 0 ;*/
		}
        if ( (retcode = fork()) == 0 ) {
            int     ns ;
            blockallsignals() ;
            /*
            ** We are in child
            */
            /* 
            ** In child the first thing to do is to 
            ** close the control socket, and all the 
            ** socket not concerning itself
            */
            close(STDIN_FILENO) ;
            close(STDOUT_FILENO) ;
            close(STDERR_FILENO) ;
            close(incontrolsock) ;
            close(outcontrolsock) ; 
			if (protocol == 2) { /* Active mode */
              int     *socktoclose ;
              socktoclose = mysockets ;
              for ( i=0 ; i< requestedstreamnumber ; i++ ) {
                if ( *socktoclose !=  sendsock) close(*socktoclose) ;
                socktoclose++ ;
              }
			}
            /*
            ** And open the file 
            */
#ifdef STANDART_FILE_CALL
            if ( (fd = open(filename,O_RDONLY|O_BINARY)) < 0 ) {
#else
            if ( (fd = open64(filename,O_RDONLY|O_BINARY)) < 0 ) {
#endif
                /*
                ** An error on openning the local file is considered
                ** as fatal. Maybe this need to be improved depending
                ** on errno
                */
                i = errno ;
                _exit(i) ;
            }
#ifdef STANDART_FILE_CALL
            if ( lseek(fd,startpoint,SEEK_SET) < 0 ) {
#else
            if ( lseek64(fd,startpoint,SEEK_SET) < 0 ) {
#endif
                i = errno ;
                close(fd) ;
                _exit(i)  ;
            }
            /*
            ** We are now just going to select on our 
            ** socket
            **/
            nfds = sysconf(_SC_OPEN_MAX) ;
            FD_ZERO(&selectmask) ;
            FD_SET(sendsock,&selectmask) ;
            /*
            ** Set the timer for the connection
            */
            wait_timer.tv_sec  = CHILDWAITTIME ;
            wait_timer.tv_usec = 0 ;
            if (protocol == 2) {
                retcode = select(FD_SETSIZE,&selectmask,0,0,&wait_timer) ;
            } else {
                retcode = select(FD_SETSIZE,0,&selectmask,0,&wait_timer) ;
            }
            if ( retcode < 0 ) {
                /*
                ** select return in error 
                ** Let us sleep a while in order to let
                ** the father fork all its children
                */
                i = errno ;
                close(fd) ;
                sleep(CHILDWAITTIME) ;
                _exit(i) ;
            }
            if ( retcode == 0 ) {
                /*
                ** That is a time out let us exit 
                ** with the time out error
                */
                close(fd) ;
                _exit(ETIMEDOUT) ;
            }
            /*
            ** At this point as we only set one bit we have 
            ** got a connection
            */
			if (protocol == 2) { /* Active mode */
              if ( (ns = accept(sendsock,0,0) ) < 0 ) {
                i = errno ;
                close(fd) ;
                _exit(i) ;
              }
              /*
              ** Close the listening socket
              */
              close(sendsock) ;
			} else {
			  ns = sendsock ;
			  /*close(sendsock) ;*/
			}
            /*
            ** Start the sending loop
            ** In simulation mode, simulate the transfer
            */
            if (!simulation_mode) {
              nbread = 0 ;
              while ( nbread < nbtosend ) {
                if ( (numberread = read ( fd, readbuffer, ( (buffersizeperstream*1024) <= nbtosend - nbread) ?  (buffersizeperstream*1024) : nbtosend-nbread) ) > 0 ) {
                    nbread = nbread+numberread ;
#ifdef WITH_GZIP                    
                    if ( (transferoption & TROPT_GZIP ) == TROPT_GZIP ) {
                        /*
                        ** In case of compression we are going to use
                        ** a temporary buffer
                        */
                        bufcomplen = buffersizeperstream*1024 ;
                        buflen = numberread ;
                        retcode = compress((Bytef *)compbuffer,&bufcomplen,(Bytef *)readbuffer,buflen) ;
                        if ( retcode != 0 ) {
                            msg_compress = ( struct mess_compress *) compbuffer;
                            /*
                            ** Compress error, in this cas we are sending the
                            ** date uncompressed
                            */
                            msg_compress->code = DATA_NOCOMPRESS ;
                            lentosend = numberread ;
#ifndef WORDS_BIGENDIAN
                            msg_compress->datalen = ntohl(lentosend) ;
#else
                            msg_compress->datalen = lentosend ;
#endif
                            realnbtosend = numberread ;
                        } else {
                            memcpy(readbuffer,compbuffer,buffersizeperstream*1024) ;
                            msg_compress = ( struct mess_compress *) compbuffer;
                            msg_compress->code = DATA_COMPRESS ;
                            lentosend = bufcomplen ;
#ifndef WORDS_BIGENDIAN
                            msg_compress->datalen = ntohl(lentosend) ;
#else
                            msg_compress->datalen = lentosend ;
#endif
                            realnbtosend =  bufcomplen ;
                        }
                        /*
                        ** Send the header
                        */
                        if ( writemessage(ns,compbuffer,COMPMESSLEN,datato,1) < 0 ) {
                            i = ETIMEDOUT ;
                            _exit(i) ;
                        }
                    } else {
                        realnbtosend = numberread ;
                    }
#else
                    realnbtosend = numberread ;
#endif                    
                    /*
                    ** Send the data
                    */
                    nbsent = 0 ;
                    while ( nbsent < realnbtosend ) {
                        lentosend = realnbtosend-nbsent ;
                        nfds = sysconf(_SC_OPEN_MAX) ;
                        FD_ZERO(&selectmask) ;
                        FD_SET(ns,&selectmask) ;
                        wait_timer.tv_sec  = datato  ;
                        wait_timer.tv_usec = 0 ;
                        if ( (retcode = select(FD_SETSIZE,0,&selectmask,0,&wait_timer) ) == -1 ) {
                            /*
                            ** Select error
                            */
                            i = errno ;
                            close(fd) ;
                            close(ns) ;
                            _exit(i) ;
                        } else if ( retcode == 0 ) {
                            close(fd) ;
                            i=ETIMEDOUT ;
                            close(ns) ;
                            _exit(i) ;
                        } else {
                            retcode = send(ns,&readbuffer[nbsent],lentosend,0) ;
                            if ( retcode < 0 ) {
                                i = errno ;
                                close(fd) ;
                                close(ns) ;
                                _exit(i) ;
                            } else if ( retcode == 0 ) {
                                i = ECONNRESET ;
                                close(fd) ;
                                close(ns) ;
                                _exit(i) ;
                            } else {
                                nbsent = nbsent+retcode ;
                            }
                        }
                    }
                } else {
                    i = errno ;
                    close(ns) ;
                    close(fd) ;
                    _exit(i) ;
                }
              }
              close(fd) ;
              /*
              ** All data has been sent so wait for the acknoledge
              */
              if ( readmessage(ns,readbuffer,MINMESSLEN,ackto,1) < 0 ) {
                close(ns) ;
                _exit(ETIMEDOUT) ;
              }
              msg = (struct message *) readbuffer ;
              if ( msg->code != MSG_ACK) {
                close(ns) ;
                _exit(1) ;
              }
			}
            close(ns) ;
            _exit(0) ;
        } else {
            /*
            ** We are in father
            */
            if ( retcode == -1 ) {
                /*
                ** Fork failed ...
                */
                sprintf(logmessage,"Fork failed : %s\n",strerror(errno)) ;
                *errcode = 36 ;
                sprintf(logmessage,"fork failed : %s ",strerror(errno)) ;
                bbftp_clean_child() ;
                return -1 ;
            } else {
                *pidfree++ = retcode ;
		close(sendsock) ;
                /*socknumber++ ;*/
            }
        }
    }
    return 0 ;
}
Esempio n. 15
0
int sendproto() 
{

    char    buffer[8] ;
    struct  message *msg ;
    int     remoteprotomin ;
    int     remoteprotomax ;
    fd_set  selectmask ; /* Select mask */
    int     nfds ; /* Max number of file descriptor */
    int     code ;
    int     retcode ;
    int     msglen ;
  

    if ( debug ) printmessage(stdout,CASE_NORMAL,0,timestamp,"Sending protocol request\n") ;
    /* 
    ** Now send the control message : First part
    */
    msg = (struct message *)buffer ;
    msg->code = MSG_PROT ;
    msg->msglen = 0 ;
    if ( writemessage(outcontrolsock,buffer,MINMESSLEN,sendcontrolto,0) < 0 ) {
        /*
        ** We were not able to send the minimum message so
        ** we are going to close the control socket and to 
        ** tell the calling program to restart a connection
        */
        printmessage(stderr,CASE_ERROR,64,timestamp,"Error sending %s message\n","MSG_PROT");
        return -1 ; /* restart connection */
    }
    if ( debug ) printmessage(stdout,CASE_NORMAL,0,timestamp,"Sent message %x\n", msg->code) ;
    /*
    ** Now we are going to wait for the message on the control 
    ** connection
    */
waitcontrol:
    nfds = sysconf(_SC_OPEN_MAX) ;
    FD_ZERO(&selectmask) ;
    FD_SET(incontrolsock,&selectmask) ;
    retcode = select(FD_SETSIZE,&selectmask,0,0,0) ;
    if ( retcode < 0 ) {
        /*
        ** Select error
        */
        if ( errno != EINTR ) {
            /*
            ** we have got an error so close the connection
            ** and restart
            */
            printmessage(stderr,CASE_ERROR,66,timestamp,"Error select on control connection : %s\n",strerror(errno));
            return -1 ;
        } else {
            /*
            ** Interrupted by a signal
            */
            FD_ZERO(&selectmask) ;
            FD_SET(incontrolsock,&selectmask) ;
            goto waitcontrol ;
        }
    } else if ( retcode == 0 ) {
        /*
        ** Impossible we do not set any timer
        */
        FD_ZERO(&selectmask) ;
        FD_SET(incontrolsock,&selectmask) ;
        goto waitcontrol ;
    } else {
        /*
        ** read the message
        */
        if ( readmessage(incontrolsock,buffer,MINMESSLEN,recvcontrolto,0) < 0 ) {
            printmessage(stderr,CASE_ERROR,61,timestamp,"Error waiting %s message\n","MSG_PROT_ANS");
            return -1 ;
        }
        msg = (struct message *)buffer ;
        code = msg->code ;
        if ( code == MSG_BAD || code == MSG_BAD_NO_RETRY) {
            /*
            ** The server does not understand protocol 
            */
            printmessage(stderr,CASE_FATAL_ERROR,101,timestamp,"Incompatible deamon and client (remote protocol version (%d,%d), local (%d,%d))\n",1,1,protocolmin,protocolmax);
            
        } else if (msg->code == MSG_PROT_ANS ) {
            /*
            ** At this stage 
            */
#ifndef WORDS_BIGENDIAN
            msglen = ntohl(msg->msglen) ;
#else
            msglen = msg->msglen ;
#endif
            if ( msglen != 8 ) {
                printmessage(stderr,CASE_ERROR,63,timestamp,"Unexpected message length while waiting for %s message\n","MSG_PROT_ANS");
                 return -1 ;
            }
            if ( readmessage(incontrolsock,buffer,msglen,recvcontrolto,0) < 0) {
                printmessage(stderr,CASE_ERROR,67,timestamp,"Error reading data for %s message\n","MSG_PROT_ANS");
                return -1 ;
            }
#ifndef WORDS_BIGENDIAN
            remoteprotomin = ntohl(msg->code) ;
            remoteprotomax = ntohl(msg->msglen) ;
#else
            remoteprotomin = msg->code ;
            remoteprotomax = msg->msglen ;
#endif            
            if ( (remoteprotomax < protocolmin) || (remoteprotomin > protocolmax) ) {
                /*
                ** Imcompatible version
                */
                msg->code = MSG_BAD_NO_RETRY ;
                msg->msglen = 0 ;
                writemessage(outcontrolsock,buffer,MINMESSLEN,recvcontrolto,0); 
                printmessage(stderr,CASE_FATAL_ERROR,101,timestamp,"Incompatible deamon and client (remote protocol version (%d,%d), local (%d,%d))\n",remoteprotomin,remoteprotomax,protocolmin,protocolmax);
               
            } else if (remoteprotomax <= protocolmax ) {
                protocol = remoteprotomax ;
            } else {
                protocol = protocolmax ;
            }
            msg->code = MSG_PROT_ANS ;
#ifndef WORDS_BIGENDIAN
            msg->msglen = ntohl(4) ;
#else
            msg->msglen = 4 ;
#endif
            if ( writemessage(outcontrolsock,buffer,MINMESSLEN,recvcontrolto,0) < 0 ){
                printmessage(stderr,CASE_ERROR,64,timestamp,"Error sending %s message\n","MSG_PROT_ANS");
                return -1 ; /* restart connection */
            }
#ifndef WORDS_BIGENDIAN
            msg->code = ntohl(protocol) ;
#else
            msg->code = protocol ;
#endif
            if ( writemessage(outcontrolsock,buffer,4,recvcontrolto,0) < 0 ){
                printmessage(stderr,CASE_ERROR,64,timestamp,"Error sending %s message\n","MSG_PROT_ANS");
                return -1 ; /* restart connection */
            }
            return 0 ;
        } else {
            /*
            ** Receive unkwown message so something is
            ** going wrong. close the control socket
            ** and restart
            */
            printmessage(stderr,CASE_ERROR,62,timestamp,"Unknown message while waiting for %s message\n","MSG_PROT_ANS");
            return -1 ;
        }
    }
    /*
    ** Never reach this point but to in order to avoid stupid messages
    ** from IRIX compiler set a return code to -1
    */
    return -1 ;

}
Esempio n. 16
0
Response kConnection::receive_response() {
	Response r;
	auto s = readmessage();
	r.ParseFromString(s);
	return r;
}