home *** CD-ROM | disk | FTP | other *** search
- // Contents ---------------------------------------------------------------
- //
- // dsplist.c -- Display linked lists module
- //
- // Version 1.0, Windows Socket Finger Daemon
- //
- // Copyright (C) Frederick W. Bent 1994
- // All rights reserved.
- //
- //
- // Description
- //
- // Module DSPLIST allows the NETWRK_ module to build a display list,
- // and the FINGERD module to retrieve one. A display list is a linked
- // list of text lines accompanied by a count of list entries. The finger
- // daemon uses display lists to represent the the remote finger client's
- // return data in a form suitable for scrolling window display.
- //
- // The display lists are stored in the local heap using Windows functions
- // rather than the C library functions so that the heap can grow easily.
- //
- // Ends -------------------------------------------------------------------
-
- // History ----------------------------------------------------------------
- //
- // 10/20/92 Lee Murach Created.
- // 12/02/92 Lee Murach PushChars() replaces PushChar() as export, LF
- // triggers newline, CRs discarded
- // 01/08/94 Fred Bent Converted everything from malloc() to LocalAlloc()
- // also made sure everything is left moveable.
- //
- // Ends -------------------------------------------------------------------
-
- // Legal Stuff ------------------------------------------------------------
- //
- // Finger Version 3.1, a Windows Sockets Finger Client
- //
- // Copyright 1992, 1993 Network Research Corporation
- //
- // Permission to use, modify, and distribute this software and its
- // documentation for any purpose and without fee is hereby granted, provided
- // that the above copyright notice appears in all copies and that both
- // that copyright notice and this permission notice appear in supporting
- // documentation. NRC makes no claims as to the suitability of this software
- // for any purpose.
- //
- // Ends -------------------------------------------------------------------
-
-
- // Interface Dependencies -------------------------------------------------
-
-
-
-
- #include <string.h>
- #include <stdlib.h>
- #include <windows.h>
- #include "dsplist.h"
-
- #define LF 10 // linefeed
- #define CR 13 // carriage return
- #define TABSTRING " " // 8 character tab
-
- VOID PushChar(char ch);
- VOID PushLine(VOID);
- VOID FreeLine(HLOCAL hLine);
-
- char LineBuf[132]; // holds accumulating text line
- int LineLen; // length of text line
- int LineCount; // n items in list
- HLOCAL hLast;
- HLOCAL hFirst;
-
- //
- // PushChars -- pushes buffer of characters into the display list;
- // expands tabs.
- //
- VOID PushChars(char *buf, int buflen)
- {
- while (buflen--)
- {
- if (*buf == '\t')
- PushChars(TABSTRING, strlen(TABSTRING));
- else
- PushChar(*buf);
-
- buf++;
- }
- }
-
-
- //
- // PushChar -- pushes a character into the LineBuf. Pushes line into
- // the line list if <cr> encountered, or LineBuf is full. Discards
- // linefeeds.
- //
- VOID PushChar(char ch)
- {
- if (LineLen < sizeof(LineBuf))
- if (ch != LF)
- if (ch != CR)
- LineBuf[LineLen++] = ch;
- else; // discard carriage returns
- else // linefeeds signal newline
- PushLine();
- else
- PushLine();
- }
-
- //
- // PushLine -- pushes a text line into the accumulating list of text lines.
- //
- VOID PushLine(VOID)
- {
- HLOCAL hLocal;
- LINEITEM *p, *pLast;
- PSTR szText;
-
-
- hLocal = LocalAlloc(LHND, sizeof(LINEITEM));
-
- if ( hLocal != NULL )
- {
- p = (LINEITEM *) LocalLock(hLocal);
- if (p != NULL)
- {
- p->next = NULL;
-
- if (LineLen > 0)
- {
- HLOCAL hTemp;
-
- hTemp = LocalAlloc(LHND, (LineLen+1));
- p->hText = hTemp;
- if ( hTemp != NULL )
- {
- szText = LocalLock(hTemp);
- if (szText != NULL)
- {
- p->len = LineLen;
- lstrcpyn(szText, (LPSTR) LineBuf, (LineLen+1));
- LocalUnlock(hTemp);
- } else {
- LocalFree(hTemp);
- p->len = 0;
- }
- } else {
- p->len = 0;
- }
- } else {
- p->hText = NULL;
- p->len = 0;
- }
-
- pLast = (LINEITEM *) LocalLock(hLast);
- pLast->next = hLocal;
- LocalUnlock(hLast);
-
- hLast = hLocal;
- LocalUnlock(hLocal);
-
- LineLen = 0;
- LineCount++;
-
- } else {
- LocalFree(hLocal);
- }
- }
- }
-
-
- VOID RemoveFirstDisplayLine(VOID)
- {
- LINEITEM *temp;
- HLOCAL hNext;
-
- if (hFirst != NULL)
- {
- temp = (LINEITEM *) LocalLock(hFirst);
- hNext = temp->next;
- LocalUnlock(hFirst);
- FreeLine(hFirst);
- hFirst = hNext;
- LineCount--;
- }
- }
-
- //
- // FreeDisplayList -- frees the display list, leaves a null list.
- //
- VOID FreeDisplayList(VOID)
- {
- FreeLineList(hFirst);
- hFirst = NULL;
- LineCount = 0;
- }
-
- //
- // FreeLineList -- frees a LINEITEM list
- //
- VOID FreeLineList(HLOCAL hLine)
- {
- LINEITEM *p;
- HLOCAL hNext, hItem;
-
- hItem = hLine;
- while (hItem != NULL)
- {
- p = (LINEITEM *) LocalLock(hItem); // local current item
- hNext = p->next; // what's next?
- LocalUnlock(hItem);
- FreeLine(hItem);
- hItem = hNext;
- }
- }
-
-
- //
- // FreeLine -- frees a LINEITEM
- //
- VOID FreeLine(HLOCAL hLine)
- {
-
- LINEITEM *p;
-
- if (hLine != NULL)
- {
- p = (LINEITEM *) LocalLock(hLine); // local current item
- if ( p->hText != NULL )
- LocalFree(p->hText); // bye bye test buffer
- LocalUnlock(hLine);
- LocalFree(hLine); // bye bye item
- }
- }
-
-
- //
- // OpenDisplayList -- initializes a display list. Call before using
- // PushChar() to build the list.
- //
- BOOL OpenDisplayList(VOID)
- {
- LineCount = LineLen = 0;
-
- // initialize list with a dummy LINEITEM
- if ((hLast = hFirst = LocalAlloc(LHND, sizeof(LINEITEM))) != NULL )
- return TRUE;
-
- return FALSE; // failure
- }
-
- //
- // CloseDisplayList -- pushes final LINEITEM (if any) onto list, and
- // releases dummy list header. Call after last PushChar() to complete
- // the display list.
- //
- VOID CloseDisplayList(VOID)
- {
- LINEITEM *pFirst;
- HLOCAL hNext;
-
- if (LineLen > 0) // part of a line
- PushLine();
-
- pFirst = (LINEITEM *) LocalLock(hFirst);
- hNext = pFirst->next;
- LocalUnlock(hFirst);
- FreeLine(hFirst);
- hFirst = hNext;
- }
-
- //
- // GetDispList -- retrieves the display list.
- //
- VOID GetDisplayList(HLOCAL *ppLine, int *pNLines)
- {
- *ppLine = hFirst;
- *pNLines = LineCount;
- }
-
-
- long GetSizeOfDisplay(HLOCAL hItem)
- {
- long lSize;
- LINEITEM *p;
- HLOCAL hNext;
-
- hItem = hItem;
- lSize = 0L;
- while (hItem != NULL)
- {
- p = (LINEITEM *) LocalLock(hItem); // local current item
- hNext = p->next; // what's next?
- lSize += p->len + 2; // don't forget <CRLF>!
- LocalUnlock(hItem);
- hItem = hNext;
- }
-
- return lSize;
- }
-
- HGLOBAL CopyDisplayList(VOID)
- {
- long lSize;
- HGLOBAL hGlobal;
- LINEITEM *p;
- HLOCAL hNext, hItem;
- PSTR szText;
- LPSTR lpszBuffer;
-
-
- hGlobal = GlobalAlloc(GHND, GetSizeOfDisplay(hFirst));
- if ( hGlobal == NULL) return NULL;
-
- lpszBuffer = GlobalLock(hGlobal);
- if ( lpszBuffer == NULL)
- {
- GlobalFree(hGlobal);
- return NULL;
- }
-
- hItem = hFirst;
- while (hItem != NULL)
- {
- p = (LINEITEM *)LocalLock(hItem); // local current item
- hNext = p->next; // what's next?
- if ( p->hText != NULL)
- {
- szText = LocalLock(p->hText);
- lstrcat(lpszBuffer, (LPSTR) szText);
- LocalUnlock(p->hText);
- }
- lstrcat(lpszBuffer, "\r\n");
- LocalUnlock(hItem);
- hItem = hNext;
- }
- GlobalUnlock(hGlobal);
-
- return hGlobal;
-
- }
-
-
-