/****************************************************************************** * TMBO.cpp - description * ------------------- * begin : 2005/04/20 * copyright : (C) 2005 by Harald K. Strack * copyright : (C) 2005 by Trymedia Inc. * email : hstrack@trymedia.com, strack@fhm.edu ****************************************************************************** * changes name date comment * hks 2005/05/24 Handlers for add, revert, edit added * hks 2005/05/25 Mask support added. Chmod(). * hks 2005/05/26 Extended interface for 2 vpathes and 2 pathes * (senseless) */ /* TMBO: Trymedia Busines Objects * This is the abstract base class for all Handlers (business objects). * * It is the central point to process data. For this it's interface * supports a linked list, which behaves more or less like a stack. * * Since there may only one handler per command, the TMBOs are implemented * as singletons. You may call TMBO::Create at any point in your * program flow and will be able to access the same instance of your handler. * * Derived classes have to implement: * * Run() - Algorithm which performs any operations. * GetDescription () - Returns a string which describes the class. * * * TMBO::Create () - Adding a creational statement to this factory method. * TMBOType - Creating a new Handlertype (enum) * */ #include "TMBO.h" //Subclasses #include "TMBOSubmit.h" #include "TMBOSync.h" #include "TMBOEdit.h" #include "TMBOAdd.h" #include "TMBORevert.h" #include "TMBOInteg.h" #include "TMTools.h" //Singleton TMBO * TMBO::_self = NULL; TMBO::TMBO() { head=NULL; cl = NULL; tmpNode = NULL; data=this; tools=TMTools::Instance(); } TMBO::~TMBO() { //Free linked list. FreeList(); } /* Do nothing on chmod - may be overwritten in subclasses */ void TMBO::Chmod (TMFSHook * f, Error * e) { } /* Factory method for singleton. You have to add here addition if-statements * if you add new subclasses (Handlers). */ TMBO * TMBO::Create( ClientApi * ca, TMBOType tt = STANDARD ) { if (_self == 0) { if (tt == SUBMIT_HANDLER) _self = new TMBOSubmit(); else if (tt == SYNC_HANDLER) _self = new TMBOSync(); else if (tt == EDIT_HANDLER) _self = new TMBOEdit(); else if (tt == REVERT_HANDLER) _self = new TMBORevert(); else if (tt == ADD_HANDLER) _self = new TMBOAdd(); else if (tt == INTEG_HANDLER) _self = new TMBOInteg(); else _self = NULL; /*if (_self == NULL) { cerr << "TRYMEDIA HANDLER FACTORY: Could not initalize demanded handler. Giving up." << endl; exit (1); }*/ if (_self == NULL) return NULL; _self->SetClientApi (ca); _self->type = tt; } return _self; } void TMBO::SetClientApi(ClientApi * ca) { this->ca = ca; } /* Adds a FileSys->path pointer to the internal linked list * Usefull for filesystem hooks. */ void TMBO::SetFileSys (FileSys * fs) { PushNode(); SetPath (GetHeadNode(),&fs->Path()); } /* Interface to the linked list (Stack) * * Usage: * 1 tmp = PushNode(); * 2 SetPerm (tmp, data) or similar * * and so on... * n PopNode(); * */ /* Loads via p4 fstat -Oa all attributes for a versioned file from p4d */ int TMBO::RecieveP4Attributes (StrBuf * vpath) { //Command for getting attributes (see p4 help undoc for details) char * p4Command [4]; p4Command [0] = "fstat"; p4Command [1] = "-Oa"; p4Command [2] = vpath->Text(); //Check for existing connection... if (ca->Dropped()) { cerr << "Error: " << GetDescription ().Text() << " : Connection dropped. " << vpath->Text() << " - Cannot get attributes. " << endl; return TM_CONNECTION_ERROR; } //Load attributes from p4d TMClientUser * tcu = new TMClientUser(ca); //The TMClientUser needs a reference to this object. tcu->SetTMBO( this->type ); //Run the command ca->SetArgv(2, p4Command+1); ca->Run( p4Command[0], tcu ); //Check for existing connection... if (ca->Dropped()) { cerr << "Error: " << GetDescription ().Text() << " : Connection dropped. " << vpath->Text() << " - Error getting attributes. " << endl; //Clean it up delete tcu; return TM_CONNECTION_ERROR; } //Clean it up delete tcu; return TM_SUCCESS; } /* Sets a Attribute in p4d */ int TMBO::SendP4Attribute (StrBuf * path, StrBuf * attr, StrBuf * value) { //Check for existing connection... if (ca->Dropped()) { cerr << "Error: " << GetDescription ().Text() << " : Connection dropped. " << path->Text() << " - Cannot set attribute: " << attr->Text() << endl; return TM_CONNECTION_ERROR; } char * p4Command [7]; //Command for setting attributes (see p4 help undoc for details) p4Command [0] = "attribute"; p4Command [1] = "-n"; p4Command [3] = "-v"; p4Command [5] = "-f"; p4Command [6] = path->Text(); p4Command [4] = value->Text(); p4Command [2] = attr->Text(); //Initialise standard clientuser ClientUser * tcu = new ClientUser(); //Run command ca->SetArgv(6, p4Command+1); ca->Run( p4Command[0], tcu ); //Check for existing connection... if (ca->Dropped()) { cerr << "Error: " << GetDescription ().Text() << " : Connection dropped. " << path->Text() << " - Error setting attribute: " << attr->Text() << endl; //clean up clientUser delete tcu; return TM_CONNECTION_ERROR; } //clean up clientUser delete tcu; return TM_SUCCESS; } //Sets file permissions fileNode * TMBO::SetPerm (fileNode * node, StrPtr * perm) { if (perm != NULL) { StrBuf * sb = new StrBuf; sb->Set(perm->Text()); node->data->perm = sb; return node; } else { return NULL; } } //Sets file permissions fileNode * TMBO::SetUid (fileNode * node, StrPtr * uid) { if (uid != NULL) { StrBuf * sb = new StrBuf; sb->Set(uid->Text()); node->data->uid = sb; return node; } else { return NULL; } } //Sets file permissions fileNode * TMBO::SetGid (fileNode * node, StrPtr * gid) { if (gid != NULL) { StrBuf * sb = new StrBuf; sb->Set(gid->Text()); node->data->gid = sb; return node; } else { return NULL; } } /* Sets file's versioned path * like: Makefile#2 (Revision) * or Makefile@2031 (Changelist) */ fileNode * TMBO::SetVPath (fileNode * node, StrPtr * vpath) { if (vpath != NULL) { StrBuf * sb = new StrBuf; sb->Set(vpath->Text()); node->data->vpath = sb; return node; } else { return NULL; } } /* Sets file's unix filesystem path */ fileNode * TMBO::SetPath (fileNode * node, StrPtr * path) { if (path != NULL) { StrBuf * sb = new StrBuf; sb->Set(path->Text()); node->data->path = sb; return node; } else { return NULL; } } /* Sets file's versioned path * like: Makefile#2 (Revision) * or Makefile@2031 (Changelist) * * Is senseless used in ap4 integrate. */ fileNode * TMBO::SetVNPath (fileNode * node, StrPtr * vnpath) { if (vnpath != NULL) { StrBuf * sb = new StrBuf; sb->Set(vnpath->Text()); node->data->vnpath = sb; return node; } else { return NULL; } } /* Sets file's unix filesystem path * Is senseless used in ap4 integrate * Oh no, is not used at all. Hm.*/ fileNode * TMBO::SetNPath (fileNode * node, StrPtr * npath) { if (npath != NULL) { StrBuf * sb = new StrBuf; sb->Set(npath->Text()); node->data->npath = sb; return node; } else { return NULL; } } /* Deletes top node of the stack */ void TMBO::PopNode () { fileNode * tmp;; //Take care to delete EVERYTHING //cout << head->data->vpath->Text() << endl; if (head == NULL) return; if (head->data == NULL) return; if (head->data->path != NULL) delete head->data->path; if (head->data->vpath != NULL) delete head->data->vpath; if (head->data->npath != NULL) delete head->data->npath; if (head->data->vnpath != NULL) delete head->data->vnpath; if (head->data->perm != NULL) delete head->data->perm; if (head->data->uid != NULL) delete head->data->uid; if (head->data->gid != NULL) delete head->data->gid; delete head->data; tmp = head->next; delete head; head = tmp; } /* Adds a new top node to the stack */ fileNode * TMBO::PushNode () { fileNode * tmp = new fileNode; tmp->data = new fileData; tmp->data->perm=NULL; tmp->data->path=NULL; tmp->data->vnpath=NULL; tmp->data->npath=NULL; tmp->data->vpath=NULL; tmp->data->uid=NULL; tmp->data->gid=NULL; tmp->next = this->head; this->head = tmp; return tmp; } /* Deletes the whole list */ void TMBO::FreeList () { fileNode * tmp;; while (head != NULL) { PopNode(); } } /* Sets a changelist number to the handler */ void TMBO::SetChangeList(StrPtr * pcl) { if (pcl != NULL) { this->cl = new StrBuf; this->cl->Set(pcl->Text()); } } /* Sets an error message to Error * e. * Behaves like printf(). */ void TMBO::SetErrorMsg (Error * e, ErrorSeverity s, const char *fmt, ...) { char buf[1024]; va_list ap; va_start(ap, fmt); vsprintf (buf, fmt, ap); va_end(ap); cerr << buf << endl; e->Set (s,buf); //FIXME: closeme when last revision is closed.. }
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#7 | 5069 | harald_strack |
ADDITIONAL command parameter handling introduced. ap4 sync -n is handled. Usually there is no need for handling any command specific parameters. Tests improved. |
||
#6 | 5056 | harald_strack |
Directory support. Serious bug concerned to not unzipped binaries removed. Some other small bugfixes. |
||
#5 | 4980 | harald_strack |
Since I am maintaining the stuff in a local repository, I did some copy errors in the last revisions. Fixed. |
||
#4 | 4978 | harald_strack |
ap4 integrate implemented. Octal format is now used to save permissions. NOT backwards compatible anymore!!! |
||
#3 | 4975 | harald_strack |
Permissions are now masked to 555, so no write is possible. If you edit the Makefile and give the parameter -DFULL_PERMS, you have the old behaviour. Bugfix in ap4 revert: Edited and changed files were not reverted correctly. |
||
#2 | 4952 | harald_strack | Logical error, which caused seg.fault corrected. | ||
#1 | 4948 | harald_strack | Initial revision. |