Create a write lock for a text file

S

sesi

Guest
Hello all,

How to lock a text file from editing by opening it graphically.
I used ddLockPath(filpath) to lock the file and opened the text file
and I could edit the text file and save it.
How could I do this.
 
sesi wrote, on 11/24/09 08:03:
Hello all,

How to lock a text file from editing by opening it graphically.
I used ddLockPath(filpath) to lock the file and opened the text file
and I could edit the text file and save it.
How could I do this.
See:
http://groups.google.com/group/comp.cad.cadence/browse_frm/thread/29376b9309fd4ce3/eb831d628d23988c?lnk=gst&q=abOpenTextCellView#eb831d628d23988c

Regards,

Andrew.
 
Hi Andrew,

Yes I could Create a text cellview , I could write in to the file by
using its port.


But the problem is I want to lock this file from being edited
graphically.Still I could open the file graphically and edit the
information.
After Creating the Text file here "cv=abOpenTextCellView("mylib"
"mycell" "notes" "a")" , I am using fprintf(cv->port "Testing 123\n")
to write to the file and after completion of writing to the file I am
closing it abCloseTextCellView(cv) .
Now at this point I want to lock the file from being edited
Graphically , for this I used ddLockPath(filepath) ,but this is not
working.
 
sesi wrote, on 11/25/09 05:16:
Hi Andrew,

Yes I could Create a text cellview , I could write in to the file by
using its port.


But the problem is I want to lock this file from being edited
graphically.Still I could open the file graphically and edit the
information.
After Creating the Text file here "cv=abOpenTextCellView("mylib"
"mycell" "notes" "a")" , I am using fprintf(cv->port "Testing 123\n")
to write to the file and after completion of writing to the file I am
closing it abCloseTextCellView(cv) .
Now at this point I want to lock the file from being edited
Graphically , for this I used ddLockPath(filepath) ,but this is not
working.
Locking is used within the code I referenced.

Are you actually talking about Locking, or making it so that it's not editable?
Locking is to ensure that two people do not edit it at once - if you've closed
the text cellView, then the lock would be freed, and it would be OK for another
user to edit it (because it would no longer be locked).

So my guess is that you're talking about permissions rather than locking?
Perhaps you can clarify?

Regards,

Andrew.
 
Yes Andrew I am not talking about locking the file, What I want is
after writing the important info into the text file using printf(cv-
port "Testing 123\n") , I want to make it uneditable(So I have
written it write lock)
Simply Changing the permissions to read is not a good idea , because
the user itself is the owner of that textfile.He should be able to
edit the text file only by running the script and using the port to
write to the text file
and after closing the text file it should become uneditable(even for
the owner of the text file) i.e it should not be graphically editable.
I think this is a bit clear.How can I achieve this Andrew.
 
sesi wrote, on 11/26/09 04:43:
Yes Andrew I am not talking about locking the file, What I want is
after writing the important info into the text file using printf(cv-
port "Testing 123\n") , I want to make it uneditable(So I have
written it write lock)
Simply Changing the permissions to read is not a good idea , because
the user itself is the owner of that textfile.He should be able to
edit the text file only by running the script and using the port to
write to the text file
and after closing the text file it should become uneditable(even for
the owner of the text file) i.e it should not be graphically editable.
I think this is a bit clear.How can I achieve this Andrew.
There used to be an article that I wrote (nearly 11 years ago) on sourcelink,
but it has now gone (it was pretty old) which talked about using dd Triggers to
implement an access control mechanism. I think something similar is what you
need here.

This isn't quite what you want, but you may be able to adapt it to what you
want. Here's the example from that article:

=================================================================================
4.3.X had a fairly simple access control list mechanism, and generally expected
the UNIX permissions to be wide open. In 4.4.X, the permissions are entirely
UNIX based, but sometimes it may be useful to further restrict the access to
parts of a library further.

This example uses dd triggers to implement an access control mechanism which
enables you to define groups of people and restrict access to particular views
by group. This idea could also be implemented using TDM policies, but this
method will work whether you are using TDM or not.

The example will only work in IC442 QSR3 and later, because it uses the
PreAutoCheckout and PreObjAccess triggers.


The ACL code will make use of a file which is placed in the top level of a
library, called libACL.att. This file contains data to define some groups, and
then defines edit and read access control lists for several viewName patterns.

The following is an example of a libACL.att file. If the file is not present,
the library is assumed to be wide open (although it will still use the UNIX
permissions of course).

The access to the libACL.att file should be restricted (in UNIX), and probably a
user-interface could be developed to ease the task of editing it. However, the
format is quite simple and easy to understand, and so editing it in a text
editor should be sufficient.

