// ===================================================
// Листинг 28. Посылка сообщения станциям
//
// Файл msgsend\msgsend.cpp
//
// (C) A. Frolov, 1993
// ===================================================

#include <stdlib.h>
#include <stdio.h>

#define WORD unsigned int
#define BYTE unsigned char

typedef struct {
	 char    serverName[48];
	 BYTE    netwareVersion;
	 BYTE    netwareSubVersion;
	 WORD    maxConnectionsSupported;
	 WORD    connectionsInUse;
	 WORD    maxVolumesSupported;
	 BYTE    revisionLevel;
	 BYTE    SFTLevel;
	 BYTE    TTSLevel;
	 WORD    peakConnectionsUsed;
	 BYTE    accountingVersion;
	 BYTE    VAPversion;
	 BYTE    queingVersion;
	 BYTE    printServerVersion;
	 BYTE    virtualConsoleVersion;
	 BYTE    securityRestrictionLevel;
	 BYTE    internetBridgeSupport;
} FILE_SERV_INFO;

extern "C" int GetNetWareShellVersion(char *,char *, char *);
extern "C" int BroadcastToConsole(char *);
extern "C" int SendBroadcastMessage(char*, WORD*, BYTE*, WORD);
extern "C" int LogNetworkMessage(char*);
extern "C" void GetServerInformation(int, FILE_SERV_INFO*);
extern "C" int GetConnectionInformation(WORD, char *, WORD *,
						long *, BYTE *);


void main(int argc, char *argv[]) {

	char MajorVersion=0;
	char MinorVersion=0;
	char Revision=0;

	long ObjectID;
	char ObjectName[48];
	WORD ObjectType;
	BYTE LoginTime;
	FILE_SERV_INFO ServerInfo;
	int MaxUsers;

	WORD ConnectionList[250];
	BYTE ResultList[250];
	WORD ConnectionCount;

	printf("\n*MSGSEND* (C) Frolov A., 1993\n");

	if(argc < 2) {
		printf("Введите сообщение в качестве параметра\n");
		return;
	}

// Проверяем присутствие сетевой оболочки

	asm push si
	GetNetWareShellVersion(&MajorVersion,
			&MinorVersion, &Revision);
	asm pop si

	if(MajorVersion == 0) {
		printf("\nОболочка NetWare не загружена\n");
		return;
	}

// Выводим сообщение на консоль файл-сервера и
// записываем его в журнал

	BroadcastToConsole("*MSGSEND* (C) Frolov A., 1993");
	LogNetworkMessage("*MSGSEND* (C) Frolov A., 1993");

// Получаем информацию о сервере. Нас интересует
// в первую очередь максимальное количество пользователей,
// которые могут подключиться к файл-серверу

	GetServerInformation(sizeof(ServerInfo), &ServerInfo);

// Запоминаем максимальное количество пользователей

	MaxUsers = ServerInfo.maxConnectionsSupported;

	printf("Сервер %s, версия на %d пользователей\n",
		ServerInfo.serverName,	MaxUsers);

// Цикл посылки сообщений
// Подсчитываем количество используемых каналов
// и для каждого канала заполняем массив ConnectionList[]

	printf("\nСообщение посылается пользователям:\n");

	ConnectionCount = 0;

	for(int i=1, j=0; i <= MaxUsers; i++) {

// Получаем информацию о канале

		GetConnectionInformation(i, ObjectName, &ObjectType,
				&ObjectID, &LoginTime);

// Если есть имя объекта, выводим его на экран

		if(ObjectName[0] != '\0') {
			printf("%s\n", ObjectName);

// Записываем номер канала в массив

			ConnectionList[j++] = i;
			ConnectionCount += 1;
		}
	}

// Посылаем сообщение обнаруженным пользователям

	SendBroadcastMessage(argv[1],
		ConnectionList, ResultList, ConnectionCount);
}