filesys.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002                           filesys.cpp  -  description
00003                              -------------------
00004     begin                : Thu Dec 9 2004
00005     copyright            : (C) 2004 by VooDooMan
00006     email                : vdmfun@hotmail.com
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010 
00011 VooDoo cIRCle - an IRC (ro)bot
00012 Copyright (C) 2004 by Marian VooDooMan Meravy (vdmfun@hotmail.com)
00013 
00014 This program is free software; you can redistribute it and/or
00015 modify it under the terms of the GNU General Public License
00016 as published by the Free Software Foundation; either version 2
00017 of the License, or (at your option) any later version.
00018 
00019 This program is distributed in the hope that it will be useful,
00020 but WITHOUT ANY WARRANTY; without even the implied warranty of
00021 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00022 GNU General Public License for more details.
00023 
00024 You should have received a copy of the GNU General Public License
00025 along with this program; if not, write to the Free Software
00026 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00027 
00028 ****************************************************************************/
00029 
00030 /*!
00031     \file
00032     \brief Handles filesystem
00033 */
00034 
00035 #include <string>
00036 #include <vector>
00037 #include <time.h>
00038 #include <stdlib.h>
00039 #include <stdio.h>
00040 #ifdef _WIN32
00041 #    include <io.h>
00042 #else
00043 #    include <unistd.h>
00044 #endif
00045 
00046 #include "filesys.h"
00047 #include "dcc.h"
00048 #include "conf.h"
00049 #include "irc.h"
00050 #include "logic.h"
00051 #include "lang.h"
00052 
00053 #include "params.h"
00054 
00055 #pragma hdrstop
00056 
00057 using namespace std;
00058 
00059 #ifdef _WIN32
00060 #    define FILE_SLASH "\\"
00061 #else
00062 #    define FILE_SLASH "/"
00063 #endif
00064 
00065 #ifndef _WIN32
00066 #ifndef HAVE_LTOA
00067 extern char *ltoa(long value, char *buffer, int radix);
00068 #endif
00069 #endif
00070 
00071 vector<s_file> files;                       //!< List of all files in the filesystem
00072 
00073 bool filesys_init_done=false;               //!< Have we initialised the filesystem yet?
00074 
00075 time_t filesys_last_flush=0;                //!< Timestamp of last call to filesys_flush()
00076 
00077 /*!
00078     \brief Parses line from index file (key=value)
00079     \author VooDooMan
00080     \version 1
00081     \date 2004
00082     \param ln Line to parse
00083     \param key Returns key (key=value)
00084     \param val Returns value (key=value)
00085     \param end Returns true if comment was found
00086     \return Returns true if succeeded (false for empty line, etc...)
00087 */
00088 bool filesys_get_key(char* ln, string& key, string& val, bool& end)
00089 {
00090     key="";
00091     val="";
00092     end=false;
00093     if(strlen(ln)) {
00094         if(ln[0]=='#') {
00095             end=true;
00096             return false;
00097         }
00098         int pos=0;
00099         for(unsigned int i1=0; i1<strlen(ln); i1++) {
00100             if(pos==0 && ln[i1]=='=') {
00101                 pos++;
00102                 continue;
00103             }
00104             if(pos==0)
00105                 key+=ln[i1];
00106             if(pos>0)
00107                 val+=ln[i1];
00108         }
00109         return true;
00110     } else
00111         return false;
00112 }
00113 
00114 /*!
00115     \brief Initializes the filesystem
00116     \author VooDooMan
00117     \version 1
00118     \date 2004
00119 */
00120 void filesys_init()
00121 {
00122     if(filesys_init_done)
00123         return;
00124     filesys_init_done=true;
00125 
00126     files.clear();
00127     FILE* f=fopen("." FILE_SLASH "filesystem" FILE_SLASH "index.txt","r");
00128     if(!f) {
00129         f=fopen("." FILE_SLASH "filesystem" FILE_SLASH "index.txt","w");
00130         if(!f) {
00131             return;
00132         }
00133         fclose(f);
00134         return;
00135     }
00136     char ln[1024+16];
00137 
00138     s_file file;
00139     s_access access;
00140     s_event event;
00141 
00142     while(!feof(f)) {
00143         if(fgets(ln,1024-1,f)==NULL)
00144             break;
00145 
00146         while(strlen(ln) && ln[strlen(ln)-1]=='\n')
00147             ln[strlen(ln)-1]=0;
00148         while(strlen(ln) && ln[strlen(ln)-1]=='\r')
00149             ln[strlen(ln)-1]=0;
00150 
00151         string key, val;
00152         bool end;
00153         if(!filesys_get_key(ln,key,val,end))
00154             continue;
00155 
00156         if(!key.compare("FILE_BEGIN")) {
00157             access.clear();
00158             file.clear();
00159             event.clear();
00160             continue;
00161         }
00162 
00163         if(!key.compare("FILE_END")) {
00164             files.push_back(file);
00165             access.clear();
00166             file.clear();
00167             event.clear();
00168             continue;
00169         }
00170 
00171         if(!key.compare("InternalName")) {
00172             file.internal_name=val;
00173             continue;
00174         }
00175 
00176         if(!key.compare("PublicName")) {
00177             file.public_name=val;
00178             continue;
00179         }
00180 
00181         if(!key.compare("Published")) {
00182             file.published=!val.compare("1");
00183             continue;
00184         }
00185 
00186         if(!key.compare("Complete")) {
00187             file.complete=!val.compare("1");
00188             continue;
00189         }
00190 
00191         if(!key.compare("Time")) {
00192             file.ftime=atol(val.c_str());
00193             continue;
00194         }
00195 
00196         if(!key.compare("Expiration")) {
00197             file.expiration=atol(val.c_str());
00198             continue;
00199         }
00200 
00201         if(!key.compare("Type")) {
00202             file.file_type=ft_invalid;
00203             if(!val.compare("file"))
00204                 file.file_type=ft_file;
00205             if(!val.compare("message"))
00206                 file.file_type=ft_message;
00207             continue;
00208         }
00209 
00210         if(!key.compare("ACCESS_BEGIN")) {
00211             access.clear();
00212             continue;
00213         }
00214 
00215         if(!key.compare("ACCESS_END")) {
00216             file.access.push_back(access);
00217             access.clear();
00218             continue;
00219         }
00220 
00221         if(!key.compare("UserName")) {
00222             access.user_name=val;
00223             continue;
00224         }
00225 
00226         if(!key.compare("AllOnChannel")) {
00227             access.all_on_channel=val;
00228             continue;
00229         }
00230 
00231         if(!key.compare("AlsoUnknown")) {
00232             access.also_unknown=!val.compare("1");
00233             continue;
00234         }
00235 
00236         if(!key.compare("AllUsers")) {
00237             access.all_users=!val.compare("1");
00238             access.user_name="";
00239             continue;
00240         }
00241 
00242         if(!key.compare("Owner")) {
00243             access.owner=!val.compare("1");
00244             continue;
00245         }
00246 
00247         if(!key.compare("Read")) {
00248             access.read=!val.compare("1");
00249             continue;
00250         }
00251 
00252         if(!key.compare("Delete")) {
00253             access.del=!val.compare("1");
00254             continue;
00255         }
00256 
00257         if(!key.compare("NotifyOwner")) {
00258             access.notify_owner=!val.compare("1");
00259             continue;
00260         }
00261 
00262         if(!key.compare("NotifyUser")) {
00263             access.notify_user=!val.compare("1");
00264             continue;
00265         }
00266 
00267         if(!key.compare("Secure")) {
00268             access.secure=!val.compare("1");
00269             continue;
00270         }
00271 
00272         if(!key.compare("EVENT_BEGIN")) {
00273             event.clear();
00274             continue;
00275         }
00276 
00277         if(!key.compare("EVENT_END")) {
00278             file.events.push_back(event);
00279             event.clear();
00280             continue;
00281         }
00282 
00283         if(!key.compare("EventHasRead")) {
00284             event.has_read=!val.compare("1");
00285             continue;
00286         }
00287 
00288         if(!key.compare("EventOwnerNotified")) {
00289             event.owner_notified=!val.compare("1");
00290             continue;
00291         }
00292 
00293         if(!key.compare("EventUserName")) {
00294             event.user_name=val;
00295             continue;
00296         }
00297 
00298         if(!key.compare("EventTimestamp")) {
00299             event.first=atol(val.c_str());
00300             continue;
00301         }
00302 
00303         if(!key.compare("NotifyOwnerMessage")){
00304             access.notify_owner_message+=val;
00305             continue;
00306         }
00307 
00308         if(!key.compare("NotifyUserMessage")){
00309             access.notify_user_message+=val;
00310             continue;
00311         }
00312 
00313         if(!key.compare("UserNotified")){
00314             event.user_notified=!val.compare("1");
00315             continue;
00316         }
00317     }
00318     fclose(f);
00319 
00320     filesys_flush(); // for killing of expired files
00321 }
00322 
00323 /*!
00324     \brief Writes new index file from memory
00325     \author VooDooMan
00326     \version 1
00327     \date 2004
00328 */
00329 void filesys_flush()
00330 {
00331     time(&filesys_last_flush);
00332 
00333     extern bool dcc_want_to_upgrade;
00334     if(dcc_want_to_upgrade)
00335         return;
00336 
00337     FILE* f=fopen("." FILE_SLASH "filesystem" FILE_SLASH "index.txt","w");
00338     if(!f)
00339         return;
00340 
00341     vector<s_file>::iterator i1;
00342 again:
00343     for(i1=files.begin(); i1!=files.end(); i1++) {
00344         if((*i1).expiration!=0 && (*i1).expiration<=time(NULL)) {
00345             string fn="." FILE_SLASH "filesystem" FILE_SLASH;
00346             fn+=(*i1).internal_name;
00347             unlink(fn.c_str());
00348             (*i1).expired=true;
00349             files.erase(i1);
00350             goto again;
00351         }
00352         fprintf(f,"#\nFILE_BEGIN=\nInternalName=%s\nPublicName=%s\nTime=%ld\nType=",(*i1).internal_name.c_str(),(*i1).public_name.c_str(),(*i1).ftime);
00353         if((*i1).file_type==ft_invalid)
00354             fprintf(f,"invalid");
00355         if((*i1).file_type==ft_file)
00356             fprintf(f,"file");
00357         if((*i1).file_type==ft_message)
00358             fprintf(f,"message");
00359         fprintf(f,"\nPublished=%d\nComplete=%d\nExpiration=%ld\n",(*i1).published,(*i1).complete,(*i1).expiration);
00360         fprintf(f,"#\n");
00361         vector<s_access>::iterator i2;
00362         for(i2=(*i1).access.begin(); i2!=(*i1).access.end(); i2++) {
00363             fprintf(f,"ACCESS_BEGIN=\n");
00364             fprintf(f,"AllUsers=%d\nUserName=%s\nOwner=%d\nRead=%d\nDelete=%d\nNotifyOwner=%d\nNotifyUser=%d\nSecure=%d\n",(*i2).all_users,(*i2).user_name.c_str(),(*i2).owner,(*i2).read,(*i2).del,(*i2).notify_owner,(*i2).notify_user,(*i2).secure);
00365             vector<string>::iterator i3;
00366             fprintf(f,"AllOnChannel=%s\n",(*i2).all_on_channel.c_str());
00367             fprintf(f,"AlsoUnknown=%d\n",(*i2).also_unknown);
00368             string msg_orig=(*i2).notify_owner_message;
00369             unsigned int i1;
00370             string msg;
00371             for(i1=0; i1<msg_orig.length(); i1++) {
00372                 if(msg_orig[i1]=='\n') {
00373                     msg+="\\n";
00374                     continue;
00375                 }
00376                 msg+=msg_orig[i1];
00377             }
00378             string partial;
00379             for(i1=0; i1<msg.length(); i1++) {
00380                 partial+=msg[i1];
00381                 if((i1!=0 && i1%128==0) || i1==msg.length()-1) {
00382                     fprintf(f,"NotifyOwnerMessage=%s\n",partial.c_str());
00383                     partial="";
00384                 }
00385             }
00386             msg_orig=(*i2).notify_user_message;
00387             msg="";
00388             for(i1=0; i1<msg_orig.length(); i1++) {
00389                 if(msg_orig[i1]=='\n') {
00390                     msg+="\\n";
00391                     continue;
00392                 }
00393                 msg+=msg_orig[i1];
00394             }
00395             partial="";
00396             for(i1=0; i1<msg.length(); i1++) {
00397                 partial+=msg[i1];
00398                 if((i1!=0 && i1%128==0) || i1==msg.length()-1) {
00399                     fprintf(f,"NotifyUserMessage=%s\n",partial.c_str());
00400                     partial="";
00401                 }
00402             }
00403             fprintf(f,"ACCESS_END=\n#\n");
00404         }
00405 
00406         // pack events
00407 pack_continue:
00408         vector<s_event>::iterator i3;
00409         for(i3=(*i1).events.begin(); i3!=(*i1).events.end(); i3++) {
00410             vector<s_event>::iterator i4;
00411             for(i4=(*i1).events.begin(); i4!=(*i1).events.end(); i4++) {
00412                 if(i3==i4)
00413                     continue;
00414                 if(!(*i4).user_name.compare((*i3).user_name)) {
00415                     (*i3).has_read=(*i4).has_read || (*i3).has_read;
00416                     (*i3).owner_notified=(*i4).owner_notified || (*i3).owner_notified;
00417                     (*i3).user_notified=(*i4).user_notified || (*i3).user_notified;
00418 
00419                     if((*i4).first>(*i3).first)
00420                         (*i3).first=(*i4).first;
00421 
00422                     (*i1).events.erase(i4);
00423                     goto pack_continue;
00424                 }
00425             }
00426         }
00427 
00428         for(i3=(*i1).events.begin(); i3!=(*i1).events.end(); i3++) {
00429             fprintf(f,"EVENT_BEGIN=\n");
00430             fprintf(f,"EventHasRead=%d\nEventOwnerNotified=%d\nEventUserName=%s\nUserNotified=%d\nEventTimestamp=%ld\n",(*i3).has_read,(*i3).owner_notified,(*i3).user_name.c_str(),(*i3).user_notified,(*i3).first);
00431             fprintf(f,"EVENT_END=\n#\n");
00432         }
00433 
00434         fprintf(f,"FILE_END=\n###\n");
00435     }
00436 
00437     fclose(f);
00438 }
00439 
00440 /*!
00441     \brief Adds a new file to filesystem, if the same public name exists, and owner argument is its owner, it will be replaced
00442     \author VooDooMan
00443     \version 1
00444     \date 2004
00445     \param internal_name Internal name of the file
00446     \param original_name Original name of the file
00447     \param owner Owner of the file (from "logic.txt")
00448     \param complete Set to true if file is complete. If false, it will be tried to resume (DCC RESUME extension to standard DCC protocol)
00449     \param after_resume Set this to true if file was updated deu to resume in DCC SEND (DCC RESUME extension)
00450 */
00451 void filesys_add_file_raw(string internal_name, string original_name, string owner, bool complete, bool after_resume)
00452 {
00453     filesys_init();
00454 
00455     string sender_file_name=original_name;
00456 
00457     for(unsigned int i2=0; i2<original_name.length(); i2++) {
00458         bool ok=false;
00459         if(original_name[i2]>='a' && original_name[i2]<='z')
00460             ok=true;
00461         if(original_name[i2]>='A' && original_name[i2]<='Z')
00462             ok=true;
00463         if(original_name[i2]>='0' && original_name[i2]<='9')
00464             ok=true;
00465         if(original_name[i2]=='_' || original_name[i2]=='-' || original_name[i2]=='.')
00466             ok=true;
00467         if(!ok)
00468             original_name[i2]='_';
00469     }
00470 
00471     s_file f;
00472     bool got_file=false;
00473 
00474 again:
00475     if(!after_resume) {
00476         vector<s_file>::iterator i1;
00477         for(i1=files.begin(); i1!=files.end(); i1++) {
00478             if(!(*i1).public_name.compare(original_name)) {
00479                 if((*i1).is_owner(owner)) {
00480                     string fn="." FILE_SLASH "filesystem" FILE_SLASH;
00481                     fn+=(*i1).internal_name;
00482                     unlink(fn.c_str());
00483                     files.erase(i1);
00484                     goto again;
00485                 }
00486             }
00487         }
00488     } else {
00489         vector<s_file>::iterator i1;
00490         bool is_owner=false;
00491         for(i1=files.begin(); i1!=files.end(); i1++) {
00492             if((*i1).public_name.compare(sender_file_name))
00493                 continue;
00494             vector<s_access>::iterator i2;
00495             for(i2=(*i1).access.begin(); i2!=(*i1).access.end(); i2++) {
00496                 if((*i2).owner && !owner.compare((*i2).user_name)) {
00497                     is_owner=true;
00498                     break;
00499                 }
00500             }
00501             got_file=true;
00502             break;
00503         }
00504         if(!is_owner)
00505             return;
00506 
00507         f=*i1;
00508     }
00509 
00510     if(original_name.length()>1024-128)
00511         return;
00512 
00513     f.file_type=ft_file;
00514     time(&f.ftime);
00515     if(!got_file) {
00516         f.sender_file_name=sender_file_name;
00517         f.complete=complete;
00518         f.internal_name=internal_name;
00519         f.public_name=original_name;
00520         f.published=false;
00521 
00522         s_access a;
00523         a.all_users=false;
00524         a.user_name=owner;
00525         a.owner=true;
00526         a.read=true;
00527         a.del=true;
00528 
00529         f.access.push_back(a);
00530 
00531         files.push_back(f);
00532     } else {
00533         vector<s_file>::iterator i1;
00534         for(i1=files.begin(); i1!=files.end(); i1++) {
00535             if((*i1).public_name.compare(sender_file_name))
00536                 continue;
00537             f.complete=complete;
00538             (*i1)=f;
00539             break;
00540         }
00541     }
00542 
00543     if(filesys_last_flush+60<time(NULL))
00544         filesys_flush();
00545 
00546     if(complete)
00547         dcc_notify(owner,FILESYS_NOT_PUBLISHED,"");
00548     else
00549         dcc_notify(owner,FILESYS_GOT_INCOMPLETE,sender_file_name);
00550 }
00551 
00552 /*
00553     \brief Builds a message for notifying user how to download file via ".getfile"
00554     \author VooDooMan
00555     \version 2
00556     \date 2004
00557     \param a Access rights with messages
00558     \param public_name Public name of file
00559     \param eol EOL sequence
00560     \param lang Language to use for user
00561     \return Returns message for user
00562 */
00563 string filesys_build_getfile_message(s_access a, string public_name, string lang, string eol)
00564 {
00565     string msg;
00566     if(!a.notify_user_message.empty())  {
00567         string m;
00568         int i2=0;
00569         for(unsigned int i1=0; i1<a.notify_user_message.length(); i1++) {
00570             if(a.notify_user_message[i1]=='\n')
00571                 i2=i1;
00572             if(i1-i2>=128 && a.notify_user_message[i1]!='\n') {
00573                 m+=eol;
00574                 i2=i1;
00575             }
00576             m+=a.notify_user_message[i1];
00577         }
00578         string m2;
00579         for(unsigned int i3=0; i3<m.length(); i3++) {
00580             if(i3+1<m.length() && m[i3]=='%' && m[i3+1]=='%') {
00581                 i3++;
00582                 m2+=public_name;
00583                 continue;
00584             }
00585             if((i3+1<m.length() && m[i3]=='%' && m[i3+1]!='%') || (i3+1==m.length() && m[i3]=='%')) {
00586                 m2+=" .getfile "; // SPACE as first character! To avoid bot loops!
00587                 m2+=public_name;
00588                 continue;
00589             }
00590             m2+=m[i3];
00591         }
00592         msg+=m2;
00593     }
00594     msg+=eol;
00595     msg+="---";
00596     msg+=eol;
00597     msg.append(lang_get_string(1,lang,655)); // Use command:
00598     msg+=eol;
00599     msg+=" .getfile "; // SPACE as first character! To avoid bot loops!
00600     msg+=public_name;
00601     msg+=eol;
00602     msg.append(lang_get_string(1,lang,656)); // To get the file.
00603     msg+=eol;
00604     msg+="---";
00605     msg+=eol;
00606     return msg;
00607 }
00608 
00609 /*
00610     \brief Returns time string
00611     \author VooDooMan
00612     \version 1
00613     \date 2005
00614     \param t Time to convert to text
00615     \return Returns time string of "t"
00616 */
00617 string filesys_get_time_str(time_t t)
00618 {
00619     char time_[512];
00620     strcpy(time_,ctime(&t));
00621     int ii;
00622     for(ii=0; time_[ii]!='\r' && time_[ii]!='\n' && time_[ii]!=0; ii++)
00623         ;
00624     time_[ii]=0;
00625     return time_;
00626 }
00627 
00628 /*!
00629     \brief Checks for notifications about new object in the filesystem
00630     \author VooDooMan
00631     \version 1
00632     \date 2004
00633     \param user User name from "logic.txt"
00634     \param notify Returns list of notifications
00635     \param secured Set to true if client is connected via DCC CHAT or telnet (has been authentificated)
00636     \param channel Name of channel that is the user on
00637     \param u User descriptor
00638     \param chs User's channels
00639     \param eol EOL sequence to use
00640     \param lang Language to use for user
00641     \return Returns true if any notification was found
00642 */
00643 bool filesys_dcc_check_for_notifies(string user, s_user& u, vector<s_channel>& chs, string channel, vector<s_dcc_notify>& notify, bool secured, string lang, string eol)
00644 {
00645     filesys_init();
00646 
00647     notify.clear();
00648 
00649     bool host_unknown=false;
00650     /*s_user u;
00651     vector<s_channel> chs;
00652     logic_partyline_get_user(user,u,chs);*/
00653     host_unknown=u.host_unknown;
00654 
00655     vector<s_file>::iterator i1;
00656     for(i1=files.begin(); i1!=files.end(); i1++) {
00657         if(!(*i1).published && (*i1).complete) {
00658             vector<s_access>::iterator i2;
00659             for(i2=(*i1).access.begin(); i2!=(*i1).access.end(); i2++) {
00660                 if((*i2).owner && ((*i2).all_users || !(*i2).user_name.compare(user))) {
00661                     s_dcc_notify n;
00662                     n.unpublished=true;
00663                     n.name=(*i1).public_name.c_str();
00664                     notify.push_back(n);
00665                     break;
00666                 }
00667             }
00668             continue;
00669         }
00670         if(!(*i1).complete) {
00671             vector<s_access>::iterator i2;
00672             for(i2=(*i1).access.begin(); i2!=(*i1).access.end(); i2++) {
00673                 if((*i2).owner && ((*i2).all_users || !(*i2).user_name.compare(user))) {
00674                     s_dcc_notify n;
00675                     n.incomplete=true;
00676                     n.name=(*i1).public_name.c_str();
00677                     notify.push_back(n);
00678                     break;
00679                 }
00680             }
00681             continue;
00682         }
00683         vector<s_access>::iterator i2;
00684         for(i2=(*i1).access.begin(); i2!=(*i1).access.end(); i2++) {
00685             if(!(*i2).also_unknown && host_unknown && (*i2).user_name.compare(user))
00686                 continue;
00687             string on_channel;
00688             if(!cmp_strings_case_insensitive((*i2).all_on_channel,channel))
00689                 on_channel=(*i2).all_on_channel;
00690             if((*i2).all_users || !(*i2).user_name.compare(user) || !on_channel.empty()) {
00691                 if((*i2).notify_user) {
00692                     bool got=false;
00693                     vector<s_event>::iterator i3;
00694                     for(i3=(*i1).events.begin(); i3!=(*i1).events.end(); i3++) {
00695                         if(!(*i3).has_read && !(*i3).user_name.compare(user) && !(*i3).user_notified) {
00696                             s_dcc_notify n;
00697                             bool secure=(*i2).secure;
00698                             n.notify_user=!secure;
00699                             n.secure_notify_user=secure;
00700                             n.name=(*i1).public_name.c_str();
00701                             n.message=(*i2).notify_user_message;
00702                             if((*i1).file_type==ft_message && ((secured && (*i2).secure) || !(*i2).secure) && !host_unknown) {
00703                                 s_event e;
00704                                 e.has_read=true;
00705                                 e.owner_notified=false;
00706                                 e.user_name=user;
00707                                 e.user_notified=true;
00708                                 e.first=time(NULL);
00709                                 (*i1).events.push_back(e);
00710 
00711                                 string msg=eol;
00712                                 msg+="---";
00713                                 msg+=eol;
00714                                 msg.append(lang_get_string(1,lang,657)); // Message from
00715                                 msg+=" ";
00716                                 vector<s_access>::iterator i3;
00717                                 for(i3=(*i1).access.begin(); i3!=(*i1).access.end(); i3++)
00718                                     if((*i3).owner) {
00719                                         msg+=(*i3).user_name;
00720                                         break;
00721                                     }
00722                                 msg+=eol;
00723                                 lang_get_string(1,lang,658); // On
00724                                 msg+=" ";
00725                                 msg+=filesys_get_time_str((*i1).ftime);
00726                                 msg+=eol;
00727                                 msg.append(lang_get_string(1,lang,659)); // Subject:
00728                                 msg+=" ";
00729                                 msg+=(*i1).public_name;
00730                                 msg+=eol;
00731                                 string fn="." FILE_SLASH "filesystem" FILE_SLASH;
00732                                 fn+=(*i1).internal_name;
00733                                 FILE* f=fopen(fn.c_str(),"rb");
00734                                 if(f) {
00735                                     char buff[128+1];
00736                                     while(!feof(f)) {
00737                                         size_t len=fread(buff,1,sizeof(buff)-1,f);
00738                                         buff[len]=0;
00739                                         for(unsigned int i2=0; i2<len; i2++)
00740                                             if(buff[i2]=='\n')
00741                                                 msg+=eol;
00742                                             else
00743                                                 msg.push_back(buff[i2]);
00744                                         //msg+=buff;
00745                                         //msg+=eol;
00746                                     }
00747                                     fclose(f);
00748                                     msg+="---";
00749                                     msg+=eol;
00750                                     n.message=msg;
00751                                 }
00752                             }
00753                             if(n.message.length()) {
00754                                 string msg=eol;
00755                                 msg+="---";
00756                                 msg+=eol;
00757                                 msg.append(lang_get_string(1,lang,660)); // File from
00758                                 msg+=" ";
00759                                 vector<s_access>::iterator i3;
00760                                 for(i3=(*i1).access.begin(); i3!=(*i1).access.end(); i3++)
00761                                     if((*i3).owner) {
00762                                         msg+=(*i3).user_name;
00763                                         break;
00764                                     }
00765                                 msg+=eol;
00766                                 msg.append(lang_get_string(1,lang,658)); // On
00767                                 msg+=" ";
00768                                 msg+=filesys_get_time_str((*i1).ftime);
00769                                 msg+=eol;
00770                                 msg.append(lang_get_string(1,lang,661)); // File name:
00771                                 msg+=" ";
00772                                 msg+=(*i1).public_name;
00773                                 msg+=eol;
00774                                 msg.append(lang_get_string(1,lang,662)); // Message from owner:
00775                                 msg+=eol;
00776                                 msg+=filesys_build_getfile_message(*i2,(*i1).public_name,lang,eol);
00777                                 n.message=msg;
00778                                 notify.push_back(n);
00779                                 got=true;
00780                                 break;
00781                             }
00782                             if(!secured && (*i2).secure) {
00783                                 n.message="";
00784                                 notify.push_back(n);
00785                                 got=true;
00786                                 break;
00787                             }
00788                         }
00789                         if(!(*i3).user_name.compare(user) && (*i3).user_notified) {
00790                             got=true;
00791                             break;
00792                         }
00793                     }
00794                     if(!got) {
00795                         s_dcc_notify n;
00796                         bool secure=(*i2).secure;
00797                         n.notify_user=((secured && (*i2).secure) || !(*i2).secure);
00798                         n.secure_notify_user=secure;
00799                         n.name=(*i1).public_name.c_str();
00800                         n.message=(*i2).notify_user_message;
00801                         if((*i1).file_type==ft_message && ((secured && (*i2).secure) || !(*i2).secure)) {
00802                             if(!host_unknown) {
00803                                 s_event e;
00804                                 e.has_read=true;
00805                                 e.owner_notified=false;
00806                                 e.user_name=user;
00807                                 e.user_notified=true;
00808                                 e.first=time(NULL);
00809                                 (*i1).events.push_back(e);
00810                             }
00811 
00812                             string msg=eol;
00813                             msg+="---";
00814                             msg+=eol;
00815                             msg.append(lang_get_string(1,lang,657)); // Message from
00816                             msg+=" ";
00817                             vector<s_access>::iterator i3;
00818                             for(i3=(*i1).access.begin(); i3!=(*i1).access.end(); i3++)
00819                                 if((*i3).owner) {
00820                                     msg+=(*i3).user_name;
00821                                     break;
00822                                 }
00823                             msg+=eol;
00824                             msg.append(lang_get_string(1,lang,658)); // On
00825                             msg+=" ";
00826                             msg+=filesys_get_time_str((*i1).ftime);
00827                             msg+=eol;
00828                             msg.append(lang_get_string(1,lang,659)); // Subject:
00829                             msg+=" ";
00830                             msg+=(*i1).public_name;
00831                             msg+=eol;
00832                             string fn="." FILE_SLASH "filesystem" FILE_SLASH;
00833                             fn+=(*i1).internal_name;
00834                             FILE* f=fopen(fn.c_str(),"rb");
00835                             if(f) {
00836                                 char buff[128+1];
00837                                 while(!feof(f)) {
00838                                     size_t len=fread(buff,1,sizeof(buff)-1,f);
00839                                     buff[len]=0;
00840                                     for(unsigned int i2=0; i2<len; i2++)
00841                                         if(buff[i2]=='\n')
00842                                             msg+=eol;
00843                                         else
00844                                             msg.push_back(buff[i2]);
00845                                     //msg+=buff;
00846                                     //msg+=eol;
00847                                 }
00848                                 fclose(f);
00849                                 msg+="---";
00850                                 msg+=eol;
00851                                 n.message=msg;
00852                             }
00853                         }
00854                         if((*i1).file_type==ft_file && ((secured && (*i2).secure) || !(*i2).secure)) {
00855                             if(!host_unknown) {
00856                                 s_event e;
00857                                 e.has_read=false;
00858                                 e.owner_notified=false;
00859                                 e.user_name=user;
00860                                 e.user_notified=true;
00861                                 e.first=time(NULL);
00862                                 (*i1).events.push_back(e);
00863                             }
00864 
00865                             string msg=eol;
00866                             msg+="---";
00867                             msg+=eol;
00868                             msg.append(lang_get_string(1,lang,660)); // File from:
00869                             msg+=" ";
00870                             vector<s_access>::iterator i3;
00871                             for(i3=(*i1).access.begin(); i3!=(*i1).access.end(); i3++)
00872                                 if((*i3).owner) {
00873                                     msg+=(*i3).user_name;
00874                                     break;
00875                                 }
00876                             msg+=eol;
00877                             msg.append(lang_get_string(1,lang,658)); // On
00878                             msg+=" ";
00879                             msg+=filesys_get_time_str((*i1).ftime);
00880                             msg+=eol;
00881                             msg+="File name: ";
00882                             msg+=(*i1).public_name;
00883                             msg+=eol;
00884                             msg.append(lang_get_string(1,lang,662)); // Message from owner:
00885                             msg+=eol;
00886                             msg+=filesys_build_getfile_message(*i2,(*i1).public_name,lang,eol);
00887                             n.message=msg;
00888                         }
00889                         if(n.message.length()) {
00890                             notify.push_back(n);
00891                         }
00892                         if(!secured && (*i2).secure) {
00893                             n.message="";
00894                             notify.push_back(n);
00895                             break;
00896                         }
00897                     }
00898                 }
00899             }
00900             if((*i2).notify_owner && (*i1).is_owner(user)) {
00901                 vector<s_event>::iterator i3;
00902                 for(i3=(*i1).events.begin(); i3!=(*i1).events.end(); i3++) {
00903                     if(!(*i3).owner_notified) {
00904                         vector<s_event>::iterator i4;
00905                         for(i4=(*i1).events.begin(); i4!=(*i1).events.end(); i4++) {
00906                             if((*i4).has_read && !(*i4).owner_notified) {
00907                                 (*i4).owner_notified=true;
00908 
00909                                 s_dcc_notify n;
00910                                 bool secure=(*i2).secure;
00911                                 n.notify_owner=!secure;
00912                                 n.secure_notify_owner=secure;
00913                                 n.name=(*i1).public_name;
00914                                 n.message=(*i2).notify_owner_message;
00915                                 if((*i1).file_type==ft_message && ((secured && (*i2).secure) || !(*i2).secure)) {
00916                                     string msg=lang_get_string(1,lang,663); // User
00917                                     msg+=" ";
00918                                     char tmp[64];
00919                                     strncpy(tmp,(*i4).user_name.c_str(),sizeof(tmp));
00920                                     tmp[sizeof(tmp)-1]=0;
00921                                     msg+=tmp;
00922                                     msg+=" ";
00923                                     msg.append(lang_get_string(1,lang,664)); // has read your message with subject
00924                                     msg+=" ";
00925                                     strncpy(tmp,(*i1).public_name.c_str(),sizeof(tmp));
00926                                     tmp[sizeof(tmp)-1]=0;
00927                                     msg+=tmp;
00928                                     msg+=(string)"; ";
00929                                     msg.append(lang_get_string(1,lang,658)); // On
00930                                     msg+=" ";
00931                                     msg+=filesys_get_time_str((*i4).first);
00932                                     msg+=eol;
00933                                     n.message=msg;
00934                                 }
00935                                 if((*i1).file_type==ft_file && ((secured && (*i2).secure) || !(*i2).secure)) {
00936                                     string msg=n.message;
00937                                     if(!msg.empty())  {
00938                                         string m;
00939                                         {
00940                                             int i2=0;
00941                                             for(unsigned int i1=0; i1<msg.length(); i1++) {
00942                                                 if(msg[i1]=='\n')
00943                                                     i2=i1;
00944                                                 if(i1-i2>=128 && msg[i1]!='\n') {
00945                                                     m+=eol;
00946                                                     i2=i1;
00947                                                 }
00948                                                 m+=msg[i1];
00949                                             }
00950                                         }
00951                                         string m2;
00952                                         for(unsigned int i3=0; i3<m.length(); i3++) {
00953                                             if(i3+1<m.length() && m[i3]=='%' && m[i3+1]=='%') {
00954                                                 i3++;
00955                                                 m2+=(*i4).user_name;
00956                                                 continue;
00957                                             }
00958                                             if((i3+1<m.length() && m[i3]=='%' && m[i3+1]!='%') || (i3+1==m.length() && m[i3]=='%')) {
00959                                                 m2+=(*i1).public_name;
00960                                                 continue;
00961                                             }
00962                                             m2+=m[i3];
00963                                         }
00964                                         msg=m2;
00965                                     }
00966                                     if(!msg.empty() && msg[msg.length()-1]!=eol[eol.length()-1])
00967                                         msg+=eol;
00968                                     msg.append(lang_get_string(1,lang,658)); // On
00969                                     msg+=" ";
00970                                     msg+=filesys_get_time_str((*i4).first);
00971                                     msg+=eol;
00972                                     n.message=msg;
00973                                 }
00974                                 if(!secured && (*i2).secure) {
00975                                     n.message="";
00976                                     notify.push_back(n);
00977                                     break;
00978                                 }
00979                                 notify.push_back(n);
00980                             }
00981                         }
00982                     }
00983                 }
00984             }
00985         }
00986     }
00987 
00988     if(filesys_last_flush+60<time(NULL))
00989         filesys_flush();
00990 
00991     return !notify.empty();
00992 }
00993 
00994 
00995 /*!
00996     \brief Gets list of files for user from the filesystem
00997     \author VooDooMan
00998     \version 1
00999     \date 2004
01000     \param user User name from "logic.txt"
01001     \param files_ Returns list of files
01002     \param must_be_owner Set to true if we wish to get files that the user is owner of
01003     \return Returns true if any file was found
01004 */
01005 bool filesys_dcc_filelist(string user, vector<s_file>& files_, bool must_be_owner)
01006 {
01007     filesys_init();
01008 
01009     files_.clear();
01010 
01011     vector<s_file>::iterator i1;
01012     for(i1=files.begin(); i1!=files.end(); i1++) {
01013         vector<s_access>::iterator i2;
01014         for(i2=(*i1).access.begin(); i2!=(*i1).access.end(); i2++) {
01015             if(must_be_owner) {
01016                 if((*i2).owner && !(*i2).user_name.compare(user)) {
01017                     files_.push_back(*i1);
01018                     break;
01019                 }
01020             } else {
01021                 if((*i2).read && ((*i2).all_users || !(*i2).user_name.compare(user) || (*i2).also_unknown)) {
01022                     files_.push_back(*i1);
01023                     break;
01024                 }
01025             }
01026         }
01027     }
01028 
01029     return !files_.empty();
01030 }
01031 
01032 
01033 /*!
01034     \brief Gets file for user from the filesystem
01035     \author VooDooMan
01036     \version 1
01037     \date 2004
01038     \param user User name from "logic.txt"
01039     \param public_name Public name of the file
01040     \param file Returns file descriptor
01041     \return Returns true if file was found and user has access to it
01042 */
01043 bool filesys_dcc_get_file(string user, string public_name, s_file& file)
01044 {
01045     filesys_init();
01046 
01047     file.clear();
01048 
01049     bool got=false;
01050 
01051     vector<s_file>::iterator i1;
01052     for(i1=files.begin(); i1!=files.end(); i1++) {
01053         if((*i1).public_name.compare(public_name))
01054             continue;
01055         if((*i1).expired)
01056             continue;
01057         vector<s_access>::iterator i2;
01058         for(i2=(*i1).access.begin(); i2!=(*i1).access.end(); i2++) {
01059             if((*i2).owner && ((*i2).all_users || !(*i2).user_name.compare(user))) {
01060                 file=*i1;
01061                 got=true;
01062                 break;
01063             }
01064         }
01065         if(got)
01066             break;
01067     }
01068 
01069     return got;
01070 }
01071 
01072 /*!
01073     \brief Sets new file attributes
01074     \author VooDooMan
01075     \version 1
01076     \date 2004
01077     \param user User name from "logic.txt"
01078     \param file File descriptor
01079     \param forced_secure Returns true if file were forced as SECUREd, due to excess in long notification messages
01080     \return Returns true if file was found and user has access to it
01081 */
01082 bool filesys_dcc_set_file_attrs(string user, s_file& file, bool& forced_secure)
01083 {
01084     filesys_init();
01085 
01086     bool ok=false;
01087 
01088     vector<s_file>::iterator i1;
01089     for(i1=files.begin(); i1!=files.end(); i1++) {
01090         if((*i1).public_name.compare(file.public_name))
01091             continue;
01092         (*i1).expiration=file.expiration;
01093         vector<s_access>::iterator i2;
01094         for(i2=(*i1).access.begin(); i2!=(*i1).access.end(); i2++) {
01095             if((*i2).owner && ((*i2).all_users || !(*i2).user_name.compare(user))) {
01096                 ok=true;
01097                 break;
01098             }
01099         }
01100         if(ok) {
01101             files.erase(i1);
01102 
01103             forced_secure=false;
01104 
01105             vector<s_access>::iterator iii;
01106             for(iii=file.access.begin(); iii!=file.access.end(); iii++)
01107                 for(int i1=0; i1<2; i1++) {
01108                     if(forced_secure)
01109                         break;
01110                     string content;
01111                     if(i1==0)
01112                         content=(*iii).notify_owner_message;
01113                     if(i1==1)
01114                         content=(*iii).notify_user_message;
01115                     unsigned int ii, i2, i3;
01116 
01117                     i2=1;
01118                     i3=0;
01119                     for(ii=0; ii<content.length(); ii++) {
01120                         if(content[ii]=='\n') {
01121                             i2++;
01122                             i3=0;
01123                         }
01124                         i3++;
01125                         if(i3>=128) {
01126                             i2++;
01127                             i3=0;
01128                         }
01129                     }
01130                     if(i2>(unsigned)atol(conf_getvar("msg_force_secure_lines").c_str())) {
01131                         vector<s_access>::iterator i1;
01132                         for(i1=file.access.begin(); i1!=file.access.end(); i1++)
01133                             (*i1).secure=true;
01134                         forced_secure=true;
01135                     }
01136                 }
01137 
01138             files.push_back(file);
01139             break;
01140         }
01141     }
01142 
01143     if(filesys_last_flush+60<time(NULL))
01144         filesys_flush();
01145 
01146     return ok;
01147 }
01148 
01149 /*!
01150     \brief Drops/clears notifications about new object in the filesystem
01151     \author VooDooMan
01152     \version 1
01153     \date 2004
01154     \param user User name from "logic.txt"
01155     \param only_non_secure Set to true if client is NOT connected via DCC CHAT or telnet (has NOT been authentificated)
01156 */
01157 void filesys_dcc_drop_notifies(string user, bool only_non_secure)
01158 {
01159     filesys_init();
01160 
01161     {
01162         // Check: do NOT drop notify for unknown user!!!
01163         s_user u;
01164         vector<s_channel> chs;
01165         logic_partyline_get_user(user,u,chs);
01166         if(u.host_unknown)
01167             return;
01168     }
01169 
01170     vector<s_file>::iterator i1;
01171     for(i1=files.begin(); i1!=files.end(); i1++) {
01172         vector<s_access>::iterator i2;
01173         for(i2=(*i1).access.begin(); i2!=(*i1).access.end(); i2++) {
01174             if((*i2).all_users || !(*i2).user_name.compare(user)) {
01175                 if((*i2).notify_user && ((only_non_secure && !(*i2).secure) || !only_non_secure)) {
01176                     bool got=false;
01177                     vector<s_event>::iterator i3;
01178                     for(i3=(*i1).events.begin(); i3!=(*i1).events.end(); i3++) {
01179                         if(!(*i3).has_read && !(*i3).user_name.compare(user)) {
01180                             (*i3).user_notified=true;
01181                             got=true;
01182                         }
01183                     }
01184                     if(!got) {
01185                         s_event e;
01186                         e.has_read=false;
01187                         e.owner_notified=false;
01188                         e.user_name=user;
01189                         e.user_notified=true;
01190                         e.first=time(NULL);
01191                         (*i1).events.push_back(e);
01192                     }
01193                 }
01194                 /*if(((*i2).notify_owner && ((only_non_secure && !(*i2).secure) || !only_non_secure))) {
01195                     vector<s_event>::iterator i3;
01196                     for(i3=(*i1).events.begin(); i3!=(*i1).events.end(); i3++) {
01197                         if(!(*i3).owner_notified && (*i2).owner && !(*i2).user_name) {
01198                             (*i3).owner_notified=true;
01199                         }
01200                     }
01201                 }*/
01202             }
01203         }
01204     }
01205 
01206     if(filesys_last_flush+60<time(NULL))
01207         filesys_flush();
01208 }
01209 
01210 /*!
01211     \brief Adds a message to the filesystem
01212     \author VooDooMan
01213     \version 1
01214     \date 2004
01215     \param from User name from "logic.txt"
01216     \param msg File/message descriptor
01217     \param content Message text
01218     \param force_secure Returns true if SECURE flag was explicitly set (for case that message is too long - flood protection)
01219     \return Returns internal name of file
01220 */
01221 string filesys_dcc_add_message(string from, s_file& msg, string content, bool& force_secure)
01222 {
01223     filesys_init();
01224 
01225     force_secure=false;
01226 
01227     unsigned int ii, i2, i3;
01228 
01229     i2=1;
01230     i3=0;
01231     for(ii=0; ii<content.length(); ii++) {
01232         if(content[ii]=='\n') {
01233             i2++;
01234             i3=0;
01235         }
01236         i3++;
01237         if(i3>=128) {
01238             i2++;
01239             i3=0;
01240         }
01241     }
01242     if(i2>(unsigned)atol(conf_getvar("msg_force_secure_lines").c_str())) {
01243         vector<s_access>::iterator i1;
01244         for(i1=msg.access.begin(); i1!=msg.access.end(); i1++)
01245             (*i1).secure=true;
01246         force_secure=true;
01247     }
01248 
01249     for(ii=0; ii<msg.public_name.length(); ii++)
01250         if(msg.public_name[ii]==' ')
01251             msg.public_name[ii]='_';
01252 
01253 again:
01254     vector<s_file>::iterator i1;
01255     for(i1=files.begin(); i1!=files.end(); i1++) {
01256         if(!(*i1).public_name.compare(msg.public_name)) {
01257             string n="_";
01258             n+=msg.public_name;
01259             msg.public_name=n;
01260             goto again;
01261         }
01262     }
01263 
01264     if(msg.public_name.length()>1024-128)
01265         return "";
01266 
01267     msg.file_type=ft_message;
01268     time(&msg.ftime);
01269 
01270     char t[128];
01271     time_t now=time(NULL);
01272     strcpy(t,ctime(&now));
01273 
01274     string internal=t;
01275     internal+="_msg_";
01276     internal+=from;
01277     for(ii=0; ii<internal.length(); ii++) {
01278         if(internal[ii]==' ' || internal[ii]=='\n')
01279             internal[ii]='_';
01280         bool okay=false;
01281         if(internal[ii]>='a' && internal[ii]<='z')
01282             okay=true;
01283         if(internal[ii]>='A' && internal[ii]<='Z')
01284             okay=true;
01285         if(internal[ii]>='0' && internal[ii]<='9')
01286             okay=true;
01287         if(!okay)
01288             internal[ii]='_';
01289     }
01290     internal+=".dat";
01291 
01292     msg.internal_name=internal;
01293     msg.published=true;
01294     msg.complete=true;
01295 
01296     string fn="." FILE_SLASH "filesystem" FILE_SLASH;
01297     fn+=internal;
01298 
01299     FILE* f=fopen(fn.c_str(),"wb");
01300     if(f) {
01301         fwrite(content.c_str(),1,content.length(),f);
01302         fclose(f);
01303 
01304         files.push_back(msg);
01305     }
01306 
01307     if(filesys_last_flush+60<time(NULL))
01308         filesys_flush();
01309 
01310     return internal;
01311 }
01312 
01313 /*!
01314     \brief Sets flag READ-"ed" for file from the filesystem
01315     \author VooDooMan
01316     \version 1
01317     \date 2004
01318     \param user Name of user from "logic.txt"
01319     \param public_name Public name of the file
01320 */
01321 void filesys_set_file_was_read(string user, string public_name)
01322 {
01323     filesys_init();
01324 
01325     vector<s_file>::iterator i1;
01326     for(i1=files.begin(); i1!=files.end(); i1++) {
01327         if(!(*i1).public_name.compare(public_name)) {
01328             vector<s_access>::iterator i2;
01329             for(i2=(*i1).access.begin(); i2!=(*i1).access.end(); i2++) {
01330                 if(!(*i2).user_name.compare(user)) {
01331                     (*i2).read=true;
01332                 }
01333             }
01334             break;
01335         }
01336     }
01337 
01338     if(filesys_last_flush+60<time(NULL))
01339         filesys_flush();
01340 }
01341 
01342 /*!
01343     \brief Sets new attributes for file in the filesystem
01344     \author VooDooMan
01345     \version 1
01346     \date 2004
01347     \param file File descriptor
01348     \return Returns true if succeeded
01349 */
01350 bool filesys_dcc_set_file_attrs(s_file& file)
01351 {
01352     filesys_init();
01353 
01354     bool ok=false;
01355 
01356     vector<s_file>::iterator i1;
01357     for(i1=files.begin(); i1!=files.end(); i1++) {
01358         if((*i1).public_name.compare(file.public_name))
01359             continue;
01360         files.erase(i1);
01361         files.push_back(file);
01362         ok=true;
01363         break;
01364     }
01365 
01366     if(filesys_last_flush+60<time(NULL))
01367         filesys_flush();
01368 
01369     return ok;
01370 }
01371 
01372 /*!
01373     \brief Checks if the file in the filesystem can be resumed
01374     \author VooDooMan
01375     \version 1
01376     \date 2004
01377     \param user User from logic.txt who requests for resume
01378     \param file_name Public name of file
01379     \param got_bytes Returns (if succeeded) size of file in bytes that actually file has (if function returns false, this argument is undefined)
01380     \return Returns true if okay to resume
01381 */
01382 // returns true for resume
01383 bool filesys_dcc_check_for_resume(string user, string file_name, size_t& got_bytes)
01384 {
01385     filesys_init();
01386 
01387     vector<s_file>::iterator i1;
01388     for(i1=files.begin(); i1!=files.end(); i1++) {
01389         if((*i1).file_type!=ft_file || (*i1).sender_file_name.compare(file_name) || (*i1).complete)
01390             continue;
01391         if((*i1).expired)
01392             continue;
01393         vector<s_access>::iterator i2;
01394         for(i2=(*i1).access.begin(); i2!=(*i1).access.end(); i2++) {
01395             if((*i2).owner && !user.compare((*i2).user_name)) {
01396                 char tmp[1024];
01397                 strcpy(tmp,"." FILE_SLASH "filesystem" FILE_SLASH);
01398                 strcat(tmp,(*i1).internal_name.c_str());
01399                 FILE* f=fopen(tmp,"rb");
01400                 if(!f)
01401                     return false;
01402                 fseek(f,0,SEEK_END);
01403                 got_bytes=ftell(f);
01404                 return true;
01405             }
01406         }
01407     }
01408     return false;
01409 }
01410 
01411 /*!
01412     \brief Retrieves informations about resume
01413     \author VooDooMan
01414     \version 1
01415     \date 2004
01416     \param user Name of user from logic.txt who requests resume
01417     \param file_name Public name of file
01418     \param internal_name Returns internal name of file in the filesystem
01419 */
01420 // returns an empty string in internal_name on error
01421 void filesys_dcc_get_resume_info(string user, string file_name, string& internal_name)
01422 {
01423     filesys_init();
01424 
01425     vector<s_file>::iterator i1;
01426     for(i1=files.begin(); i1!=files.end(); i1++) {
01427         if((*i1).file_type!=ft_file || (*i1).sender_file_name.compare(file_name) || (*i1).complete)
01428             continue;
01429         if((*i1).expired)
01430             continue;
01431         vector<s_access>::iterator i2;
01432         for(i2=(*i1).access.begin(); i2!=(*i1).access.end(); i2++) {
01433             if((*i2).owner && !user.compare((*i2).user_name)) {
01434                 internal_name=(*i1).internal_name;
01435                 return;
01436             }
01437         }
01438     }
01439     internal_name=""; // an error
01440 }
01441 
01442 /*!
01443     \brief Deletes the file from the filesystem
01444     \author VooDooMan
01445     \version 1
01446     \date 2004
01447     \param user Name of user from logic.txt who wants to delete the file
01448     \param file_name Public name of the file
01449     \retval 0 For successful delete
01450     \retval DCC_NO_SUCH_FILE The file is not present in the filesystem
01451     \retval DCC_ACCESS_DENIED Insufficient privileges for deletion
01452 */
01453 int filesys_dcc_delete(string user, string file_name)
01454 {
01455     filesys_init();
01456 
01457     bool del_it=false;
01458     bool got=false;
01459 
01460     vector<s_file>::iterator i1;
01461     for(i1=files.begin(); i1!=files.end(); i1++) {
01462         if((*i1).file_type!=ft_file || (*i1).public_name.compare(file_name))
01463             continue;
01464         got=true;
01465         vector<s_access>::iterator i2;
01466         for(i2=(*i1).access.begin(); i2!=(*i1).access.end(); i2++) {
01467             if((*i2).owner && !user.compare((*i2).user_name))
01468                 del_it=true;
01469             if((*i2).del && !user.compare((*i2).user_name))
01470                 del_it=true;
01471         }
01472         if(del_it)
01473             break;
01474     }
01475 
01476     if(del_it) {
01477         char tmp[1024];
01478         strcpy(tmp,"." FILE_SLASH "filesystem" FILE_SLASH);
01479         strcat(tmp,(*i1).internal_name.c_str());
01480         unlink(tmp);
01481         files.erase(i1);
01482     }
01483 
01484     if(filesys_last_flush+60<time(NULL))
01485         filesys_flush();
01486 
01487     if(!got)
01488         return DCC_NO_SUCH_FILE;
01489 
01490     return del_it?0:DCC_ACCESS_DENIED;
01491 }
01492 
01493 /*!
01494     \brief Check if the file with the same name already exists
01495     \author VooDooMan
01496     \version 1
01497     \date 2004
01498     \param public_name Original name of the file (aka public name in the filesystem terminology)
01499     \param user_name Owner of the file (from "logic.txt") / who is calling DCC SEND
01500     \retval 0 Okay, file doesn't exists
01501     \retval FILESYS_REPLACED File with such public name exists, argument owner matchs the OWNER, thus will be replaced, or continued due to resume
01502     \retval FILESYS_ALREADY_EXISTS File with such public name exists, argument owner DOESN'T matchs the OWNER, thus access is denied
01503 */
01504 int filesys_check_add_file_raw(string public_name, string user_name)
01505 {
01506     filesys_init();
01507 
01508     s_file f;
01509     //bool got_file=false;
01510 
01511     vector<s_file>::iterator i1;
01512     for(i1=files.begin(); i1!=files.end(); i1++) {
01513         if(!(*i1).public_name.compare(public_name)) {
01514             if((*i1).is_owner(user_name))
01515                 return FILESYS_REPLACED;
01516             else
01517                 return FILESYS_ALREADY_EXISTS;
01518         }
01519     }
01520 
01521     return 0;
01522 }
01523 
01524 /*!
01525     \brief Returns array of filesystem for an external script
01526     \author VooDooMan
01527     \version 1
01528     \date 2004
01529 */
01530 string filesys_get_script(string script_type)
01531 {
01532     filesys_init();
01533 
01534     string res="";
01535     if(!script_type.compare("php")) {
01536         res+="    $filesys_files=array();\n";
01537         vector<s_file>::iterator i1;
01538         for(i1=files.begin(); i1!=files.end(); i1++) {
01539             string x="    $x=array(); $x[\"type\"]=\"";
01540             switch((*i1).file_type) {
01541                 case ft_invalid:
01542                     x+="ft_invalid";
01543                     break;
01544                 case ft_file:
01545                     x+="ft_file";
01546                     break;
01547                 case ft_message:
01548                     x+="ft_message";
01549                     break;
01550                 default:
01551                     x+="ft_invalid";
01552                     break;
01553             }
01554             x+="\"; $x[\"InternalName\"]=\"";
01555             x+=(*i1).internal_name;
01556             x+="\"; $x[\"PublicName\"]=\"";
01557             x+=(*i1).public_name;
01558             x+="\"; $x[\"Time\"]=";
01559             char tmp[64];
01560             x+=ltoa((long)(*i1).ftime,tmp,10);
01561             x+="; $x[\"Published\"]=";
01562             x+=ltoa((*i1).published,tmp,10);
01563             x+="; $x[\"Complete\"]=";
01564             x+=ltoa((*i1).complete,tmp,10);
01565             x+="; $x[\"Expiration\"]=";
01566             x+=ltoa((long)(*i1).expiration,tmp,10);
01567 
01568             x+="; $x[\"access\"]=array(); $x[\"events\"]=array();\n";
01569 
01570             vector<s_access>::iterator i2;
01571             for(i2=(*i1).access.begin(); i2!=(*i1).access.end(); i2++) {
01572                 x+="      $xa=array(); ";
01573                 x+="$xa[\"AllUsers\"]=";
01574                 x+=ltoa((*i2).all_users,tmp,10);
01575                 x+="; $xa[\"UserName\"]=\"";
01576                 x+=(*i2).user_name;
01577                 x+="\"; $xa[\"Owner\"]=";
01578                 x+=ltoa((*i2).owner,tmp,10);
01579                 x+="; $xa[\"Read\"]=";
01580                 x+=ltoa((*i2).read,tmp,10);
01581                 x+="; $xa[\"Delete\"]=";
01582                 x+=ltoa((*i2).del,tmp,10);
01583                 x+="; $xa[\"NotifyOwner\"]=";
01584                 x+=ltoa((*i2).notify_owner,tmp,10);
01585                 x+="; $xa[\"NotifyUser\"]=";
01586                 x+=ltoa((*i2).notify_user,tmp,10);
01587                 x+="; $xa[\"Secure\"]=";
01588                 x+=ltoa((*i2).secure,tmp,10);
01589                 x+=";\n      $xa[\"AllOnChannel\"]=\"";
01590                 x+=(*i2).all_on_channel;
01591                 x+="\"; $xa[\"AlsoUnknown\"]=";
01592                 x+=ltoa((*i2).also_unknown,tmp,10);
01593                 x+="; $xa[\"NotifyOwnerMessage\"]=\"";
01594                 x+=logic_script_esc(script_type,(*i2).notify_owner_message);
01595                 x+="\"; $xa[\"NotifyUserMessage\"]=\"";
01596                 x+=logic_script_esc(script_type,(*i2).notify_user_message);
01597                 x+="\";\n";
01598                 x+="      array_push($x[\"access\"],$xa); unset($xa);\n";
01599             }
01600 
01601             vector<s_event>::iterator i3;
01602             for(i3=(*i1).events.begin(); i3!=(*i1).events.end(); i3++) {
01603                 x+="      $xe=array(); ";
01604                 x+="$xe[\"EventHasRead\"]=";
01605                 x+=ltoa((*i3).has_read,tmp,10);
01606                 x+="; $xe[\"EventOwnerNotified\"]=";
01607                 x+=ltoa((*i3).owner_notified,tmp,10);
01608                 x+="; $xe[\"EventUserName\"]=\"";
01609                 x+=(*i3).user_name;
01610                 x+="\"; $xe[\"UserNotified\"]=";
01611                 x+=ltoa((*i3).user_notified,tmp,10);
01612                 x+="; $xe[\"EventTimestamp\"]=";
01613                 x+=ltoa((long)(*i3).first,tmp,10);
01614                 x+=";\n      array_push($x[\"events\"],$xe); unset($xe);\n";
01615             }
01616 
01617             x+="    array_push($filesys_files,$x); unset($x);\n\n";
01618             res+=x;
01619         }
01620     }
01621     if(!script_type.compare("php_2")) {
01622         res+="    $filesys_files=array();\n";
01623         vector<s_file>::iterator i1;
01624         for(i1=files.begin(); i1!=files.end(); i1++) {
01625             string x="    $x=new c_filesys_object; $x->init(\"";
01626             switch((*i1).file_type) {
01627                 case ft_invalid:
01628                     x+="ft_invalid";
01629                     break;
01630                 case ft_file:
01631                     x+="ft_file";
01632                     break;
01633                 case ft_message:
01634                     x+="ft_message";
01635                     break;
01636                 default:
01637                     x+="ft_invalid";
01638                     break;
01639             }
01640             x+="\",\"";
01641             x+=(*i1).internal_name;
01642             x+="\",\"";
01643             x+=(*i1).public_name;
01644             x+="\",";
01645             char tmp[64];
01646             x+=ltoa((long)(*i1).ftime,tmp,10);
01647             x+=",";
01648             x+=(*i1).published?"TRUE":"FALSE";
01649             x+=",";
01650             x+=(*i1).complete?"TRUE":"FALSE";
01651             x+=",";
01652             x+=ltoa((long)(*i1).expiration,tmp,10);
01653             x+=");\n";
01654 
01655             vector<s_access>::iterator i2;
01656             for(i2=(*i1).access.begin(); i2!=(*i1).access.end(); i2++) {
01657                 x+="    $access=new c_filesys_access; $access->init(";
01658 
01659                 x+=(*i2).all_users?"TRUE":"FALSE";
01660                 x+=",\"";
01661                 x+=(*i2).user_name;
01662                 x+="\",";
01663                 x+=(*i2).owner?"TRUE":"FALSE";
01664                 x+=",";
01665                 x+=(*i2).read?"TRUE":"FALSE";
01666                 x+=",";
01667                 x+=(*i2).del?"TRUE":"FALSE";
01668                 x+=",";
01669                 x+=(*i2).notify_owner?"TRUE":"FALSE";
01670                 x+=",";
01671                 x+=(*i2).notify_user?"TRUE":"FALSE";
01672                 x+=",";
01673                 x+=(*i2).secure?"TRUE":"FALSE";
01674                 x+=",\"";
01675                 x+=(*i2).all_on_channel;
01676                 x+="\",";
01677                 x+=(*i2).also_unknown?"TRUE":"FALSE";
01678                 x+=",\"";
01679                 x+=logic_script_esc(script_type,(*i2).notify_owner_message);
01680                 x+="\",\"";
01681                 x+=logic_script_esc(script_type,(*i2).notify_user_message);
01682                 x+="\");\n";
01683                 x+="    $x->add_access($access); unset($access);\n";
01684             }
01685 
01686             vector<s_event>::iterator i3;
01687             for(i3=(*i1).events.begin(); i3!=(*i1).events.end(); i3++) {
01688                 x+="    $event=new c_filesys_event; $event->init(";
01689                 x+=(*i3).has_read?"TRUE":"FALSE";
01690                 x+=",";
01691                 x+=(*i3).owner_notified?"TRUE":"FALSE";
01692                 x+=",\"";
01693                 x+=(*i3).user_name;
01694                 x+="\",";
01695                 x+=(*i3).user_notified?"TRUE":"FALSE";
01696                 x+=",";
01697                 x+=ltoa((long)(*i3).first,tmp,10);
01698                 x+=");\n    $x->add_event($event); unset($event);\n";
01699             }
01700 
01701             x+="    $filesys_files[\"";
01702             x+=(*i1).internal_name;
01703             x+="\"]=$x; unset($x);\n\n";
01704             res+=x;
01705         }
01706     }
01707     return res;
01708 }
01709 
01710 /*!
01711     \brief Gets file from the filesystem
01712     \author VooDooMan
01713     \version 1
01714     \date 2005
01715     \param internal_name Internal name of the file
01716     \param file Returns file descriptor
01717     \return Returns true if file was found
01718 */
01719 bool filesys_logic_get_file(string internal_name, s_file& file)
01720 {
01721     filesys_init();
01722 
01723     file.clear();
01724 
01725     bool got=false;
01726 
01727     vector<s_file>::iterator i1;
01728     for(i1=files.begin(); i1!=files.end(); i1++) {
01729         if((*i1).internal_name.compare(internal_name))
01730             continue;
01731         if((*i1).expired)
01732             continue;
01733         file=*i1;
01734         got=true;
01735         break;
01736     }
01737 
01738     return got;
01739 }
01740 
01741 /*!
01742     \brief Sets file attributes for the file in filesystem
01743     \author VooDooMan
01744     \version 1
01745     \date 2005
01746     \param internal_name Internal name of the file
01747     \param file File descriptor to set
01748     \return Returns true if file was found
01749 */
01750 bool filesys_logic_set_file(string internal_name, s_file& file)
01751 {
01752     filesys_init();
01753 
01754     bool got=false;
01755 
01756     vector<s_file>::iterator i1;
01757     for(i1=files.begin(); i1!=files.end(); i1++) {
01758         if((*i1).internal_name.compare(internal_name))
01759             continue;
01760         if((*i1).expired)
01761             continue;
01762         *i1=file;
01763         got=true;
01764         break;
01765     }
01766 
01767     return got;
01768 }
01769 

Generated on Sun Jul 10 03:22:52 2005 for VooDoo cIRCle by doxygen 1.4.3

Hosted by SourceForge.net Logo