652 lines
19 KiB
C
652 lines
19 KiB
C
/* script.c version 0.14.08
|
|
|
|
part of rutty - a modified version of putty
|
|
Copyright 2013, Ernst Dijk
|
|
*/
|
|
|
|
/* proto's
|
|
*/
|
|
void script_setsend(ScriptData * scriptdata);
|
|
void script_record_stop(ScriptData * scriptdata);
|
|
BOOL script_record_line(ScriptData * scriptdata, int remote);
|
|
int script_cond_chk(char *ref, int rc, char *data, int dc);
|
|
void script_cond_set(char * cond, int *p, char *in, int sz);
|
|
int script_chkline(ScriptData * scriptdata);
|
|
void script_timeout(void *ctx, long now);
|
|
void script_sendline(void *ctx, long now);
|
|
void script_sendchar(void *ctx, long now);
|
|
void script_getline(ScriptData * scriptdata);
|
|
|
|
|
|
/* init scriptdata structure
|
|
copy/translate settings from scripting panel
|
|
*/
|
|
void script_init(ScriptData * scriptdata, Conf * conf)
|
|
{
|
|
scriptdata->line_delay = conf_get_int(conf, CONF_script_line_delay);
|
|
if(scriptdata->line_delay<5)
|
|
scriptdata->line_delay = 5;
|
|
scriptdata->line_delay = scriptdata->line_delay * TICKSPERSEC / 1000;
|
|
scriptdata->char_delay = conf_get_int(conf, CONF_script_char_delay) * TICKSPERSEC / 1000;
|
|
scriptdata->cond_char = conf_get_str(conf, CONF_script_cond_line)[0];
|
|
if(scriptdata->cond_char =='\0')
|
|
scriptdata->cond_char =':'; /* if none use default */
|
|
scriptdata->enable = conf_get_int(conf, CONF_script_enable);
|
|
scriptdata->cond_use = (scriptdata->enable)?conf_get_int(conf, CONF_script_cond_use):FALSE; /* can only be true if wait is enabled */
|
|
scriptdata->except = conf_get_int(conf, CONF_script_except);
|
|
scriptdata->timeout = conf_get_int(conf, CONF_script_timeout) * TICKSPERSEC ; /* in winstuff.h */
|
|
|
|
script_cond_set(scriptdata->waitfor, &scriptdata->waitfor_c, conf_get_str(conf, CONF_script_waitfor), strlen(conf_get_str(conf, CONF_script_waitfor)));
|
|
script_cond_set(scriptdata->halton, &scriptdata->halton_c, conf_get_str(conf, CONF_script_halton), strlen(conf_get_str(conf, CONF_script_halton)));
|
|
|
|
scriptdata->crlf = conf_get_int(conf, CONF_script_crlf);
|
|
|
|
scriptdata->waitfor2[0] = '\0';
|
|
scriptdata->waitfor2_c = -1; /* -1= there is no condition from file, 0= there an empty line (cr/lf) */
|
|
|
|
scriptdata->runs = FALSE;
|
|
scriptdata->send = FALSE;
|
|
scriptdata->filebuffer = NULL;
|
|
|
|
scriptdata->latest = 0;
|
|
|
|
scriptdata->remotedata_c = script_cond_size;
|
|
scriptdata->remotedata[0] = '\0' ;
|
|
|
|
scriptdata->localdata_c = 0 ;
|
|
scriptdata->localdata[0] = '\0' ;
|
|
|
|
}
|
|
|
|
|
|
/* send script file to host
|
|
assume script file short - read complete file in memory
|
|
makes read ahead to detect lf lf possible
|
|
*/
|
|
BOOL script_sendfile(ScriptData * scriptdata, Filename * scriptfile)
|
|
{
|
|
FILE * fp;
|
|
long fsize;
|
|
if(scriptdata->runs)
|
|
return FALSE; /* a script is already running */
|
|
|
|
fp = f_open(scriptfile, "rb", FALSE);
|
|
if(fp==NULL)
|
|
{
|
|
logevent(NULL, "script file not found");
|
|
return FALSE; /* scriptfile not found or something like it */
|
|
}
|
|
|
|
scriptdata->runs = TRUE;
|
|
script_menu(scriptdata);
|
|
|
|
fseek(fp, 0L, SEEK_END);
|
|
fsize = ftell(fp); /* script file size */
|
|
fseek(fp, 0L, SEEK_SET);
|
|
|
|
scriptdata->nextnextline = scriptdata->filebuffer = smalloc(fsize);
|
|
scriptdata->filebuffer_end = &scriptdata->filebuffer[fsize];
|
|
|
|
if(fread(scriptdata->filebuffer,sizeof(char),fsize,fp)!=fsize)
|
|
{
|
|
logevent(NULL, "script file read failed");
|
|
fclose(fp);
|
|
script_close(scriptdata);
|
|
return FALSE;
|
|
}
|
|
|
|
fclose(fp);
|
|
|
|
logevent(NULL, "sending script to host ...");
|
|
|
|
script_getline(scriptdata);
|
|
script_chkline(scriptdata);
|
|
|
|
if(scriptdata->enable && !scriptdata->except) /* start timeout if wait for prompt is enabled */
|
|
{
|
|
scriptdata->send = FALSE;
|
|
scriptdata->latest = schedule_timer(scriptdata->timeout, (timer_fn_t)script_timeout, scriptdata);
|
|
}
|
|
else
|
|
{
|
|
scriptdata->send = TRUE;
|
|
schedule_timer(scriptdata->line_delay, (timer_fn_t)script_sendline, scriptdata);
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/* find nextline in buffer
|
|
*/
|
|
int script_findline(ScriptData * scriptdata)
|
|
{
|
|
if(scriptdata->filebuffer==NULL)
|
|
return FALSE;
|
|
|
|
if(scriptdata->nextnextline >= scriptdata->filebuffer_end) /* end of filebuffer */
|
|
return FALSE;
|
|
|
|
scriptdata->nextline = scriptdata->nextnextline;
|
|
scriptdata->nextline_c = 0;
|
|
while(scriptdata->nextnextline < scriptdata->filebuffer_end && scriptdata->nextnextline[0] !='\n')
|
|
{
|
|
scriptdata->nextnextline++;
|
|
scriptdata->nextline_c++;
|
|
}
|
|
|
|
if(scriptdata->nextnextline < scriptdata->filebuffer_end)
|
|
{
|
|
/* while loop ended due lf found, correct pointers to point to next nextline */
|
|
scriptdata->nextnextline++;
|
|
scriptdata->nextline_c++;
|
|
|
|
/* cr, lf and crlf are recorded as crlf, lflf and crlflflf
|
|
correct pointers so nextnextline points to the next nextline
|
|
and nextline_c is the size of nextline
|
|
in script file real data
|
|
data lf data
|
|
data lf lf data lf ** correct pointer +1
|
|
data cr lf data cr
|
|
data cr lf lf lf data cr lf ** correct pointer +2
|
|
data cr lf lf data cr lf ** this can't be recorded, user edit
|
|
1: -2 -1 0 +1
|
|
2: -3 -2 -1 0
|
|
*/
|
|
if(scriptdata->crlf==SCRIPT_REC)
|
|
{
|
|
/* 1: not past end of buffer and char is a lf */
|
|
if(scriptdata->nextnextline < scriptdata->filebuffer_end && scriptdata->nextnextline[0]=='\n')
|
|
{
|
|
scriptdata->nextnextline++;
|
|
scriptdata->nextline_c++;
|
|
|
|
/* 2: not before buffer start and char at position -3 is a cr
|
|
also not past buffer end and char is a lf
|
|
*/
|
|
if( &scriptdata->nextnextline[-3] >= scriptdata->filebuffer && scriptdata->nextnextline[-3]=='\r'
|
|
&& scriptdata->nextnextline < scriptdata->filebuffer_end && scriptdata->nextnextline[0]=='\n' )
|
|
{
|
|
scriptdata->nextnextline++;
|
|
//scriptdata->nextline_c++;
|
|
}
|
|
}
|
|
/* correct nextlinesize, remove the lf we added while recording */
|
|
scriptdata->nextline_c--;
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/* read a line from script file
|
|
skip comment/condition lines if conditions are disabled
|
|
if conditions are enabled skip only comments
|
|
e.g. if ':' is the condition marker:
|
|
:condition, the prompt from host were we will wait for
|
|
::comment, a comment line
|
|
*/
|
|
void script_getline(ScriptData * scriptdata)
|
|
{
|
|
int neof;
|
|
int i;
|
|
|
|
if(!scriptdata->runs || scriptdata->filebuffer==NULL)
|
|
return;
|
|
|
|
do {
|
|
do
|
|
neof=script_findline(scriptdata);
|
|
while(neof && ( (!scriptdata->cond_use && scriptdata->nextline[0]==scriptdata->cond_char)
|
|
|| ( scriptdata->cond_use && scriptdata->nextline[0]==scriptdata->cond_char
|
|
&& scriptdata->nextline[1]==scriptdata->cond_char ) ) ) ;
|
|
if(!neof)
|
|
{
|
|
scriptdata->nextline_c = 0;
|
|
scriptdata->nextline_cc = 0;
|
|
return;
|
|
}
|
|
|
|
i = scriptdata->nextline_c ;
|
|
switch(scriptdata->crlf) /* translate cr/lf */
|
|
{
|
|
case SCRIPT_OFF: /* no translation */
|
|
break;
|
|
|
|
case SCRIPT_NOLF: /* remove LF (recorded file)*/
|
|
if(scriptdata->nextline[i-1]=='\n')
|
|
i--;
|
|
break;
|
|
|
|
case SCRIPT_CR: /* replace cr/lf by cr */
|
|
if(scriptdata->nextline[i-1]=='\n')
|
|
i--;
|
|
if(i>0 && scriptdata->nextline[i-1]=='\r')
|
|
i--;
|
|
scriptdata->nextline[i++]='\r';
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
} while(i==0); /* skip empty lines */
|
|
scriptdata->nextline_c = i;
|
|
scriptdata->nextline_cc = 0;
|
|
}
|
|
|
|
|
|
/* close script file
|
|
*/
|
|
void script_close(ScriptData * scriptdata)
|
|
{
|
|
scriptdata->runs=FALSE;
|
|
|
|
expire_timer_context(scriptdata); /* seems it dusn't work in windows */
|
|
scriptdata->latest = 0; /* so block previous timeouts this way */
|
|
|
|
script_menu(scriptdata);
|
|
|
|
if(scriptdata->filebuffer!=NULL)
|
|
{
|
|
sfree(scriptdata->filebuffer);
|
|
scriptdata->filebuffer = NULL;
|
|
}
|
|
}
|
|
|
|
|
|
/* send line, called by timer after linedelay
|
|
*/
|
|
void script_sendline(void *ctx, long now)
|
|
{
|
|
ScriptData *scriptdata = (ScriptData *) ctx;
|
|
|
|
if(!scriptdata->runs) /* script terminated */
|
|
return;
|
|
|
|
if(scriptdata->nextline_c==0) /* no more lines */
|
|
{
|
|
script_close(scriptdata);
|
|
logevent(NULL, " ...finished sending script");
|
|
return;
|
|
}
|
|
|
|
if(scriptdata->char_delay>1)
|
|
{
|
|
schedule_timer(scriptdata->char_delay, (timer_fn_t)script_sendchar, scriptdata);
|
|
return;
|
|
}
|
|
|
|
if(scriptdata->char_delay==0)
|
|
ldisc_send(ldisc, scriptdata->nextline, scriptdata->nextline_c, 0);
|
|
else
|
|
{
|
|
int i;
|
|
for(i=0;i<scriptdata->nextline_c;i++)
|
|
ldisc_send(ldisc, &scriptdata->nextline[i], 1, 0);
|
|
}
|
|
|
|
script_getline(scriptdata);
|
|
script_chkline(scriptdata);
|
|
|
|
if(scriptdata->enable)
|
|
{
|
|
scriptdata->send = FALSE;
|
|
scriptdata->latest = schedule_timer(scriptdata->timeout, (timer_fn_t)script_timeout, scriptdata);
|
|
}
|
|
else
|
|
{
|
|
schedule_timer(scriptdata->line_delay, (timer_fn_t)script_sendline, scriptdata);
|
|
}
|
|
return;
|
|
}
|
|
|
|
|
|
/* send char, called by timer after char_delay
|
|
*/
|
|
void script_sendchar(void *ctx, long now)
|
|
{
|
|
ScriptData *scriptdata = (ScriptData *) ctx;
|
|
|
|
if(!scriptdata->runs) /* script terminated */
|
|
return;
|
|
|
|
if(scriptdata->nextline_c==0) /* no more lines */ /* can never happen? it's captured by send line */
|
|
{
|
|
script_close(scriptdata);
|
|
logevent(NULL, "....finished sending script");
|
|
return;
|
|
}
|
|
|
|
/* send char */
|
|
if(scriptdata->nextline_cc < scriptdata->nextline_c)
|
|
ldisc_send(ldisc, &scriptdata->nextline[scriptdata->nextline_cc++], 1, 0);
|
|
|
|
/* set timer for next */
|
|
if(scriptdata->nextline_cc < scriptdata->nextline_c)
|
|
{
|
|
schedule_timer(scriptdata->char_delay, (timer_fn_t)script_sendchar, scriptdata);
|
|
return;
|
|
}
|
|
|
|
/* last char - get next line and set timer */
|
|
script_getline(scriptdata);
|
|
script_chkline(scriptdata);
|
|
|
|
if(scriptdata->enable)
|
|
{
|
|
scriptdata->send = FALSE;
|
|
scriptdata->latest = schedule_timer(scriptdata->timeout, (timer_fn_t)script_timeout, scriptdata);
|
|
}
|
|
else
|
|
{
|
|
schedule_timer(scriptdata->line_delay, (timer_fn_t)script_sendline, scriptdata);
|
|
}
|
|
return;
|
|
}
|
|
|
|
|
|
/* called by timer after wait for prompt timeout
|
|
*/
|
|
void script_timeout(void *ctx, long now)
|
|
{
|
|
ScriptData * scriptdata = (ScriptData *) ctx;
|
|
|
|
/* disable timer seems not to be working, timeout is disabled by keeping track of time */
|
|
if(abs(now - scriptdata->latest)<50)
|
|
{
|
|
script_close(scriptdata);
|
|
script_fail("script timeout !");
|
|
}
|
|
}
|
|
|
|
|
|
/* check line in nextline buffer
|
|
if it's a condition copy/translate it to 'waitfor' and read the nextline
|
|
*/
|
|
int script_chkline(ScriptData * scriptdata)
|
|
{
|
|
if(scriptdata->nextline_c>0 && scriptdata->nextline[0]==scriptdata->cond_char)
|
|
{
|
|
script_cond_set(scriptdata->waitfor2,&scriptdata->waitfor2_c,&scriptdata->nextline[1],scriptdata->nextline_c-1);
|
|
script_getline(scriptdata);
|
|
return TRUE;
|
|
}
|
|
else
|
|
{
|
|
scriptdata->waitfor2_c = -1;
|
|
scriptdata->waitfor2[0] = '\0';
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/* copy condition from settings or scriptfile to scriptdata structure
|
|
there are 2 options:
|
|
condition line - the complete line must mach before the script is continued or halted
|
|
"word1" "word2" - if one of these words is found the script is continued or halted
|
|
note: the first char must be "
|
|
|
|
'waitfor' and 'halton' are string lists, strings seperated by \0
|
|
lateron we compare it backwards, from end to start, to make that easier the terminating \0 is at start !
|
|
*/
|
|
void script_cond_set(char * cond, int *p, char *in, int sz)
|
|
{
|
|
int i = 0;
|
|
(*p) = 0;
|
|
|
|
while(sz>0 && (in[sz-1] =='\n' || in[sz-1] =='\r')) /* remove cr/lf */
|
|
sz--;
|
|
|
|
if(sz==0)
|
|
{
|
|
cond[*p]='\0';
|
|
}
|
|
else if(in[0]!='"')
|
|
{
|
|
if(sz>(script_cond_size-1))
|
|
i = sz - (script_cond_size-1); /* line to large - use only last part */
|
|
cond[(*p)++]='\0';
|
|
while(i<sz)
|
|
cond[(*p)++] = in[i++];
|
|
}
|
|
else
|
|
{
|
|
if(sz>script_cond_size)
|
|
sz = script_cond_size; /* word list to large, use only first part */
|
|
i++;
|
|
while(i<sz)
|
|
{
|
|
cond[(*p)++] = '\0';
|
|
while(i<sz && in[i]!='"')
|
|
cond[(*p)++] = in[i++];
|
|
i++;
|
|
while(i<sz && in[i]==' ')
|
|
i++;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* compare received 'data' with our condition list 'ref'
|
|
'ref' is a list of words, from end to start, terminated with \0
|
|
'dc' and 'rc' points to the end+1
|
|
if 'data' has an \0 in it compare will fail
|
|
*/
|
|
int script_cond_chk(char *ref, int rc, char *data, int dc)
|
|
{
|
|
int rcc = rc;
|
|
int dcc = dc;
|
|
|
|
while(rcc>0 && dcc>0)
|
|
{
|
|
do {
|
|
rcc--;
|
|
dcc--;
|
|
} while (rcc>=0 && dcc>=0 && ref[rcc]==data[dcc]);
|
|
|
|
if(ref[rcc]=='\0')
|
|
return TRUE;
|
|
|
|
/* no match - find next word in list*/
|
|
dcc = dc;
|
|
while(rcc>0 && ref[--rcc]!='\0')
|
|
; /* all done in loop */
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/* setup send line
|
|
*/
|
|
void script_setsend(ScriptData * scriptdata)
|
|
{
|
|
//expire_timer_context(scriptdata); /* stop timeout */
|
|
scriptdata->latest = 0;
|
|
|
|
if(scriptdata->nextline_c == 0) /* no more data */
|
|
{
|
|
script_close(scriptdata);
|
|
logevent(NULL, "... finished sending script");
|
|
return;
|
|
}
|
|
|
|
if(script_chkline(scriptdata)) /* new condition - restart timeout */
|
|
{
|
|
scriptdata->send = FALSE;
|
|
scriptdata->latest = schedule_timer(scriptdata->timeout, (timer_fn_t)script_timeout, scriptdata);
|
|
}
|
|
else /* data - set line delay timer */
|
|
{
|
|
scriptdata->send = TRUE;
|
|
schedule_timer(scriptdata->line_delay, (timer_fn_t)script_sendline, scriptdata);
|
|
}
|
|
}
|
|
|
|
|
|
/* capture data from host
|
|
check if thats were we are waiting for
|
|
*/
|
|
void script_remote(ScriptData * scriptdata, const char * data, int len)
|
|
{
|
|
int i = 0 ;
|
|
for (;i<len;i++)
|
|
{
|
|
if(data[i]=='\n' || data[i]=='\r' || data[i]=='\0' )
|
|
{
|
|
/* no need to record cr/lf - we add a lf when writing it to file */
|
|
/* we must prevent recording empty lines - incase cr is followed by lf */
|
|
if(scriptdata->remotedata_c > script_cond_size)
|
|
script_record_line(scriptdata, TRUE);
|
|
|
|
/* reset buffer */
|
|
scriptdata->remotedata_c = script_cond_size ;
|
|
scriptdata->remotedata[scriptdata->remotedata_c] = '\0' ;
|
|
}
|
|
else
|
|
{
|
|
/* if buffer full, copy last 'script_cond_size' bytes to first part of the buffer */
|
|
if(scriptdata->remotedata_c>=script_line_size)
|
|
{
|
|
int j = script_line_size - script_cond_size;
|
|
script_record_line(scriptdata, TRUE);
|
|
scriptdata->remotedata_c = 0;
|
|
while(scriptdata->remotedata_c < script_cond_size)
|
|
scriptdata->remotedata[scriptdata->remotedata_c++]=scriptdata->remotedata[j++];
|
|
}
|
|
scriptdata->remotedata[scriptdata->remotedata_c++]=data[i];
|
|
}
|
|
|
|
if (scriptdata->runs)
|
|
{
|
|
/* test for halton */
|
|
if(scriptdata->halton_c > 0 && script_cond_chk(scriptdata->halton,scriptdata->halton_c,scriptdata->remotedata,scriptdata->remotedata_c))
|
|
{
|
|
script_close(scriptdata);
|
|
logevent(NULL, "script halted");
|
|
script_fail("script halted");
|
|
return;
|
|
}
|
|
|
|
/* test for waitfor, e.g. the prompt to send the next line */
|
|
if(scriptdata->enable && !scriptdata->send)
|
|
{
|
|
if(scriptdata->waitfor2_c >= 0) /* use prompt from script file */
|
|
{
|
|
if( scriptdata->waitfor2_c == 0 || script_cond_chk(scriptdata->waitfor2,scriptdata->waitfor2_c,scriptdata->remotedata,scriptdata->remotedata_c) )
|
|
script_setsend(scriptdata);
|
|
}
|
|
else if( scriptdata->waitfor_c == 0 || script_cond_chk(scriptdata->waitfor,scriptdata->waitfor_c,scriptdata->remotedata,scriptdata->remotedata_c) )
|
|
{
|
|
script_setsend(scriptdata);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* capture data entered by the user
|
|
*/
|
|
void script_local(ScriptData * scriptdata, const char * data, int len)
|
|
{
|
|
int i = 0 ;
|
|
if(len<0) len = strlen(data);
|
|
for (;i<len;i++)
|
|
{
|
|
if(scriptdata->localdata_c>=script_line_size)
|
|
{
|
|
/* buffer full */
|
|
script_record_line(scriptdata, FALSE);
|
|
scriptdata->localdata_c = 0;
|
|
scriptdata->localdata[scriptdata->localdata_c] = '\0' ;
|
|
}
|
|
|
|
if(data[i]=='\r' || data[i]=='\n')
|
|
{
|
|
/* we need to record all data, including cr/lf
|
|
a lf is also used to mark the end of a line in the file
|
|
a lf entered by the user is recorded as lf lf, and a cr as cr lf
|
|
*/
|
|
scriptdata->localdata[scriptdata->localdata_c++]=data[i];
|
|
script_record_line(scriptdata, FALSE);
|
|
scriptdata->localdata_c = 0 ;
|
|
scriptdata->localdata[scriptdata->localdata_c] = '\0' ;
|
|
}
|
|
else
|
|
{
|
|
scriptdata->localdata[(scriptdata->localdata_c)++]=data[i];
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* start script recording
|
|
*/
|
|
BOOL script_record(ScriptData * scriptdata, Filename * script_filename)
|
|
{
|
|
if(scriptdata->scriptrecord != NULL)
|
|
return FALSE;
|
|
|
|
if ((scriptdata->scriptrecord = f_open(script_filename, "r", FALSE))!=NULL)
|
|
{
|
|
fclose(scriptdata->scriptrecord);
|
|
logevent(NULL, "script recording, file already exists");
|
|
script_fail("script recording, file already exists");
|
|
return FALSE;
|
|
}
|
|
|
|
scriptdata->cond_charR = scriptdata->cond_char; /* copy of current cond_char for record */
|
|
scriptdata->scriptrecord = f_open(script_filename, "wb", FALSE);
|
|
if(scriptdata->scriptrecord==NULL)
|
|
{
|
|
logevent(NULL, "unable to open file for script recording");
|
|
script_fail("unable to open file for script recording");
|
|
return FALSE;
|
|
}
|
|
|
|
logevent(NULL, "script recording started");
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
void script_record_stop(ScriptData * scriptdata)
|
|
{
|
|
if(scriptdata->scriptrecord!=NULL)
|
|
{
|
|
fclose(scriptdata->scriptrecord);
|
|
scriptdata->scriptrecord = NULL;
|
|
logevent(NULL, "script recording stopped");
|
|
}
|
|
};
|
|
|
|
BOOL script_record_line(ScriptData * scriptdata, int remote)
|
|
{
|
|
int fail = FALSE;
|
|
|
|
if(scriptdata->scriptrecord == NULL)
|
|
return FALSE;
|
|
|
|
if(remote)
|
|
{
|
|
fputc(scriptdata->cond_charR, scriptdata->scriptrecord);
|
|
fail = (fwrite(&(scriptdata->remotedata[script_cond_size]), 1, (scriptdata->remotedata_c - script_cond_size), scriptdata->scriptrecord)!=(scriptdata->remotedata_c - script_cond_size));
|
|
}
|
|
else
|
|
{
|
|
fail = (fwrite(scriptdata->localdata, 1, scriptdata->localdata_c, scriptdata->scriptrecord)!=scriptdata->localdata_c);
|
|
}
|
|
if(fail)
|
|
{
|
|
logevent(NULL, "script recording, file write error");
|
|
script_record_stop(scriptdata);
|
|
script_fail("script recording, error writing file");
|
|
return FALSE;
|
|
}
|
|
|
|
fputc('\n', scriptdata->scriptrecord);
|
|
fflush(scriptdata->scriptrecord);
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/* end of file */
|