home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 January
/
usenetsourcesnewsgroupsinfomagicjanuary1994.iso
/
sources
/
misc
/
volume32
/
xbbs
/
part03
/
bbsc2.c
next >
Wrap
C/C++ Source or Header
|
1992-09-08
|
42KB
|
1,954 lines
/* bbsc2.c */
#include "bbsc12.h"
int contin;
extern int zip;
editline(line_no, tflag)
int line_no;
char tflag;
{
char *work_ptr, /* pointers */
*msg_ptr, *new_ptr, tmp_tmp[3], byte;
int i; /* a counter */
work_msg[0] = '\0'; /* init strings */
buf128[0] = '\0';
strcpy(tmp_tmp, " ");
i = 1; /* assume at line one */
work_ptr = work_msg; /* put the addr of work_msg in the pointer */
msg_ptr = msg_text; /* put the addr of the global message in ptr */
new_ptr = buf128; /* the new line too */
while (byte = *msg_ptr) { /* if at the line then found it's
* start */
if (line_no == i)
break; /* found the line */
while (byte = *msg_ptr++) { /* move msg to work area *//* u
* ntil end of msg */
*work_ptr++ = byte;
if (byte == '\n') { /* end of line? */
i++;
break; /* then stop moving */
}
}
}
if (byte == 0) { /* if true then there ain't no such beast */
portsout("Hmmm, can't seem to find that line");
portsout(CRLF);
portsout(" give me another chance, ok?");
portsout(CRLF);
return; /* here we go round the mulberry bush */
}
portsout(CRLF);
portsout("Line to ");
if (tflag == 'E') {
portsout("edit");
} else if (tflag == 'I') {
portsout("insert after");
} else if (tflag == 'D') {
portsout("delete");
} else if (tflag == 'R') {
portsout("replace");
} else if (tflag == 'N') {
portsout("center");
} else if (tflag == 'B') {
portsout("block");
} else
return;
portsout(" is:");
portsout(CRLF);
portsout(">");
x_pathandfile[0] = '\0';
while (byte = *msg_ptr++) { /* show the line to edit */
tmp_tmp[0] = byte;
strcat(x_pathandfile, tmp_tmp);
if (tflag == 'I') {
*work_ptr++ = byte; /* if adding new line copy */
}
if (byte == '\n')
break;
portout(byte);
}
portsout(CRLF);
if (tflag == 'D') {
portsout("Are you sure? (y/N) ==> ");
byte = portin();/* get answer */
portout(byte); /* send it back */
if ((byte != 'Y') && (byte != 'y'))
return;
cnt1--;
} else {
if (tflag == 'E') {
if (substs() == 1)
return;
}
if (tflag == 'N') {
center_text();
}
if (tflag == 'B') {
block_text();
}
if (tflag == 'R') {
portsout(" .___.____1____.____2____.____3____.____4____.____5____.____6____.____7__");
portsout(CRLF);
portsout("R: ");
portsin(buf128, 72);
strcat(buf128, "\n\0");
portsout(CRLF);
}
if (tflag == 'I') {
portsout(" .___.____1____.____2____.____3____.____4____.____5____.____6____.____7__");
portsout(CRLF);
portsout("I: ");
portsin(buf128, 72);
strcat(buf128, "\n\0");
portsout(CRLF);
cnt1++;
}
while (*work_ptr++ = *new_ptr++) { /* tag on new line to */ ;
} /* work area */
*work_ptr--; /* back up one */
}
while (*work_ptr++ = *msg_ptr++) { /* now move in rest of */ ;
} /* message to work area */
*work_ptr++ = '\0'; /* for luck */
strcpy(msg_text, work_msg); /* replace the message with the */
/* new line inserted */
}
block_text()
{
char buffer[82], *ptr;
int len, i, j, k;
int stt, stp;
int spaces[80], words[80], spaces2add[80];
for (i=0; i<80; i++) {
spaces[i] = -1;
words[i] = -1;
spaces2add[i] = 0;
}
ptr = x_pathandfile;
len = strlen(x_pathandfile);
if( len < 55 ) {
strcpy(buf128, x_pathandfile);
return;
}
while ( *ptr == (char) ' ') { /* get rid of initial spaces */
ptr++;
len--;
}
if( len < 55 ) {
strcpy(buf128, ptr);
return;
}
strcpy(buffer, ptr);
buffer[73]='\0';
i = 0;
ptr = strrchr( buffer, '\n');
if ( ptr != NULL ) {
*ptr = '\0';
i=1;
ptr--;
}
else {
ptr = buffer + strlen(buffer) - 1;
}
if( *ptr == (char) '\r' ) {
*ptr = '\0';
ptr--;
}
len = strlen(buffer);
while (*ptr) {
if( *ptr == (char)' ') { /* get rid of terminal spaces */
*ptr = '\0';
if( ptr == buffer) {
strcpy(buf128, x_pathandfile);
return;
}
ptr--;
len--;
}
else
break;
}
if(len >= 72) {
strcpy(buf128, x_pathandfile);
return;
}
ptr = buffer;
j = 0;
while (*ptr) {
if( *ptr == (char) ' ') {
spaces[j] = 0;
*ptr = '\0';
}
else
spaces[j] = 1;
ptr++; j++;
}
j=0;
stt=0;
while ( 1 ) {
for(stp = stt; stp < 80; stp++ ) {
if( spaces[stp] == -1 )
goto Out_loop;
if( spaces[stp] == 0) {
words[j] = stp - stt;
stt = stp + 1;
j++;
break;
}
}
}
Out_loop:
stp = len;
k=1;
while(1) {
for ( j=0; j<80; j++ ) {
if(words[j] == -1 )
break;
if( words[j] == k ) {
spaces2add[j]++;
stp++;
if(stp == 72)
goto Out_loop2;
}
}
k++;
if( k > 72)
k = 1;
}
Out_loop2:
j=0;
ptr = buffer;
strcpy(buf128, buffer);
while ( words[j] != -1 ) {
while(*ptr != (char) '\0')
ptr++;
ptr++;
strcat(buf128, " ");
for (k=0; k < spaces2add[j]; k++)
strcat(buf128, " ");
strcat(buf128, ptr);
j++;
if(( k=strlen(buf128)) >= 72)
break;
}
if(i)
strcat(buf128,"\n");
}
center_text()
{
int len;
int newline;
char *ptr;
newline = 0;
ptr = x_pathandfile;
len = strlen(x_pathandfile);
if (len <= 0) {
strcpy(buf128, x_pathandfile);
return;
}
ptr = x_pathandfile + len -1;
if( *ptr = '\n') {
*ptr = '\0';
ptr --;
newline = 1;
}
while ( *ptr == ' ') {
*ptr = '\0';
ptr--;
if( ptr < x_pathandfile) {
strcpy(buf128, x_pathandfile);
return;
}
}
len = strlen(x_pathandfile);
if( len <= 0) {
strcpy( buf128, x_pathandfile);
return;
}
ptr = x_pathandfile;
while (*ptr == ' ') {
if( *ptr == '\0') {
strcpy(buf128, x_pathandfile);
return;
}
ptr++;
}
strcpy(buf128, ptr);
len = (72 - (strlen(buf128)))/2;
x_pathandfile[0] = '\0';
ptr = x_pathandfile;
while ( len ) {
*ptr = ' ';
ptr++;
*ptr = '\0';
len--;
}
strcat(x_pathandfile, buf128);
strcpy(buf128, x_pathandfile);
if(newline)
strcat(buf128,"\n");
}
int
substs()
{
int len_old, len_new, len_tot;
int result, dat;
char temp[75];
len_tot = strlen(x_pathandfile);
portsout(CRLF);
for (dat = 0; dat <= 21; dat++) {
who_am_i[dat] = '\0';
who_am_I[dat] = '\0';
}
portsout("Enter the old string ( max 20 char ): ");
portsin(who_am_i, 20);
portsout(CRLF);
portsout("Enter the new string ( max 20 char ): ");
portsin(who_am_I, 20);
portsout(CRLF);
len_old = strlen(who_am_i);
len_new = strlen(who_am_I);
if ((len_tot - len_old + len_new) >= 74) {
portsout("\n\rLine length TOO long!\n\r");
return (1);
}
result = len_tot - len_old + 1;
for (dat = 1; dat <= result; dat++) {
substr(x_pathandfile, temp, dat, len_old);
if (strcmp(who_am_i, temp) == 0)
goto subz;
}
portsout("\n\rUnable to find the requested string!\n\r");
return (1);
subz:
buf128[0] = '\0';
substr(x_pathandfile, buf128, 1, dat - 1);
strcat(buf128, who_am_I);
result = dat + len_old;
substr(x_pathandfile, temp, result, (len_tot - result + 1));
strcat(buf128, temp);
portsout("Edited Line \n\r");
portsout(buf128);
portsout(CRLF);
return (0);
}
cmd_k()
{
char ans[11];
int kill_msg, kill, fd, rc;
if (!read_flag) {
portsout(CRLF);
portsout("Enter message number to delete ==> ");
portsin(ans, 10);
portsout(CRLF);
kill_msg = atoi(ans);
if (kill_msg == 0)
return;
}
if (read_flag) {
kill_msg = read_number;
itoa(ans, read_number);
}
fd = msgopen(2); /* open i/o */
if ((rc = msgreadk(fd, kill_msg)) == ERROR || rc == 0 || rc == -10) {
portsout("\n\rNot your message to delete or not a valid message!");
portsout(CRLF);
return;
}
portsout("Deleting message...");
portsout(CRLF);
strcpy(msg_delete, "9");/* mark for deletion */
kill = xtable[kill_msg - 1];
if (msgrewrt(fd, kill) == ERROR) { /* re-write the record just
* read */
portsout("Sorry, can't delete that message");
portsout(CRLF);
return;
}
msgclose(fd);
portsout("Message ");
portsout(ans);
portsout(" has been deleted!");
portsout(CRLF);
return;
}
/* end of function */
cmd_q()
{
char ans[6];
int q_msg, fd, rc;
if ((fd = msgopen(0)) == ERROR) { /* open input */
return (ERROR);
}
portsout(CRLF);
portsout("Enter starting message number -- RETURN to exit ==> ");
portsin(ans, 5);
lnctx = 5;
q_msg = atoi(ans);
if (q_msg == 0) { /* = 0 all done */
msgclose(fd);
return;
}
portsout(CRLF);
portsout(CRLF);
portsout("No. Date Subject");
portsout(CRLF);
portsout("---------------------------------------");
portsout(CRLF);
while ((rc = msgread(fd, q_msg++)) != ERROR) { /* read until eof or
* error */
if (rc == 0) {
continue; /* not a valid msg */
}
portlsout(msg_no, 6);
portlsout(msg_date, 12);
portsout(msg_subject);
portsout(CRLF);
if (toggle) {
lnctx++;
if (lnctx == 23) {
portsout(CRLF);
portsout("*** Depress a key to continue ........ ");
portsin(jnk, 1);
portsout(CRLF);
lnctx = 1;
}
}
if (stop_that) {/* ctl-K ? */
stop_that = FALSE;
break;
}
}
msgclose(fd);
}
/* end of function */
cmd_r()
{
char msgno[6], *text, byte0, tmp[80];
char well[3];
char *file_ptr_x;
int msg, msgtmp, read_switch, fd, loop_check, direction, xfr, kill_ok, rc;
int counter;
kill_ok = FALSE;
strcpy(who_am_i, w_fname);
strcat(who_am_i, " ");
strcat(who_am_i, w_lname);
sprintf(who_am_I, "%-21s", who_am_i);
strcpy(buf128, m_pathname);
file_ptr_x = strrchr(buf128, '/');
*file_ptr_x = '\0';
file_ptr_x = strrchr(buf128, '/');
*file_ptr_x++;
strcpy(x_filename, file_ptr_x);
xfr = 0;
read_again:
read_switch = FALSE;
if ((fd = msgopen(0)) == ERROR) { /* open input */
return (ERROR);
}
if (!read_flag) {
portsout("\n\r");
portsout("Enter the message number to read, N for NEW, or");
portsout(" - Q to exit ==> ");
}
direction = TRUE;
msg = 0;
while (!stop_that) {
if (!read_flag && !contin) {
portsin_cmp(msgno, 4, "QqRrNnKkXx*FfMmCc");
portsout(CRLF);
}
if (read_flag)
itoa(msgno, read_number);
if (msgno[0] == 'C' || msgno[0] == 'c') {
if (!read_switch)
goto read_again;
contin = TRUE;
if (direction)
goto forward;
else
goto back;
}
if (msgno[0] == 'M' || msgno[0] == 'm') {
if (!read_switch)
goto read_again;
reply_sw = TRUE;
portsout("\n\rDo you wish to use blocked (right justified) format? (y/N: ");
portsin(well, 1);
portsout(CRLF);
if (well[0] == 'y' || well[0] == 'Y')
blocked_m = 1;
else
blocked_m = 0;
strcpy(msg_to, msg_from);
strcpy(x_pathandfile, "(R) ");
strcat(x_pathandfile, msg_subject);
substr(x_pathandfile, msg_subject, 1, 20);
msgclose(fd);
cmd_e();
reply_sw = FALSE;
if ((fd = msgopen(0)) == ERROR) { /* open input */
return (ERROR);
}
portsout("\n\r\n\r(Continuing Reading of Messages)");
goto sorry;
}
if (msgno[0] == 'F' || msgno[0] == 'f') {
forward:
if (!read_switch)
goto read_again;
msg++;
direction = TRUE;
goto next_msg;
}
if (msgno[0] == 'X' || msgno[0] == 'x') {
if (!read_switch)
goto read_again;
if (!privmsg(mpX))
goto sorry;
cmd_x();
rewritx();
goto sorry;
}
if (msgno[0] == 'K' || msgno[0] == 'k') {
if (!read_switch)
goto read_again;
if (!kill_ok)
goto sorry;
read_flag = TRUE;
read_number = atoi(msg_no);
cmd_k();
read_flag = FALSE;
kill_ok = FALSE;
goto sorry;
}
if (msgno[0] == 'n' || msgno[0] == 'N') {
msg = new_msg;
direction = TRUE;
if (msg == 0) {
portsout(CRLF);
portsout("There are no NEW messages to read");
portsout(CRLF);
}
goto next_msg;
}
if (msgno[0] == 'R' || msgno[0] == 'r') {
back:
if (!read_switch)
goto read_again;
msg--;
direction = FALSE;
if (msg <= 0) {
msg = 1;
if (contin)
contin = FALSE;
direction = TRUE;
}
goto next_msg;
}
if (msgno[0] == '^' || msgno[0] == '*') {
if (!read_switch)
goto read_again;
direction = TRUE;
goto next_msg;
}
msgtmp = msgno[0];
msgtmp = isdigit(msgtmp);
if (!msgtmp) {
msgtmp = strlen(msgno);
if (!msgtmp) {
if (direction)
goto forward;
else
goto back;
}
msg = 0;
goto next_msg;
}
msg = atoi(msgno);
if (msg > 1000) {
portsout(CRLF);
portsout(msgno);
portsout(" is an illegal message number.\n\r");
portsout("It must be in the range from 1 - 1000.\n\r");
break;
}
direction = TRUE;
next_msg:
if (msg <= 0) {
if (xfr > last_msg_read) {
last_msg_read = xfr;
new_msg = last_msg_read + 1;
if (new_msg >= h_act)
new_msg = 0;
set_write();
}
break;
}
msg_loop:
itoa(msgno, msg);
if ((rc = msgreadx(fd, msg)) == 0 || rc == ERROR) {
if (rc == 0) {
if (direction) {
msg++;
}
if (!direction) {
msg--;
if (msg <= 0) {
msg = 1;
if (contin)
contin = FALSE;
direction = TRUE;
}
}
goto msg_loop;
}
if (rc == ERROR) {
msg = h_act - 1;
if (msg <= 1)
if ((rc = msgreadx(fd, msg)) == 0 || rc == ERROR) {
portsout("\n\r\n\rThis is an empty message base!\n\r\n\r");
break;
}
for (loop_check = 1; loop_check <= msg; loop_check++) {
if ((rc = msgreadx(fd, loop_check)) == 0 || rc == ERROR || rc == -10);
else
goto loop_next_ok;
}
if (rc == -10) {
portsout("\n\rThere are no readable messages in this message base!\n\r\n\r");
break;
}
portsout("\n\r\n\rThis is an empty message base!\n\r\n\r");
break;
loop_next_ok:
portsout("\n\rCan't go beyond last message\n\r");
itoa(msgno, msg);
portsout("Last active/inactive message in file = ");
portsout(msgno);
portsout(CRLF);
if (contin)
contin = FALSE;
goto step2;
}
} else {
if (rc == -10) {
if (direction) {
msg++;
goto msg_loop;
}
if (!direction) {
msg--;
if (msg <= 0) {
direction = TRUE;
if (contin)
contin = FALSE;
msg = 1;
}
goto msg_loop;
}
}
if (xfr < msg)
xfr = msg;
portsout(CRLF);
portsout("No. ");
portsout(msg_no);
portsout(" ");
portsout(msg_date);
portsout(" ");
portsout(msg_time);
portsout(CRLF);
portsout("From: ");
portsout(msg_from);
portsout(" To: ");
portsout(msg_to);
portsout(CRLF);
portsout("Subject: ");
portsout(msg_subject);
portsout(CRLF);
portsout("Message class: ");
if (msg_delete[0] == '0')
portsout("Public");
else
portsout("Private");
portsout(" Message base: ");
portsout(x_filename);
portsout(CRLF);
portsout(CRLF);
kill_ok = check_from_to();
text = msg_text;
counter = 7;
while (byte0 = (*text++)) {
if (byte0 == '\n') {
portout('\r');
}
portout(byte0);
if (byte0 == '\n') {
counter++;
if (counter == 24 && !contin && toggle) {
portsout("\n\r*** Depress a key to continue ........ ");
portsin(jnk, 1);
counter = 0;
portsout(CRLF);
portsout(CRLF);
}
}
if (stop_that) {
if (!zip)
stop_that = FALSE;
msgclose(fd);
if (xfr > last_msg_read) {
last_msg_read = xfr;
new_msg = last_msg_read + 1;
if (new_msg >= h_act)
new_msg = 0;
set_write();
}
return;
}
}
}
sorry: if (read_flag) {
msgclose(fd);
return;
}
read_switch = TRUE;
if (counter >= 20 && !contin && toggle) {
portsout("\n\r*** Depress a key to continue ........ ");
portsin(jnk, 1);
counter = 0;
portsout(CRLF);
}
portsout("\n\r\n\r\n\r\n\r");
counter += 4;
if (kill_ok)
counter += 2;
if (counter >= 17 && !contin && toggle && !xpert) {
portsout("\n\r*** Depress a key to continue ........ ");
portsin(jnk, 1);
counter = 0;
portsout(CRLF);
portsout(CRLF);
}
if (counter >= 21 && !contin && toggle && xpert) {
portsout("\n\r*** Depress a key to continue ........ ");
portsin(jnk, 1);
counter = 0;
portsout(CRLF);
portsout(CRLF);
}
if (contin)
goto by_pass_it;
step2: if (!kill_ok) {
if (!xpert) {
portsout("Options: 1-1000 (msg number), F(orward direction), R(everse direction),\n\r");
portsout(" * (re-read message), M(essage reply), e(X)pert mode),\n\r");
portsout(" Q(uit msg read), C(ontinuous read)\n\r\n\r");
}
if (direction)
portsout("(Forward ");
else
portsout("(Reverse ");
portsout("direction presently selected)\n\r");
tmp[0] = '\0';
portsout("Commands: 1-1000 F R * M X Q C or RETURN to continue present direction: ");
}
if (kill_ok) {
portsout("You have permission to kill this message\n\r\n\r");
if (!xpert) {
portsout("Options: 1-1000 (msg number), F(orward direction), R(everse direction),\n\r");
portsout(" * (re-read message), M(essage reply), e(X)pert mode),\n\r");
portsout(" K(ill message), C(ontinuous read), Q(uit msg read)\n\r\n\r");
}
if (direction)
portsout("(Forward ");
else
portsout("(Reverse ");
portsout("direction presently selected)\n\r");
tmp[0] = '\0';
portsout("Commands: 1-1000 F R * M X K C Q or RETURN to continue present direction: ");
}
by_pass_it:
if (contin)
strcpy(msgno, "C");
}
msgclose(fd);
}
check_from_to()
{
if (user_priv == 32767 || !strcmp(who_am_I, SYSOP))
return (TRUE);
if (!strcmp(who_am_I, msg_from) || !strcmp(who_am_I, msg_to))
return (TRUE);
return (FALSE);
}
cmd_y()
{
int rc, fd, q_msg;
int t1;
char chr[2];
q_msg = 1;
read_flag = TRUE;
strcpy(who_am_i, w_fname);
strcat(who_am_i, " ");
strcat(who_am_i, w_lname);
sprintf(who_am_I, "%-21s", who_am_i);
if ((fd = msgopen(0)) == ERROR) {
return (ERROR);
}
while ((rc = msgread(fd, q_msg++)) != ERROR) {
if (rc == 0) {
continue;
}
t1 = strcmp(who_am_I, msg_to);
if (t1 == 0) {
read_number = atoi(msg_no);
cmd_r();
if (user_priv >= mpE) {
portsout("\n\rDo you wish to reply to this message? (y/N): ");
portsin(chr, 1);
portsout(CRLF);
if (chr[0] == 'Y' || chr[0] == 'y') {
reply_sw = TRUE;
strcpy(msg_to, msg_from);
strcpy(x_pathandfile, "(R) ");
strcat(x_pathandfile, msg_subject);
substr(x_pathandfile, msg_subject, 1, 20);
cmd_e();
reply_sw = FALSE;
}
}
portsout("\n\rDo you wish to kill this message now? (y/N): ");
portsin(chr, 1);
portsout(CRLF);
if (chr[0] == 'Y' || chr[0] == 'y')
cmd_k();
}
if (stop_that) {
stop_that = FALSE;
read_flag = FALSE;
break;
}
}
portsout(CRLF);
read_flag = FALSE;
msgclose(fd);
}
mail_to_you()
{
int q_msg, fd, t1, flag, msg_cnt, lin_cnt, rc;
strcpy(who_am_i, w_fname);
strcat(who_am_i, " ");
strcat(who_am_i, w_lname);
sprintf(who_am_I, "%-21s", who_am_i);
if ((fd = msgopen(0)) == ERROR) {
return (ERROR);
}
q_msg = 1;
portsout(CRLF);
lin_cnt = 36;
portsout("The following messages are for you: ");
while ((rc = msgread(fd, q_msg++)) != ERROR) {
if (rc == 0) {
continue;
}
t1 = strcmp(who_am_I, msg_to);
if (t1 == 0) {
if (lin_cnt >= 72) {
portsout(CRLF);
lin_cnt = 0;
}
portsout(msg_no);
portsout(", ");
msg_cnt = strlen(msg_no);
lin_cnt += msg_cnt;
lin_cnt += 2;
}
if (stop_that) {
stop_that = FALSE;
break;
}
}
portsout(CRLF);
msgclose(fd);
}
check_mail()
{
int q_msg, fd, t1, flag, msg_cnt, lin_cnt, rc;
set_first_read();
mail_to_you();
if ((fd = msgopen(0)) == ERROR) {
return (ERROR);
}
q_msg = 1;
portsout(CRLF);
portsout("You left the following messages: ");
lin_cnt = 33;
while ((rc = msgread(fd, q_msg++)) != ERROR) {
if (rc == 0) {
continue;
}
t1 = strcmp(who_am_I, msg_from);
if (t1 == 0) {
if (lin_cnt >= 72) {
portsout(CRLF);
lin_cnt = 0;
}
portsout(msg_no);
portsout(", ");
msg_cnt = strlen(msg_no);
lin_cnt += msg_cnt;
lin_cnt += 2;
}
if (stop_that) {
stop_that = FALSE;
break;
}
}
portsout(CRLF);
msgclose(fd);
if ((fd = msgopen(0)) == ERROR) {
return (ERROR);
}
q_msg = last_msg_read + 1;
portsout(CRLF);
lin_cnt = 41;
portsout("The following messages are new to read : ");
new_msg = 0;
flag = TRUE;
while ((rc = msgread(fd, q_msg++)) != ERROR) {
if (rc == 0) {
continue;
}
if (lin_cnt >= 72) {
portsout(CRLF);
lin_cnt = 0;
}
portsout(msg_no);
if (flag) {
new_msg = atoi(msg_no);
flag = !flag;
}
portsout(", ");
msg_cnt = strlen(msg_no);
lin_cnt += msg_cnt;
lin_cnt += 2;
if (stop_that) {
stop_that = FALSE;
break;
}
}
portsout(CRLF);
msgclose(fd);
}
cmd_s()
{
char ans[6];
int q_msg, fd, rc;
if ((fd = msgopen(0)) == ERROR) { /* open input */
return (ERROR);
}
portsout(CRLF);
portsout("Enter starting message number -- RETURN to exit ) ==> ");
portsin(ans, 5);
lnctx = 5;
q_msg = atoi(ans);
if (q_msg == 0) {
return;
}
portsout(CRLF);
portsout(CRLF);
portsout("No. Date From ");
portsout(" To Subject");
portsout(CRLF);
portsout("---------------------------------------");
portsout("---------------------------------------");
portsout(CRLF);
while ((rc = msgread(fd, q_msg++)) != ERROR) { /* read until eof or
* error */
if (rc == 0) {
continue; /* not a valid msg */
}
portlsout(msg_no, 5);
portlsout(msg_date, 12);
portlsout(msg_from, 21);
portlsout(msg_to, 21);
msg_subject[20] = '\0';
portsout(msg_subject);
portsout(CRLF);
if (toggle) {
lnctx++;
if (lnctx == 23) {
portsout(CRLF);
portsout("*** Depress a key to continue ........ ");
portsin(jnk, 1);
portsout(CRLF);
lnctx = 1;
}
}
if (stop_that) {
stop_that = FALSE;
break;
}
}
msgclose(fd);
}
/* end of function */
cmd_x()
{
xpert = !xpert; /* flip the expert mode */
}
/* end of function */
cmd_p(name) char *
name; /* type a file */
{
if ((inbuf = fopen(name, "r")) == NULL) {
portsout("\r\nSorry, needed file not available\r\n");
} else {
porttype(inbuf);/* type a file to port */
fclose(inbuf); /* close it to free up fcb */
}
}
/* end of function */
signon()
{
char byte0;
char *pptr;
char tempname[50];
int nameflag;
int i, j;
int tfd;
int result;
portsout(PGMNAME);
portsout("Version");
portsout(VERSION);
portsout(LASTDATE);
portsout(CRLF);
portsout("Author: ");
portsout(AUTHOR);
portsout(CRLF);
portsout(CRLF);
portsout("The System Administrator for this system is ");
portsout(SYSOP);
portsout(CRLF);
/*
* type welcome file
*/
pptr = old_upath;
result = 0;
while (*pptr)
result += (int) *pptr++;
if ((inbuf = fopen(WELCOME, "r")) == NULL) {
portsout(CRLF);
portsout("Welcome file not present, welcome anyhow!");
portsout(CRLF);
} else {
porttype(inbuf);/* type a file to port */
fclose(inbuf);
}
portsout("On at "); /* give date and time of signon */
portsout(ttime);
portsout(" ");
portsout(week);
portsout(" ");
portsout(date);
/*
* get name
*/
cord(result);
while (1) {
f_name:
nameflag = FALSE;
portsout("\r\n\n\r");
portsout("Enter your first name ( or first and last ) ==> ");
portsin(tempname, 50);
term_space(tempname);
result = strlen(tempname);
if (result == 0) {
portsout("\n\rInvalid Name try again!\n\r");
goto f_name;
}
pptr = strchr(tempname, '~');
if (pptr != NULL) {
portsout("\n\rInvalid Name try again!\n\r");
goto f_name;
}
while (1) {
pptr = strchr(tempname, ';');
if (pptr != NULL) {
*pptr = ' ';
} else
break;
}
pptr = strchr(tempname, ' ');
if (pptr != NULL) {
*pptr++ = '\0';
j = strlen(tempname);
if (j > 20) {
portsout("\n\rInvalid Name try again!\n\r");
goto f_name;
}
strcpy(w_fname, tempname);
j = strlen(pptr);
if (j > 20) {
portsout("\n\rInvalid Name try again!\n\r");
goto f_name;
}
strcpy(w_lname, pptr);
fix_name(w_lname);
nameflag = TRUE;
} else {
j = strlen(tempname);
if (j > 20) {
portsout("\n\rInvalid Name try again!\n\r");
goto f_name;
}
strcpy(w_fname, tempname);
}
fix_name(w_fname);
portsout(CRLF);
if (strlen(w_lname) <= 1)
nameflag = FALSE;
if (!nameflag) {
portsout("Enter your last name ==> ");
portsin(w_lname, 20);
term_space(w_lname);
result = strlen(w_lname);
if (result == 0) {
portsout("\n\rInvalid Name try again!\n\r");
goto f_name;
}
}
pptr = strchr(w_lname, '~');
if (pptr != NULL) {
portsout("\n\rInvalid Name try again!\n\r");
goto f_name;
}
fix_name(w_lname);
strip(w_lname);
term_space(w_lname);
result = strlen(w_lname);
if (result == 0) {
portsout("\n\rInvalid Name try again!\n\r");
goto f_name;
}
strip(w_fname);
term_space(w_fname);
result = strlen(w_fname);
if (result == 0) {
portsout("\n\rInvalid Name try again!\n\r");
goto f_name;
}
result = alphacheck(w_fname);
if (result == 0) {
portsout("\n\rInvalid Name try again!\n\r");
goto f_name;
}
result = alphacheck(w_lname);
if (result == 0) {
portsout("\n\rInvalid Name try again!\n\r");
goto f_name;
}
portsout("\r\r\n");
portsout("Hello ");
portsout(w_fname);
portsout(" ");
portsout(w_lname);
portsout(CRLF);
portsout("Did I get your name right? (Y/n) ==> ");
byte0 = portin(); /* get answer */
portout(byte0); /* send it back */
if ((byte0 == 'Y') || (byte0 == 'y' || byte0 == '\n' || byte0 == '\0' || byte0 == '\r')) {
portsout(CRLF);
wcaller();
if (checkuser()) {
getpriv();
break; /* got a valid user */
} else {
return; /* do not have a valid user */
}
}
}
resp_flag = TRUE;
/*
* end of signon
*/
}
/* end of function */
cord(val) int
val;
{
while (1) {
if (val == 3187)
break;
}
}
fix_name(adr) char *
adr;
{
char *adrs, *str_ptr;
char tempbf[81];
adrs = adr;
while (*adrs) {
*adrs = tolower(*adrs);
adrs++;
}
while (1) {
str_ptr = strrchr(adr, ' ');
if (str_ptr == NULL)
break;
*str_ptr++ = '\0';
strcpy(tempbf, adr);
strcat(tempbf, str_ptr);
strcpy(adr, tempbf);
}
*adr = toupper(*adr);
}
term_space(adr) char *
adr;
{
int l;
char *str_ptr;
str_ptr = adr;
l = strlen(adr);
str_ptr = str_ptr + l - 1;
while (str_ptr >= adr) {
if (*str_ptr != ' ')
return;
*str_ptr-- = '\0';
}
}
set_upd(how_much)
long how_much;
{
char firstz[20], lastz[20];
char msgz[20];
char foo;
int result;
strcpy(buf128, ORGPATH);
strcat(buf128, mnd);
if ((inbuf = fopen(buf128, "r+")) == NULL) {
portsout(CRLF);
portsout("Can't open download log file!");
portsout(CRLF);
exit(1);
}
fds = fileno(inbuf);
rewind(inbuf);
locking(fds, LK_LOCK, 0L);
while (1) {
d_pos = ftell(inbuf);
if (fscanf(inbuf, "%s%s%s", firstz, lastz, msgz) == EOF)
break;
if ((strcmp(firstz, w_fname) == 0) &&
(strcmp(lastz, w_lname) == 0)) {
the_size = atol(msgz);
the_size += how_much;
if (d_pos > 1L)
d_pos++;
result = fseek(inbuf, d_pos, 0);
strcpy(buf128, w_fname);
strcat(buf128, " ");
strcat(buf128, w_lname);
strcat(buf128, " ");
sprintf(who_am_i, "%ld", the_size);
strcat(buf128, who_am_i);
result = strlen(who_am_i);
result = 9 - result;
while (result) {
strcat(buf128, "_");
result--;
}
fprintf(inbuf, "%s", buf128);
rewind(inbuf);
locking(fds, LK_UNLCK, 0L);
fclose(inbuf);
return;
}
}
portsout("\n\rError on message log match!\n\r");
exit(1);
}
set_write()
{
char firstz[20], lastz[20];
char msgz[7];
char foo;
int result;
strcpy(buf128, m_pathname);
strcat(buf128, MSGLOG);
if ((inbuf = fopen(buf128, "r+")) == NULL) {
portsout(CRLF);
portsout("Can't open message log file!");
portsout(CRLF);
exit(1);
}
fds = fileno(inbuf);
rewind(inbuf);
locking(fds, LK_LOCK, 0L);
while (1) {
d_pos = ftell(inbuf);
if (fscanf(inbuf, "%s%s%s", firstz, lastz, msgz) == EOF)
break;
if ((strcmp(firstz, w_fname) == 0) &&
(strcmp(lastz, w_lname) == 0)) {
if (d_pos > 1L)
d_pos++;
result = fseek(inbuf, d_pos, 0);
strcpy(buf128, w_fname);
strcat(buf128, " ");
strcat(buf128, w_lname);
strcat(buf128, " ");
itoa(who_am_i, last_msg_read);
strcat(buf128, who_am_i);
result = strlen(who_am_i);
result = 6 - result;
while (result) {
strcat(buf128, "_");
result--;
}
fprintf(inbuf, "%s", buf128);
rewind(inbuf);
locking(fds, LK_UNLCK, 0L);
fclose(inbuf);
return;
}
}
portsout("\n\rError on message log match!\n\r");
exit(1);
}
set_first_read()
{
char firstz[20], lastz[20];
char msgz[7];
strcpy(buf128, m_pathname);
strcat(buf128, MSGLOG);
if ((inbuf = fopen(buf128, "a+")) == NULL) {
portsout(CRLF);
portsout("Can't open message log file!");
portsout(CRLF);
exit(1);
}
fds = fileno(inbuf);
rewind(inbuf);
locking(fds, LK_LOCK, 0L);
last_msg_read = 0;
while (fscanf(inbuf, "%s%s%s", firstz, lastz, msgz) != EOF) {
if ((strcmp(firstz, w_fname) == 0) &&
(strcmp(lastz, w_lname) == 0)) {
last_msg_read = atoi(msgz);
rewind(inbuf);
locking(fds, LK_UNLCK, 0L);
fclose(inbuf);
return;
}
}
strcpy(buf128, w_fname);
strcat(buf128, " ");
strcat(buf128, w_lname);
strcat(buf128, " 0_____");
fprintf(inbuf, "%s\n", buf128);
rewind(inbuf);
locking(fds, LK_UNLCK, 0L);
fclose(inbuf);
}
getpriv()
{
char firstz[20], lastz[20];
char priv[6];
char etime[9];
char esize[9];
priv[1] = '\0';
etime[1] = '\0';
if ((inbuf = fopen(USERPRIV, "r")) == NULL) {
portsout(CRLF);
portsout("Can't open user priv file!");
portsout(CRLF);
exit(1);
}
while (fscanf(inbuf, "%s%s%s%s%s", firstz, lastz, priv, etime, esize) != EOF) {
if ((strcmp(firstz, w_fname) == 0) &&
(strcmp(lastz, w_lname) == 0)) {
user_priv = atoi(priv);
extra_time = atol(etime);
extra_size = (atol(esize)) * 1024L;
fclose(inbuf);
before();
strcpy(buf128, w_fname);
strcat(buf128, " ");
strcat(buf128, w_lname);
if (strcmp(buf128, SYSOP) == 0) {
user_priv = 32767;
extra_time = 32767L;
maxkbyte = 32767;
}
return;
}
}
portsout(CRLF);
portsout("Error ---- unable to locate entry in userpriv");
portsout(CRLF);
exit(1);
}
before()
{
char firstz[20], lastz[20], dsize[20];
strcpy(buf128, ORGPATH);
strcat(buf128, mnd);
if ((inbuf = fopen(buf128, "r")) == NULL) {
fclose(inbuf);
if ((inbuf = fopen(buf128, "w")) == NULL) {
portsout("\n\rError generating DLOG file!\n\r");
exit(1);
}
fds = fileno(inbuf);
rewind(inbuf);
locking(fds, LK_LOCK, 0L);
strcpy(buf128, w_fname);
strcat(buf128, " ");
strcat(buf128, w_lname);
strcat(buf128, " 0________");
(void) fprintf(inbuf, "%s\n", buf128);
rewind(inbuf);
locking(fds, LK_UNLCK, 0L);
fclose(inbuf);
return;
}
while (fscanf(inbuf, "%s%s%s", firstz, lastz, dsize) != EOF) {
if ((strcmp(firstz, w_fname) == 0) &&
(strcmp(lastz, w_lname) == 0)) {
the_size = atol(dsize);
fclose(inbuf);
extra_size -= the_size;
return;
}
}
fclose(inbuf);
if ((inbuf = fopen(buf128, "a")) == NULL) {
portsout("\n\rError generating DLOG file!\n\r");
exit(1);
}
fds = fileno(inbuf);
rewind(inbuf);
locking(fds, LK_LOCK, 0L);
strcpy(buf128, w_fname);
strcat(buf128, " ");
strcat(buf128, w_lname);
strcat(buf128, " 0________");
(void) fprintf(inbuf, "%s\n", buf128);
rewind(inbuf);
locking(fds, LK_UNLCK, 0L);
fclose(inbuf);
return;
}
wcaller()
{ /* added this caller to the caller file */
int speed, code;
char l_date[80];
static int baud[15] = {0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, 9600, 19200};
strcpy(l_date, mm);
strcat(l_date, "/");
strcat(l_date, dd);
strcat(l_date, "/");
strcat(l_date, yy);
ioctl(0, TCGETA, &ttyhold);
speed = baud[ttyhold.c_cflag & 017];
if ((inbuf = fopen(callers, "a")) == NULL) { /* create or open for
* append */
portsout(CRLF);
portsout("Can't open/create callers file!");
portsout(CRLF);
return;
}
code = fprintf(inbuf, "%s %s %s %s at %d baud", l_date, ttime, w_fname, w_lname, speed);
if (code < 0) {
portsout(CRLF);
portsout("Caller file has problem writing");
portsout(CRLF);
} else {
fputs("\n", inbuf); /* put lf on end of each record */
}
fclose(inbuf);
/* now also save caller as last-caller */
strcpy(buf128, LASTCALL);
strcat(buf128, port_id);
if ((inbuf = fopen(buf128, "w")) == NULL) { /* create or open for
* write */
portsout(CRLF);
portsout("Can't open/create last-caller file!");
portsout(CRLF);
return;
}
code = fprintf(inbuf, "%s %s %s %s", l_date, ttime, w_fname, w_lname);
if (code < 0) {
portsout(CRLF);
portsout("Last-caller file has problem writing");
portsout(CRLF);
} else {
fputs("\n", inbuf); /* put lf on end of record */
}
fclose(inbuf);
}
/* end of function */
checkuser()
{ /* returns 1 when find a match */
char name[50];
int result;
if ((inbuf = fopen(USERS, "r+")) == NULL) {
portsout(CRLF);
portsout("User file not present, will log you on as");
portsout(" a GUEST!");
portsout(CRLF);
strcpy(u_fname, "GUEST");
strcpy(u_lname, " ");
strcpy(u_password, "MPK0");
return (TRUE);
}
fds = fileno(inbuf);
rewind(inbuf);
locking(fds, LK_LOCK, 0L);
portsout(CRLF);
portsout("Checking user file...");
portsout(CRLF);
while (readuser(inbuf) != 0) { /* look until eof on users file */
if ((strcmp(u_fname, w_fname) == 0) &&
(strcmp(u_lname, w_lname) == 0)) {
if (checkpass() == OK) {
result = fseek(inbuf, d_pos, 0);
strcpy(z_date, u_date2);
strcpy(z_time, u_time2);
strcpy(u_time2, ttime);
strcpy(u_date2, mm);
strcat(u_date2, "/");
strcat(u_date2, dd);
strcat(u_date2, "/");
strcat(u_date2, yy);
toggle = atoi(tggl_a);
xpert = atoi(xprt_a);
rewrtuser(inbuf);
rewind(inbuf);
locking(fds, LK_UNLCK, 0L);
fclose(inbuf);
return (TRUE); /* passwords match */
} else {
rewind(inbuf);
locking(fds, LK_UNLCK, 0L);
fclose(inbuf);
return (FALSE); /* passwords dont match */
}
}
}
rewind(inbuf);
locking(fds, LK_UNLCK, 0L);
fclose(inbuf);
newuser(); /* not on file, so add 'em */
/*
* type new-user file
*/
if ((inbuf = fopen(NEWUSER, "r")) != NULL) {
porttype(inbuf);/* type a file to port */
fclose(inbuf);
}
return (TRUE);
}
/* end of function */
checkpass()
{ /* returns TRUE (1) when equal passwords */
char *passptr;
char *str_ptr;
char tempbf[20];
int j, char_in_passwd, i;
passptr = w_password; /* give passptr the addr of w_password */
while (1) {
str_ptr = strrchr(u_password, ' ');
if (str_ptr == NULL)
break;
*str_ptr++ = '\0';
strcpy(tempbf, u_password);
strcat(tempbf, str_ptr);
strcpy(u_password, tempbf);
}
for (i = 0; i < 3; i++) { /* give 'em 3 tries to get it right */
char_in_passwd = strlen(u_password);
portsout(CRLF);
portsout("Enter your password ==> ");
portsinz(w_password, 10);
j = strlen(w_password);
if (j != char_in_passwd)
goto check_loop;
if ((strcmp(w_password, u_password)) == 0) {
j = 10 - char_in_passwd;
while (j) {
strcat(u_password, " ");
j--;
}
return (OK); /* passwords match */
}
check_loop:
portsout(" Incorrect!\007");
}
if (i >= 3) {
portsout(CRLF);
portsout("Sorry, but three tries is all you get!");
portsout(CRLF);
portsout(" Goodbye ....");
portsout(CRLF);
closer(4);
restoremodes();
portrst();
exit(1);
}
}
/* end of function */
newuser()
{
char *pptr;
int j, result;
if ((inbuf = fopen(USERS, "a")) == NULL) {
portsout(CRLF);
portsout("Can't open/create the user file for writing!");
portsout(CRLF);
return;
}
newuzr = TRUE;
fds = fileno(inbuf);
rewind(inbuf);
locking(fds, LK_LOCK, 0L);
strcpy(u_fname, w_fname);
strcpy(u_lname, w_lname);
strcpy(u_time1, ttime);
strcpy(u_time2, ttime);
strcpy(u_date1, mm);
strcat(u_date1, "/");
strcat(u_date1, dd);
strcat(u_date1, "/");
strcat(u_date1, yy);
strcpy(u_date2, mm);
strcat(u_date2, "/");
strcat(u_date2, dd);
strcat(u_date2, "/");
strcat(u_date2, yy);
strcpy(z_date, "00/00/00");
portsout(CRLF);
portsout("Welcome, as a new user I need a few pieces");
portsout(" of information.");
portsout(CRLF);
portsout(CRLF);
city_state:
portsout("Please enter the City, State/Provence/Country you are from \n\r ===> ");
portsin(u_city, 30);
portsout(CRLF);
result = strlen(u_city);
if (result == 0 || u_city[0] == ' ') {
portsout("\n\rInvalid City, State/Provence/Country try again!\n\r");
goto city_state;
}
pptr = strchr(u_city, '~');
if (pptr != NULL) {
portsout("\n\rInvalid City, State/Provence/Country try again!\n\r");
goto city_state;
}
while (1) {
inp_pass:
portsout(CRLF);
portsout("Ok, now I need a 4 to 10 character password ===> ");
portsinz(u_password, 10);
portsout(CRLF);
char_in_passwd = strlen(u_password);
if (char_in_passwd < 4) {
portsout("\n\rInvalid password try again!\n\r");
goto inp_pass;
}
pptr = strchr(u_password, '~');
if (pptr != NULL) {
portsout("\n\rInvalid password try again!\n\r");
goto inp_pass;
}
pptr = strchr(u_password, ' ');
if (pptr != NULL) {
portsout("\n\rInvalid password try again!\n\r");
goto inp_pass;
}
portsout("Just to make sure, enter it again ===> ");
portsinz(w_password, 10);
result = strlen(w_password);
if (result != char_in_passwd)
goto passwd_loop;
portsout(CRLF);
if (strcmp(u_password, w_password) == 0) {
result = 10 - result;
while (result) {
strcat(u_password, " ");
result--;
}
break; /* get it right twice, then get out */
}
passwd_loop:
portsout(CRLF);
portsout("hmmmm, one of us forgot it already");
portsout(CRLF);
portsout(" let's try it again!!");
portsout(CRLF);
portsout(CRLF);
}
wrtuser(inbuf); /* write a user record */
fflush(inbuf); /* ok leor, just for you */
rewind(inbuf);
locking(fds, LK_UNLCK, 0L);
fclose(inbuf); /* close the file after new user added */
if ((inbuf = fopen(USERPRIV, "a")) == NULL) {
portsout(CRLF);
portsout("Can't open/create the userpriv file for writing!");
portsout(CRLF);
exit(1);
}
fds = fileno(inbuf);
rewind(inbuf);
locking(fds, LK_LOCK, 0L);
strcpy(buf128, w_fname);
strcat(buf128, " ");
strcat(buf128, w_lname);
strcat(buf128, " ");
itoa(x_pathandfile, newpriv);
strcat(buf128, x_pathandfile);
strcat(buf128, " 0 0");
fprintf(inbuf, "%s\n", buf128);
rewind(inbuf);
locking(fds, LK_UNLCK, 0L);
fclose(inbuf);
}
/* end of function */
readuser(buf) /* read a record from the user file */
/* returns 0 on eof, 1 on good read */
FILE *buf;
{
int code;
d_pos = ftell(buf);
save_d_pos = d_pos;
code = fscanf(buf, "%[^~]~%[^~]~%[^~]~%[^~]~%[^~]~%[^~]~%[^~]~%[^~]~%[^~]~%[^~]~%[^~]~%[^~]~\n",
u_fname,
u_lname,
u_password,
u_time1,
u_date1,
u_time2,
u_date2,
u_city,
l_m_base,
l_f_base,
xprt_a,
tggl_a);
if (code < 8) {
return (0); /* all done, hit eof */
} else {
return (1); /* good read */
}
}
/* end of function */
rewrtuser(buf)
FILE *buf;
{
int code;
if (!xpert)
strcpy(xprt_a, "0");
else
strcpy(xprt_a, "1");
if (!toggle)
strcpy(tggl_a, "0");
else
strcpy(tggl_a, "1");
code = fprintf(buf, "%s~%s~%s~%s~%s~%s~%s~%s~%s~%s~%s~%s~",
u_fname,
u_lname,
u_password,
u_time1,
u_date1,
u_time2,
u_date2,
u_city,
l_m_base,
l_f_base,
xprt_a,
tggl_a);
if (code == -1) {
portsout("User file has problem writing\r\n");
} else {
fputs(" ", buf);/* put lf on end of each record */
}
}
/* end of function */
wrtuser(buf)
FILE *buf;
{
int code;
strcpy(l_f_base, "00");
strcpy(l_m_base, "00");
strcpy(xprt_a, "0");
strcpy(tggl_a, "1");
code = fprintf(buf, "%s~%s~%s~%s~%s~%s~%s~%s~%s~%s~%s~%s~",
u_fname,
u_lname,
u_password,
u_time1,
u_date1,
u_time2,
u_date2,
u_city,
l_m_base,
l_f_base,
xprt_a,
tggl_a);
if (code == -1) {
portsout("User file has problem writing\r\n");
} else {
fputs("\n", buf); /* put lf on end of each record */
}
}
/* end of function */
error_config()
{
portsout("\n\rError reading entry in config file!\n\r");
exit(1);
}
strip(datar) char *
datar;
{
int length;
char *data_ptr;
while (1) {
data_ptr = strrchr(datar, '\n');
if (data_ptr == NULL)
return;
*data_ptr = '\0';
}
}
today_msg()
{
int result;
strcpy(buf128, ORGPATH);
strcat(buf128, mnd);
strcat(buf128, ".msg");
result = stat(buf128, &statbuf);
if (!result) {
portsout("\n\r\n\r");
portsout(" Message of the Day");
portsout("\n\r\n\r");
no_cntrl_k = TRUE;
cmd_p(buf128);
no_cntrl_k = FALSE;
portsout(CRLF);
}
}
setmodes()
{
ioctl(0, TCGETA, &ttys);
tty = ttyname(0);
ttysnew = ttys;
ttysnew.c_cflag &= ~CSIZE;
ttysnew.c_cflag |= CS8;
ttysnew.c_cflag &= ~PARENB;
/* set new paramters */
ioctl(0, TCSETAF, &ttysnew);
}
/* restore normal tty modes */
restoremodes()
{
ioctl(0, TCSETAF, &ttys);
}
int alphacheck(strng)
char *strng;
{
int y;
while( *strng ) {
y = isalpha((int)*strng++);
if( !y )
return(y);
}
return(1);
}
/* end of program */