/* * $Id: close.c,v 1.5 2002/08/23 13:38:14 howardjp Exp $ * * Copyright (c) 1990 * Jan Wolter. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by Jan Wolter * and his contributors. * 4. Neither the name of Jan Wolter nor the names of his contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JAN WOLTER AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL JAN WOLTER OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* PARTY PROGRAM -- ROUTINES TO HANDLE CLOSED CHANNELS -- Jan Wolter */ #ifndef NOCLOSE #include "party.h" #include "opt.h" #include #include extern jmp_buf jenv; extern int inhelp; /* USR_FILE_NAME: Return the name of the user file name associated with the * given channel name. This must be free()ed by someone else eventually. * This will normally contain a list of login id's, listed one per line, of * people who are permitted to join the channel. */ char *usr_file_name(chn) char *chn; { char *usr_file; usr_file= (char *)malloc((mtype)(strlen(opt[OPT_DIR].str)+CHN_LEN+6)); sprintf(usr_file,"%s/%s.usr", opt[OPT_DIR].str, chn); return(usr_file); } /* CHECK_OPEN: This checks to see if we can enter the named channel. Return * codes are: * 0 - channel is closed and we aren't allowed in. * 1 - channel is open. * 2 - channel is closed and we are allowed in. */ int check_open(chn) char *chn; { FILE *fp; char *fn; char buf[BFSZ+1]; /* Open the user list -- if it doesn't exist, anyone can enter */ fp= fopen(fn= usr_file_name(chn),"r"); free(fn); if (fp == NULL) return(1); /* See if I am in the user list */ while (fgets(buf,BFSZ,fp) != NULL) { *firstin(buf," \t\n")= '\0'; if (!strcmp(buf,realname)) { fclose(fp); return(2); } } fclose(fp); return(0); } /* IS_CLOSED: Is the channel the user is in closed? */ int is_closed() { char *fn; int rc; if (channel == NULL) return(0); rc= access(fn= usr_file_name(channel), 0); free(fn); return(!rc); } /* OPEN_CHAN: Open up the current channel */ open_chan() { char *fn; long now= time((long *)0); if (channel == NULL) return; unlink(fn= usr_file_name(channel)); free(fn); /* Closable channels are now left depermitted even when open */ /*fchmod(rst,CHN_MODE);*/ sprintf(txbuf, "---- %s opened this channel (%.12s)\n",name,ctime(&now)+4); append(txbuf,wfd); } /* CLOSE_CHAN: Close the current channel. Create the .usr file and write in a list of * the people already in the channel. */ close_chan() { char *fn; int fd; FILE *fp; long now= time((long *)0); if (channel == NULL) return; fd= open(fn= usr_file_name(channel),O_WRONLY|O_CREAT|O_EXCL,USR_MODE); free(fn); if (fd < 0) { if (errno == EEXIST) printf("channel is already closed\n"); else printf("error - cannot create user file\n"); return; } fp= fdopen(fd,"w"); who_ison(fp,channel); fclose(fp); /* Closable channels are now left depermitted even when open */ /*fchmod(rst,DEP_MODE);*/ sprintf(txbuf, "---- %s closed this channel (%.12s)\n",name,ctime(&now)+4); append(txbuf,wfd); } /* INVITE: invite a user into the the channel. Well, really just permit them * to enter. */ invite(login) char *login; { char *fn; FILE *fp; long now= time((long *)0); if (channel == NULL) return; fp= fopen(fn= usr_file_name(channel),"a"); free(fn); if (fp == NULL) { printf("error - cannot append to user file\n"); return; } fprintf(fp,"%s\n",login); fclose(fp); sprintf(txbuf, "---- %s invited %s to this channel (%.12s)\n",name, login,ctime(&now)+4); append(txbuf,wfd); } /* READYN -- in cooked mode, read in a line. It it starts with Y, return true. */ int read_yn() { int ch; if ((ch= getchar()) != '\n') while (getchar() != '\n') ; return(ch == 'y' || ch == 'Y'); } /* KNOCK -- stuff a knock-knock message into the named channel. */ knock(chn) char *chn; { char bf[BFSZ], *fn; FILE *tmp_wfd; sprintf(bf,"---- %s knocking on the door\n",logname); /* No time on this message so norepeat can be used against knock bombers */ if (access(fn= chn_file_name(chn,0), 0)) fn= chn_file_name(chn,1); if ((tmp_wfd= fopen(fn,"a")) == NULL) return(1); append(bf,tmp_wfd); fclose(tmp_wfd); return(0); } /* ENTER_CLOSED -- Go through the business of passing the doorway of a * channel. If it is closed (a .usr file exists), check if we are in it. * If not, go through the knocking routine. Return codes are: * * 0 - channel is closed and we aren't allowed in. * 1 - channel is open. * 2 - channel is closed and we are allowed in. */ enter_closed(newchannel) char *newchannel; { int was_open; int i= 0; /* If he already has access, let him in */ if (was_open= check_open(newchannel)) return(was_open); /* If the user doesn't want to knock, keep him out */ err("channel %s is a closed channel\n",newchannel); fprintf(stderr,"Would you like to knock on the door? "); if (!read_yn()) return(0); /* Do the knock */ if (!setjmp(jenv)) { inhelp= 1; fprintf(stderr,"Waiting..."); fflush(stderr); knock(newchannel); while (!check_open(newchannel)) { if (i++ >= convert(opt[OPT_KNOCKWAIT].str)) { fprintf(stderr,"there seems to be no answer\n"); /*unknock(newchannel);*/ return(0); } sleep(1); } inhelp= 0; return(2); } else { inhelp= 0; fprintf(stderr,"wait interrupted\n"); return(0); } } #endif /* NOCLOSE */