home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.muug.mb.ca
/
2014.06.ftp.muug.mb.ca.tar
/
ftp.muug.mb.ca
/
pub
/
src
/
gopher
/
gopher1.01
/
object
/
GDgopherdir.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-06-22
|
5KB
|
310 lines
/*
* This is a crude attempt at doing some object-based programming in C
*/
#include "GDgopherdir.h"
#include <Malloc.h>
#include <string.h>
#include <stdio.h>
extern int DEBUG;
/***********************************************************************
** Stuff for GopherDirObjs
**
***********************************************************************/
GopherDirObj*
GDnew(size)
int size;
{
int i;
GopherDirObj *temp;
temp = (GopherDirObj*) malloc(sizeof(GopherDirObj));
temp->Gophers = (GopherObj **) malloc(size * sizeof(GopherObj*));
for (i = 0; i < size; i++)
temp->Gophers[i] = GSnew();
temp->maxsize = size;
temp->Title = STRnew();
GDinit(temp);
return(temp);
}
void
GDdestroy(gd)
GopherDirObj *gd;
{
int i;
for (i = 0; i < gd->maxsize; i++)
GSdestroy(gd->Gophers[i]);
STRdestroy(gd->Title);
free(gd->Gophers);
free(gd);
}
void
GDinit(gd)
GopherDirObj *gd;
{
int i;
for (i=0; i<gd->maxsize; i++) {
GSinit(GDgetEntry(gd, i));
}
GDsetTop(gd, 0);
STRinit(gd->Title);
}
/*
* Increase the size of the GopherObj pointer array to "size"
*/
void
GDgrow(gd, size)
GopherDirObj *gd;
int size;
{
GopherObj **temp;
int i;
if (size < gd->maxsize)
return; /** Size is smaller than requested **/
temp = (GopherObj **) realloc(gd->Gophers, size*sizeof(GopherObj*));
if (temp == NULL)
fprintf(stderr, "Out of memory!!!\n"), exit(-1);
if (temp != gd->Gophers) {
gd->Gophers = temp;
}
/** Initialize the new GopherObjs. **/
for (i= gd->maxsize; i< size; i++)
gd->Gophers[i] = GSnew();
gd->maxsize = size;
return;
}
extern int DEBUG;
/** This proc adds a GopherObj to a gopherdir. **/
void
GDaddGS(gd, gs)
GopherDirObj *gd;
GopherObj *gs;
{
int n, i;
if (GDgetTop(gd) == gd->maxsize)
GDgrow(gd, gd->maxsize*2);
if (DEBUG)
fprintf(stderr, "Adding %s, Top=%d, Num=%d\n",
GSgetTitle(gs), GDgetTop(gd), GSgetNum(gs));
if ((n = GSgetNum(gs)) == 0) /* if we don't care where it goes */
n=1; /* put it in the first available slot */
if (GSgetType(GDgetEntry(gd, n-1)) != '\0') { /* that slot is in use*/
for (i=1; ; i++) /* find any empty slot */
if (GSgetType(GDgetEntry(gd, i-1)) == '\0')
break; /* got one */
if (i >= GDgetTop(gd)) /* item was past end of list */
GDsetTop(gd, i); /* update end of list */
if (GSgetNum(gs) != 0) { /* if we want that slot */
/* kick out the entry that's in our way */
GScpy(GDgetEntry(gd, i-1), GDgetEntry(gd, n-1));
} else {
n = i; /* don't be a bully */
}
}
GScpy(GDgetEntry(gd, n-1), gs); /* put our entry in place */
if (n >= GDgetTop(gd)) /* item was past end of list */
GDsetTop(gd, n); /* update end of list */
}
/*
* Really weird!!! We need this for qsort, don't know why we can't use
* GScmp...
*/
int
GSmoocmp(gs1, gs2)
GopherObj **gs1, **gs2;
{
if (GSgetTitle(*gs1) == NULL)
return(1);
if (GSgetTitle(*gs2) == NULL)
return(-1);
return(strcmp(GSgetTitle(*gs1), GSgetTitle(*gs2)));
}
/*
* Sorts a gopher directory
*/
void
GDsort(gd)
GopherDirObj *gd;
{
int i;
/*** Find first non-numbered entry ***/
for (i=0; ; i++) {
if (GSgetNum(GDgetEntry(gd, i)) == 0)
break;
}
/*** Everything up to i is already sorted by user-defined ordering ***/
if (GDgetTop(gd) <= i)
/** No more sorting needed ***/
return;
qsort((char *) (&(gd->Gophers[i])), gd->Top-i,
sizeof(GopherObj*),GSmoocmp);
}
void
GDtoNet(gd, sockfd)
GopherDirObj *gd;
int sockfd;
{
int i;
for (i=0; i< GDgetTop(gd); i++) {
GStoNet(GDgetEntry(gd, i), sockfd);
}
}
void
GDtoNetHTML(gd, sockfd)
GopherDirObj *gd;
int sockfd;
{
int i;
writestring(sockfd, "<MENU>\r\n");
for (i=0; i< GDgetTop(gd); i++) {
writestring(sockfd, "<LI>");
GStoNetHTML(GDgetEntry(gd, i), sockfd);
}
writestring(sockfd, "</MENU>");
}
/*
* Fill up a GopherDirObj with GopherObjs, given a gopher directory coming
* from sockfd.
*
* For each GopherObj retrieved, eachitem() is executed.
*
*/
int
GDfromNet(gd, sockfd, eachitem)
GopherDirObj *gd;
int sockfd;
int (*eachitem)();
{
static GopherObj *TempGopher;
static char ZesTmp[1024];
int j, i;
if (TempGopher == NULL)
TempGopher = GSnew();
for (j=0; ; j++) {
if (j == gd->maxsize)
GDgrow(gd, gd->maxsize*2);
ZesTmp[0] = '\0';
GSinit(TempGopher);
i = GSfromNet(TempGopher, sockfd);
if (i==0) {
GDaddGS(gd, TempGopher);
if (eachitem != NULL)
eachitem();
}
else if (i==1)
return(j);
if (i<0) {
j = j-1;
if (j<0) j=0;
readline(sockfd, ZesTmp, 1024); /** Get the rest of the line **/
return(j);
}
}
}
/*
* Given an open file descriptor and an inited GopherDirobj,
* read in gopher links, and add them to a gopherdir
*/
void
GDfromLink(gd, fd, host, port)
GopherDirObj *gd;
int fd;
char *host;
int port;
{
GopherObj *gs;
gs = GSnew();
while (GSfromLink(gs, fd, host, port) != -1)
GDaddGS(gd, gs);
GSdestroy(gs);
}
void
GDtoLink(gd, fd)
GopherDirObj *gd;
int fd;
{
int i;
for (i=0; i< GDgetTop(gd); i++) {
GStoLink(GDgetEntry(gd, i), fd);
}
}