/* libACL.att

Author A.D.Beckett
Group Custom IC, Cadence Design Systems Ltd.
Machine SUN
Date Dec 06, 1998
Modified
By

This contains a disembodied property list representing
this library's access control list information. There are
two slots in the DPL, groups and views. The "groups" slot has as its
value an assoc list of groups, each keyed by the name of
the group, and the remainder of the list a list of user names.
The "views" slot has a list of view name entries. Each of these is
of the form

(pattern
edit list_of_group_or_user_names
read list_of_group_or_user_names
)

The pattern is a regular expression; for example, "layout.*" matches
all view names beginning with "layout". The list of group or user names
may also be set to be the value t - which means that anything matches.

Only the first view name entry which matches the viewName is used for access
information; later view name entries are ignored. The order is top to bottom
in this file.

***************************************************

*/

(nil
groups (
; three groups of people
("Project Leaders" "andrew")
("Designers" "louis" "norman")
("Layouters" "robert" "lawrence")
)
views (
; layout views
("layout.*"
edit ("Project Leaders" "Layouters")
read ("Designers")
)
; schematic views - editable by proj leaders, designers and an
; extra user, robert.
("schematic"
edit ("Project Leaders" "Designers" "robert")
read ("Layouters")
)
; any other viewname is only editable by the proj leaders, but
; readable by anyone
(".*"
edit ("Project Leaders")
; t is a special value which means accessible by anyone
read t
)
)
)

The source code for the ACL system is shown below. Cut and paste this into a
file called ACL.il. It will then need to be loaded, and the function ACLinit()
invoked to initialize the system.

/* ACL.il

Author A.D.Beckett
Group Custom IC, Cadence Design Systems Ltd.
Machine SUN
Date Dec 06, 1998
Modified
By

Example code to demonstrate a simple access control list
mechanism using dd triggers in 4.4.X

Uses PreObjAccess and PreAutoCheckout triggers which are
available in IC443, but are also available in IC442 QSR3.

The user is determined from the USER environment variable.

The Access Control List file should be placed at the top level of
a library, and called libACL.att

See separate example of libACL.att.

After loading this file, call ACLinit() to initialize the system
and register all the triggers.

***************************************************

SCCS Info: @(#) ACL.il 12/07/98.10:58:01 1.1

*/

/*************************************************************************
* *
* ACLreadACLfile(fileName) *
* *
* Read the access control list file from the passed in filename. Doesn't *
* do any checking to see if the file exists. Returns the ACL dpl. *
* *
*************************************************************************/

procedure(ACLreadACLfile(fileName)
let((prt acl)
when(prt=infile(fileName)
while((acl=lineread(prt)) && acl==t t)
close(prt)
car(acl)
); when
); let
); procedure

/***************************************************************************
* *
* ACLreadLibACL(libName) *
* *
* Read the ACL file for the specified library, if it exists. The resulting *
* data is stored in the table. *
* *
***************************************************************************/

procedure(ACLreadLibACL(libName)
let((libObj fileName)
when(libObj=ddGetObj(libName)
sprintf(fileName "%s/libACL.att" libObj->readPath)
when( isFile(fileName)
ACLdatabase[libName]=ACLreadACLfile(fileName)
); when
); when
); let
); procedure

/**********************************************************************
* *
* ACLisUserNameInACL(userName acl groups) *
* *
* Check to see if the username is in the list of entries for *
* this access control list, either directly or as the result of being *
* in one of the groups. *
* *
**********************************************************************/

procedure(ACLisUserNameInACL(userName acl groups)
exists(entry acl
entry==userName ||
member(userName cdr(assoc(entry groups)))
) && t ; coerced to be t if true, rather than remainder of acl
); procedure

/***************************************************************************
* *
* ACLvalidateUser(libName viewName mode *
* @optional (userName getShellEnvVar("USER"))) *
* *
* For a named library and viewName, and access mode one of 'edit or 'read, *
* check to see whether the user is allowed that type of access based *
* on the access control list information stored in the libACL.att for *
* that library. This is the main validation function which is *
* called from the triggers. *
* *
***************************************************************************/

procedure(ACLvalidateUser(libName viewName mode
@optional (userName getShellEnvVar("USER")))
let((libACL viewDPL acl)
libACL=ACLdatabase[libName]
if(libACL
then
; find the matching view info
viewDPL=car(exists(dpl libACL->views
rexMatchp(sprintf(nil "^%s$" car(dpl)) viewName)
))
acl=get(viewDPL mode)
; t is a special value which means everyone
acl==t || ACLisUserNameInACL(userName acl libACL->groups)
else
; if no ACL data for this library, default is wide open
t
); if
); let
); procedure

