#include "lonnet.h"
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <linux/un.h>
/*lonnet.c (by Guy Albertelli); based on lonnet.pm by Gerd Kortemeyer*/
char *strsave(char *s)
{
char *p;
if (s==NULL) {return s;}
p=(char*)malloc(strlen(s)+1);
strcpy(p,s);
return (p);
}
int get_apache_config(char* key_word,char* value) {
FILE *fp;
int done=0,failed=0,num,found=0,i,j,result=-1,returnVal;
char testkey[MAX_BUFFER_SIZE],testval[MAX_BUFFER_SIZE],c;
if ((fp=fopen("/etc/httpd/conf/access.conf","r"))==NULL) { return (-1); }
do {
testkey[0]='\0';testval[0]='\0';
num = fscanf(fp,"PerlSetVar %s %s",testkey,testval);
if (num == 2) {
result = strcasecmp(testkey,key_word);
//printf("num: %d:testkey:%s:testval:%s:\n",num,testkey,testval);
}
if (result==0) { done=1; }
if (num==EOF) { failed=1; }
found=0;
if (num!=2) {
while(1) {
c=fgetc(fp);
if (found) {
if (c!='\n') {
ungetc(c,fp);
break;
}
}
if (c=='\n') found=1;
if (((char)c)==((char)EOF)) break;
}
}
} while (!done && !failed);
fclose(fp);
/*strip out the " and \\ */
if (done) {
for(i=0,j=0;i<(strlen(testval)+1);i++) {
value[j]='\0';
if (testval[i] == '\\' && (i < (strlen(testval))) ) {
i++;value[j]=testval[i];j++;
} else if (testval[i] != '\"' ) {
value[j]=testval[i];j++;
}
}
value[j]='\0';
returnVal=j;
}
return returnVal;
}
char *subreply (char* cmd, char* server) {
char *answer,*peerfile, *tempStr, inbuf[MAX_BUFFER_SIZE];
int sockFD, portFD, fromlen, length, totleng;
struct sockaddr_un lonc;
struct sockaddr_un from;
answer=(char*)malloc(MAX_BUFFER_SIZE);
answer[0]='\0';
length=strlen(lonSockDir)+strlen(peerfile)+3;
peerfile=(char*)malloc(length);
sprintf(peerfile,"%s/%s",lonSockDir,server);
if (length > UNIX_PATH_MAX) {
fprintf(stderr,"Path to socket too long:%d\n",length);
sprintf(answer,"Path to socket too long:%d\n",length);
return answer;
}
/*
*/
sockFD = socket (AF_UNIX, SOCK_STREAM, 0);
strcpy(lonc.sun_path, peerfile);
lonc.sun_family = AF_UNIX;
if (bind (sockFD, (struct sockaddr *) &lonc,
strlen(lonc.sun_path) + sizeof(lonc.sun_family))) {
fprintf(stderr,"Bind failed to %s\n",peerfile);
sprintf(answer,"Bind failed to %s\n",peerfile);
return answer;
}
listen (sockFD, 10);
portFD = accept (sockFD, (struct sockaddr *) &from, &fromlen);
write(portFD, cmd, strlen(cmd));
while (1) {
length=read(portFD, inbuf, MAX_BUFFER_SIZE);
totleng = strlen(answer) + strlen(inbuf) + 1;
tempStr = (char*)malloc(totleng);
strcat(tempStr,answer);
strcat(tempStr,inbuf);
free(answer);
answer = tempStr;
if ( length != MAX_BUFFER_SIZE ) { break; }
}
/*
*/
return answer;
}
char * reply (char *cmd,char *server) {
char *answer=NULL;
answer=subreply(cmd,server);
if (strcmp(answer,"con_lost")) {
free(answer);
answer=subreply(cmd,server);
}
return answer;
}
/*
sub subreply {
my ($cmd,$server)=@_;
my $peerfile="$perlvar{'lonSockDir'}/$server";
my $client=IO::Socket::UNIX->new(Peer =>"$peerfile",
Type => SOCK_STREAM,
Timeout => 10)
or return "con_lost";
print $client "$cmd\n";
my $answer=<$client>;
chomp($answer);
if (!$answer) { $answer="con_lost"; }
return $answer;
}
# ------------------------------------------------------ Critical communication
sub critical {
my ($cmd,$server)=@_;
&senddelayed($server);
my $answer=reply($cmd,$server);
if ($answer eq 'con_lost') {
my $pingreply=reply('ping',$server);
&reconlonc("$perlvar{'lonSockDir'}/$server");
my $pongreply=reply('pong',$server);
&logthis("Ping/Pong for $server: $pingreply/$pongreply");
$answer=reply($cmd,$server);
if ($answer eq 'con_lost') {
my $now=time;
my $middlename=$cmd;
$middlename=~s/\W//g;
my $dfilename=
"$perlvar{'lonSockDir'}/delayed/$now.$middlename.$server";
{
my $dfh;
if ($dfh=Apache::File->new(">$dfilename")) {
print $dfh "$server:$cmd\n";
}
}
sleep 2;
my $wcmd='';
{
my $dfh;
if ($dfh=Apache::File->new("$dfilename")) {
$wcmd=<$dfh>;
}
}
chomp($wcmd);
if ($wcmd eq "$server:$cmd") {
&logthis("Connection buffer $dfilename: $cmd");
&logperm("D:$server:$cmd");
return 'con_delayed';
} else {
&logthis("CRITICAL CONNECTION FAILED: $server $cmd");
&logperm("F:$server:$cmd");
return 'con_failed';
}
}
}
return $answer;
}
*/
/* need
- logthis
- logperm
- reconlonc, maybe, don't absolutely need to make critical reconnect
*/
int main() {
char value[MAX_BUFFER_SIZE];
get_apache_config("lonSockDir",value);
lonSockDir=strsave(value);
printf("Found a value of:%s\n",value);
printf("Reply: %s\n",reply("put akey:value","zaphod"));
return 1;
}
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>