/* FARGOS Development, LLC Sample Programs Copyright (C) 2002 FARGOS Development, LLC. All rights reserved. mailto:support@fargos.net for assistance. NOTE: in the future, enhanced versions of these classes may be added to the FARGOS/VISTA Object Management Environment core within the Standard namespace. Developers can avoid any potential conflict if they specify an explicit namespace when creating instances of the sample classes. */ %include implicit { const string NEWSGROUP_SERVICE = "NewsgroupDirectory"; }; class Local . MakeArticles { } inherits from Object; MakeArticles:create(int count, string newsgroup) { int i; string mess, newsgroupList; assoc acl; oid obj; set lines; newsgroupList = newsgroup; for(i=2;i\r\n"); lines += "Newsgroups: "; lines += newsgroupList; lines += "\r\n"; lines += makeAsString("Subject: subj-art ", i, "\r\n"); lines += makeAsString("From: user", i, "@localhost\r\n"); lines += "\r\n"; lines += makeAsString("Test article ",i,"\r\n"); lines += newsgroupList; lines += "\r\n"; mess = makeAsString(lines); obj = send "createObject"("NNTParticle", acl, mess) to ObjectCreator; } } MakeArticles:delete() {} class Local . NNTParticle (1) { assoc creationTime; array parsedArticle; string messageID; set newsgroupObjs; int postedOK; } inherits from PersistentObject; NNTParticle:create(string groupName) { /*! See method=initialize. !*/ if (argc != 0) { call "NNTParticle:initialize"(arrayToSet(argv)); } } NNTParticle:initialize(string articleData) { int t, disposition; any newsgroupNames, cmd, info; oid obj; int i; string randomData, databaseName; t = getLocalRelativeTime(); creationTime = convertLocalRelativeTimeToAbsolute(t, 0); parsedArticle = parseMIMEblock(articleData); //display("Headers: ", parsedArticle[0]); if (indexExists(parsedArticle[0], "control") != 0) { cmd = tokenizeString(parsedArticle[0]["control"], " ", 0); if (convertCase(cmd[0], 1) == "cancel") { display("CANCEL: ", cmd[1], "\n"); info = send "findArticleWithMessageId"(cmd[1]) to NEWSGROUP_SERVICE; if (info != nil) { send "deleteYourself" to info[0]; } return (-1); } } newsgroupNames = tokenizeString(parsedArticle[0]["newsgroups"], ", ", 0); if (indexExists(parsedArticle[0], "message-id") == 0) { // generate message Id from time, random bits and message length randomData = makeAsString(encodeLengthAsString(t), makeRandomKey(16), encodeLengthAsString(length(parsedArticle[1]))); messageID = makeAsString(""); parsedArticle[0]["message-id"] = messageID; } else { messageID = parsedArticle[0]["message-id"]; } if (indexExists(parsedArticle[0], "date") == 0) { parsedArticle[0]["date"] = rfc1123Date(creationTime); } //display("newsgroupNames=", newsgroupNames); disposition = 2; // temporary... for (i=0;indexExists(newsgroupNames, i);i+=1) { obj = send "findNewsgroup"(newsgroupNames[i]) to NEWSGROUP_SERVICE; if (obj != nil) { send "registerArticle"(thisObject, messageID, t) to obj from nil; newsgroupObjs += obj; databaseName = send "getDatabaseName" to obj; disposition = 1; // don't auto-restore } else { display("unknown newsgroup ", newsgroupNames[i], "\n"); } } if (disposition == 1) { // Initialize persistence, associate with "newsgroups" database call "PersistentObject:initialize"(databaseName, disposition); } return (0); } NNTParticle:delete() { oid obj; display("Unregister message ", messageID, "\n"); for obj in newsgroupObjs do { send "unregisterArticle"(thisObject, messageID) to obj from nil; } } NNTParticle:objectImported() { display("article ID ", messageID, " imported\n"); } NNTParticle:getPostingStatus() { if (length(messageID) == 0) return (-1); // not set return (elementCount(newsgroupObjs)); } NNTParticle:getNewsgroupCount() { return (elementCount(newsgroupObjs)); } NNTParticle:getNewsgroupObjects() { return (newsgroupObjs); } NNTParticle:getArticleBody() { return (parsedArticle[1]); } NNTParticle:getHeaderData() { return (parsedArticle[0]); } NNTParticle:getHeaderLines() { set lines; assoc ignoreList; string key; int i; for key in { "relay-version", "posting-version", "message-id", "date"} do { ignoreList[key] = 1; } // RFC 850, section 2.1.1 - Relay-Version must be first header line lines += "Relay-Version: FARGOS/VISTA NNTParticle 1.0; site "; lines += getSystemInfoAttribute("hostName"); lines += "\r\n"; // RFC 850, section 2.1.2 lines += "Posting-Version: FARGOS/VISTA NNTParticle 1.0; site "; lines += getSystemInfoAttribute("hostName"); lines += "\r\n"; // Date: Weekday, DD-Mon-YY HH:MM:SS TIMEZONE lines += "Date: "; lines += rfc1123Date(creationTime); lines += "\r\n"; // Message-ID: "<" uniqueText "@" fullDomainName ">" lines += "Message-ID: "; lines += messageID; lines += "\r\n"; // From: // Newsgroups: group[,group2 ...] // Subject: (prefixed with "Re: " if followup) // Path: myHost!nextHost!afterThatHost!originHost // ---- Optional headers ---- // Reply-To, Sender // Followup-To: (like Newsgroups:) // Date-Received: // Expires: // References: messageID[,messageID] // Control: controlMessage // Distribution: (like Newsgroups:) // Organization: /* controlMessage cancel ihave sendme newgroup rmgroup sendsys senduuname version */ for(i = nextIndex(parsedArticle[0], 0); i != 0; i = nextIndex(parsedArticle[0], i)) { key = getKeyForIndex(parsedArticle[0], i); if (indexExists(ignoreList, key) != 0) continue; // ignore lines += makeAsString(convertCase(key, 2), ": "); lines += parsedArticle[0][i]; lines += "\r\n"; } return (lines); }