/***************************************************************
* *
* ACLinit() *
* *
* Initialise the lookup table for the ACL info, and register *
* all the triggers. *
* *
***************************************************************/

procedure(ACLinit()
; database is going to be indexed by library name
ACLdatabase=makeTable("ACL data" nil)
ddRegTrigger("FirstAccessLib" 'ACLfirstAccessLibTrigger 1)
ddRegTrigger("PostUpdateLibList" 'ACLpostUpdateLibListTrigger 1)
; handle read access
ddRegTrigger("PreObjAccess" 'ACLpreObjAccessTrigger 1)
; handle edit access
ddRegTrigger("PreAutoCheckOut" 'ACLpreAutoCheckOutTrigger 1)
); procedure

/**************************************************************************
* *
* ACLfirstAccessLibTrigger(@optional libId) *
* The FirstAccessLib trigger is used to load the libACL.att file when the *
* library is first accessed (if it exists) *
* *
**************************************************************************/

procedure(ACLfirstAccessLibTrigger(@optional libId)
libId && errset(ACLreadLibACL(libId->name))
; make sure we return t - otherwise stops other FirstAccessLib triggers
; from running
t
); procedure

/*********************************************************************
* *
* ACLpostUpdateLibListTrigger(@rest args) *
* *
* The PostUpdateLibList trigger is used to reload all the libACL.att *
* files when the library list is updated. This means that when *
* File->Refresh is invoked, the ACLs will be reloaded from disk. *
* *
*********************************************************************/

procedure(ACLpostUpdateLibListTrigger(@rest args)
foreach(libId ddGetLibList()
libId && errset(ACLreadLibACL(libId->name))
)
; return t for good measure
t
); procedure

/***************************************************************
* *
* ACLpreObjAccessTrigger(@optional libName cellName viewName *
* fileName contextId mode) *
* *
* The PreObjAccess just checks that it's a cellView or one of *
* the files within the cellView that is being accessed, and *
* then sees whether the user has rights to open it in that *
* mode. Note that edit access implies read access. *
* *
***************************************************************/

procedure(ACLpreObjAccessTrigger(@optional libName cellName viewName
fileName contextId mode)
if( libName && cellName && viewName
then
if( ACLvalidateUser(libName viewName 'edit)||
(!mode||(stringp(mode) && substring(mode 1 1)=="r"))&&
ACLvalidateUser(libName viewName 'read)
then
; access is validated - return t
t
else
printf("ACL: You are not allowed to edit/read %s/%s/%s\n"
libName
cellName
viewName
)
; access is disallowed - return nil
nil
); if
else
; if not something we're interested in, validate the access
t
); if
); procedure

/***********************************************************************
* *
* ACLpreAutoCheckOutTrigger(@optional objList isBatch) *
* *
* The PreAutoCheckOut trigger is called prior to something be opened *
* for edit to check whether it needs checking out or not. This trigger *
* checks whether the user is allowed to open it for edit, and returns *
* a list of t's and nil's for each of the cellViews passed to indicate *
* whether "checkout" is allowed or not. *
* *
***********************************************************************/

procedure(ACLpreAutoCheckOutTrigger(@optional objList isBatch)
; generate a list of t's and nil's corresponding to the objList
; passed in
foreach(mapcar obj objList
if(obj->type=='ddViewType
then
if(ACLvalidateUser(obj->lib->name obj->name 'edit)
then
; "checkout" is validated
t
else
printf("ACL: You are not allowed to edit %s/%s/%s\n"
obj->lib->name
obj->cell->name
obj->name
)
; edit access not allowed - invalidate the checkout
nil
); if
else
; if it's an object we're not concerned with, allow access
t
)
); foreach
); procedure

The ACLinit function registers four triggers; FirstAccessLib, PostUpdateLibList,
PreObjAccess, and PreAutoCheckout.

The FirstAccessLib trigger is to load the libACL.att file if it exists, and
store the data in a data structure for use when a user's access needs to be
validated. The PostUpdateLibList is used so that this data will be refreshed if
the user does a File->Refresh in the CIW.

The PreObjAccess trigger is primarily for restricting read access to data,
although it is also used to prevent data from being created if the user is not
in the edit access control list for this view. If the user doesn't have access
privileges, then the trigger returns nil and the operation is aborted, giving a
message in the CIW. In this case, if the user has edit access, that also implies
read access.

The PreAutoCheckout trigger is invoked when something is attempted to be opened
for edit. In this case it is not necessarily going to checkout something because
we may not be under the control of a DM system, but the trigger may be used for
detecting edit access. Again, the trigger determines whether the user has edit
privileges for this viewname, and only allows the operation to proceed if they do.

Limitations and possible enhancements
=====================================

This example is intended as a means of preventing accidental access to data;
because it does not affect the Unix permissions of the files created in the
library, it does not prevent users from accessing the data through Unix. However
for most practical purposes it represents a workable system for providing some
simple extra access controls.

The code will work in a DM environment as well as in a non-DM environment.
However, the system as it stands does not prevent checkout of cellViews by users
who are not in the correct groups - but they would not be allowed to edit the
data in DFII once they had performed the checkout. Further triggers (such as on
Checkout) or policies within the DM system could be used to prevent the checkout
in the first place.

Another possible enhancement would be to limit deletion in DFII by using the
DeleteObj triggers. This could either use the existing edit permissions, or
could add another "delete" permission category.
 
sesi wrote, on 11/30/09 08:17:
Hi Andrew,

Thanks alot for this, seems great, What I understand from the above
code is that
I can set read or write permissions on specific users on specific view
names.
But I donot see any option to set the read or edit permissions based
on the "library" and "cell view" and "view " basis rather than only on
the view basis.
ex: lib: "Skill" cell : "Skill1" view : "layout".
Orelse I think I am wrong.
To execute this what I am doing is loaded the ACL.il and

executed


(nil
groups (
; three groups of people
("Project Leaders" "ssk")
("Designers" "qwe")
("Layouters" "e_jku")
)
views (
; layout views
("layout.*"
edit ("Project Leaders" "Layouters")
read ("Designers")
)
; schematic views - editable by proj leaders, designers and
an
; extra user, robert.
("schematic"
edit ("Project Leaders" "Designers" "e_pol")
read ("Layouters")
)
; any other viewname is only editable by the proj leaders,
but
; readable by anyone
(".*"
edit ("Project Leaders")
; t is a special value which means accessible by anyone
read t
)
)
)



this part of code here ssk , qwe , e_pol , e_jku are the user names.
After executing this part of code , I ran the function ACLinit() but
I got a return value as nil.
As I said, it's not exactly what you want. I posted the code to give you a
starting point - you'd need to modify it to suit your needs. The code is fairly
clear (I think), so you should be able to adapt it to your requirements.

Note that ACLinit() only registers the triggers - so I wouldn't worry too much
about the return value of ACLinit().

Regards,

Andrew.
 
sesi wrote, on 11/30/09 08:40:
Hi Andrew,

Thanks alot for this, seems great, What I understand from the above
code is that
I can set read or write permissions on specific users on specific view
names.
But I donot see any option to set the read or edit permissions based
on the "library" and "cell view" and "view " basis rather than only on
the view basis.
ex: lib: "Skill" cell : "Skill1" view : "layout".

By this method all the views named with layout will become read or
edit rather than a particular cell from a particular library.
How can I do this Andrew.
By modifying the code to suit your needs.

Regards,

Andrew.
 
Hi Andrew,

Thanks alot for this, seems great, What I understand from the above
code is that
I can set read or write permissions on specific users on specific view
names.
But I donot see any option to set the read or edit permissions based
on the "library" and "cell view" and "view " basis rather than only on
the view basis.
ex: lib: "Skill" cell : "Skill1" view : "layout".
Orelse I think I am wrong.
To execute this what I am doing is loaded the ACL.il and

executed


(nil
groups (
; three groups of people
("Project Leaders" "ssk")
("Designers" "qwe")
("Layouters" "e_jku")
)
views (
; layout views
("layout.*"
edit ("Project Leaders" "Layouters")
read ("Designers")
)
; schematic views - editable by proj leaders, designers and
an
; extra user, robert.
("schematic"
edit ("Project Leaders" "Designers" "e_pol")
read ("Layouters")
)
; any other viewname is only editable by the proj leaders,
but
; readable by anyone
(".*"
edit ("Project Leaders")
; t is a special value which means accessible by anyone
read t
)
)
)



this part of code here ssk , qwe , e_pol , e_jku are the user names.
After executing this part of code , I ran the function ACLinit() but
I got a return value as nil.
 
Hi Andrew,

Thanks alot for this, seems great, What I understand from the above
code is that
I can set read or write permissions on specific users on specific view
names.
But I donot see any option to set the read or edit permissions based
on the "library" and "cell view" and "view " basis rather than only on
the view basis.
ex: lib: "Skill" cell : "Skill1" view : "layout".

By this method all the views named with layout will become read or
edit rather than a particular cell from a particular library.
How can I do this Andrew.
 
Thanks Andrew surely I will work on this,
comments are clear in the script.
 

Welcome to EDABoard.com

Sponsor

Back
Top