1 /****^  ***********************************************************
  2         *                                                         *
  3         * Copyright, (C) Honeywell Bull Inc., 1987                *
  4         *                                                         *
  5         * Copyright, (C) Honeywell Information Systems Inc., 1982 *
  6         *                                                         *
  7         * Copyright (c) 1972 by Massachusetts Institute of        *
  8         * Technology and Honeywell Information Systems, Inc.      *
  9         *                                                         *
 10         *********************************************************** */
 11 
 12 
 13 /* format: style4,delnl,insnl,indattr,ifthen,dclind10 */
 14 rollback:
 15      proc (p_journal_control_block_ptr, p_code);
 16 
 17 /* Walk through the journal, starting at the latest entry and following the
 18    previous pointers.  At each entry, undo what that entry did.
 19 
 20    Written  by  Lindsey Spratt 08/06/79
 21    Modified by Chris Jones 02/14/85 to use privileges and to clean up properly.
 22 */
 23 /* Parameter */
 24 
 25 dcl       p_journal_control_block_ptr
 26                                  ptr;
 27 dcl       p_code                 fixed bin (35);
 28 
 29 
 30 /* Automatic */
 31 
 32 dcl       privileges_string      bit (36) aligned;
 33 dcl       scratch_area_ptr       ptr;
 34 
 35 /* Based */
 36 
 37 dcl       scratch_area           area (4096) based (scratch_area_ptr);
 38 
 39 /* Builtin */
 40 
 41 dcl       addr                   builtin;
 42 dcl       length                 builtin;
 43 dcl       null                   builtin;
 44 
 45 /* Condition */
 46 
 47 dcl       cleanup                condition;
 48 
 49 /* Entry */
 50 
 51 dcl       get_system_free_area_  entry returns (ptr);
 52 dcl       rcprm_registry_util_$turn_off_privs
 53                                  entry (bit (36) aligned);
 54 dcl       rcprm_registry_util_$turn_on_privs
 55                                  entry (bit (36) aligned);
 56 
 57 /* External */
 58 
 59 dcl       error_table_$locked_by_this_process
 60                                  fixed bin (35) ext;
 61 ^L
 62           journal_control_block_ptr = p_journal_control_block_ptr;
 63           scratch_area_ptr = get_system_free_area_ ();
 64 
 65           journal_entry_ptr = journal_control_block.latest_entry_ptr;
 66           ak_info_ptr, gk_info_ptr, rs_info_ptr = null ();
 67           privileges_string = ""b;
 68           on cleanup call clean_up;
 69 
 70           call rcprm_registry_util_$turn_on_privs (privileges_string);
 71           do while (journal_entry_ptr ^= null);
 72 
 73                goto ENTRY_TYPE (journal_entry.type);
 74 
 75 ENTRY_TYPE (1):                                             /* RS_LOCK */
 76                allocate rs_info in (scratch_area);
 77                rs_info.version = rs_info_version_2;
 78                rs_info.locate_sw = "1"b;
 79                rs_info.descriptor = journal_entry.descriptor;
 80 
 81                call iox_$control (journal_control_block.vfile_iocb_ptr, "record_status", rs_info_ptr, p_code);
 82                if p_code ^= 0 & p_code ^= error_table_$locked_by_this_process then do;
 83                     call clean_up;
 84                     return;
 85                end;
 86 
 87                call iox_$rewrite_record (journal_control_block.vfile_iocb_ptr, addr (journal_entry.rec_str),
 88                     journal_entry.rec_len, p_code);
 89                if p_code ^= 0 & p_code ^= error_table_$locked_by_this_process then do;
 90                     call clean_up;
 91                     return;
 92                end;
 93                rs_info.lock_sw = "0"b;
 94                rs_info.unlock_sw = "1"b;
 95 
 96                rs_info.locate_sw = "0"b;
 97                rs_info.inc_ref_count = "0"b;
 98                rs_info.dec_ref_count = "0"b;
 99                call iox_$control (journal_control_block.vfile_iocb_ptr, "record_status", rs_info_ptr, p_code);
100 
101                if p_code ^= 0 & p_code ^= error_table_$locked_by_this_process then do;
102                     call clean_up;
103                     return;
104                end;
105 
106                free rs_info;
107                goto NEXT;
108 
109 ENTRY_TYPE (2):                                             /* write_record */
110                gk_key_len = journal_entry.key_len;
111                alloc gk_info in (scratch_area);
112                gk_info.key = journal_entry.key_str;
113                gk_info.descrip = journal_entry.descriptor;
114                gk_info.input_desc = "1"b;
115                gk_info.input_key = "1"b;
116                gk_info.rel_type = 0;
117                gk_info.head_size = journal_entry.key_len;
118                gk_info.reset_pos = "0"b;
119                gk_info.version = gk_info_version_0;
120 
121                call iox_$control (journal_control_block.vfile_iocb_ptr, "get_key", gk_info_ptr, p_code);
122                if p_code ^= 0 & p_code ^= error_table_$locked_by_this_process then do;
123                     call clean_up;
124                     return;
125                end;
126 
127                call iox_$delete_record (journal_control_block.vfile_iocb_ptr, p_code);
128                if p_code ^= 0 & p_code ^= error_table_$locked_by_this_process then do;
129                     call clean_up;
130                     return;
131                end;
132 
133                free gk_info;
134                goto NEXT;
135 
136 ENTRY_TYPE (3):                                             /* delete_record */
137                ak_key_len = journal_entry.key_len;
138                alloc ak_info in (scratch_area);
139 
140                ak_info.input_key = "1"b;
141                ak_info.input_desc = "1"b;
142                ak_info.descrip = journal_entry.descriptor;
143                ak_info.key = journal_entry.key_str;
144 
145                call iox_$control (journal_control_block.vfile_iocb_ptr, "add_key", ak_info_ptr, p_code);
146                if p_code ^= 0 & p_code ^= error_table_$locked_by_this_process then do;
147                     call clean_up;
148                     return;
149                end;
150 
151                free ak_info;
152                alloc rs_info in (scratch_area);
153                rs_info.locate_sw = "1"b;
154                rs_info.dec_ref_count = "1"b;
155                rs_info.descriptor = journal_entry.descriptor;
156                rs_info.version = rs_info_version_2;
157                call iox_$control (journal_control_block.vfile_iocb_ptr, "record_status", rs_info_ptr, p_code);
158                if p_code ^= 0 & p_code ^= error_table_$locked_by_this_process then do;
159                     call clean_up;
160                     return;
161                end;
162                free rs_info;
163                goto NEXT;
164 
165 
166 ENTRY_TYPE (4):                                             /* add_key */
167                ak_key_len = journal_entry.key_len;
168                alloc ak_info in (scratch_area);
169                ak_info.input_desc = "1"b;
170                ak_info.input_key = "1"b;
171                ak_info.descrip = journal_entry.descriptor;
172                ak_info.key = journal_entry.key_str;
173 
174                call iox_$control (journal_control_block.vfile_iocb_ptr, "delete_key", ak_info_ptr, p_code);
175                if p_code ^= 0 & p_code ^= error_table_$locked_by_this_process then do;
176                     call clean_up;
177                     return;
178                end;
179 
180                free ak_info;
181                goto NEXT;
182 
183 
184 ENTRY_TYPE (5):                                             /* delete_key */
185                ak_key_len = journal_entry.key_len;
186                alloc ak_info in (scratch_area);
187                ak_info.input_desc = "1"b;
188                ak_info.input_key = "1"b;
189                ak_info.descrip = journal_entry.descriptor;
190                ak_info.key = journal_entry.key_str;
191 
192                call iox_$control (journal_control_block.vfile_iocb_ptr, "add_key", ak_info_ptr, p_code);
193                if p_code ^= 0 & p_code ^= error_table_$locked_by_this_process then do;
194                     call clean_up;
195                     return;
196                end;
197 
198                free ak_info;
199                goto NEXT;
200 
201 ENTRY_TYPE (6):                                             /* RS_COUNT */
202                allocate rs_info in (scratch_area);
203 
204                rs_info.version = rs_info_version_2;
205                rs_info.locate_sw = "1"b;
206                rs_info.descriptor = journal_entry.descriptor;
207                rs_info.inc_ref_count = journal_entry.dec_ref_count;
208                rs_info.dec_ref_count = journal_entry.inc_ref_count;
209 
210                call iox_$control (journal_control_block.vfile_iocb_ptr, "record_status", rs_info_ptr, p_code);
211                free rs_info;
212                if p_code ^= 0 & p_code ^= error_table_$locked_by_this_process then do;
213                     call clean_up;
214                     return;
215                end;
216 
217                goto NEXT;
218 
219 ENTRY_TYPE (7):                                             /* RS_LOCK_COUNT */
220                allocate rs_info in (scratch_area);
221 
222                rs_info.version = rs_info_version_2;
223                rs_info.locate_sw = "1"b;
224                rs_info.descriptor = journal_entry.descriptor;
225                rs_info.inc_ref_count = journal_entry.dec_ref_count;
226                rs_info.dec_ref_count = journal_entry.inc_ref_count;
227 
228                call iox_$control (journal_control_block.vfile_iocb_ptr, "record_status", rs_info_ptr, p_code);
229                if p_code ^= 0 & p_code ^= error_table_$locked_by_this_process then do;
230                     call clean_up;
231                     return;
232                end;
233 
234                call iox_$rewrite_record (journal_control_block.vfile_iocb_ptr, addr (journal_entry.rec_str),
235                     length (journal_entry.rec_str), p_code);
236                if p_code ^= 0 & p_code ^= error_table_$locked_by_this_process then do;
237                     call clean_up;
238                     return;
239                end;
240 
241                rs_info.locate_sw = "0"b;
242                rs_info.unlock_sw = "1"b;
243 
244                call iox_$control (journal_control_block.vfile_iocb_ptr, "record_status", rs_info_ptr, p_code);
245                free rs_info;
246                if p_code ^= 0 & p_code ^= error_table_$locked_by_this_process then
247                     return;
248 
249                goto NEXT;
250 
251 ENTRY_TYPE (8):                                             /* RS_LOCK_CREATE */
252                if journal_entry.key_len > 0 then do;
253                     gk_key_len = journal_entry.key_len;
254 
255                     allocate gk_info in (scratch_area);
256 
257                     gk_info.version = gk_info_version_0;
258                     gk_info.input_key = "1"b;
259                     gk_info.input_desc = "1"b;
260                     gk_info.descrip = journal_entry.descriptor;
261                     gk_info.key = journal_entry.key_str;
262 
263                     call iox_$control (journal_control_block.vfile_iocb_ptr, "get_key", gk_info_ptr, p_code);
264                     free gk_info;
265                     if p_code ^= 0 & p_code ^= error_table_$locked_by_this_process then do;
266                          call clean_up;
267                          return;
268                     end;
269                end;
270 
271                allocate rs_info in (scratch_area);
272 
273                rs_info.version = rs_info_version_2;
274 
275                call iox_$control (journal_control_block.vfile_iocb_ptr, "record_status", rs_info_ptr, p_code);
276                free rs_info;
277                if p_code ^= 0 & p_code ^= error_table_$locked_by_this_process then do;
278                     call clean_up;
279                     return;
280                end;
281 
282                call iox_$delete_record (journal_control_block.vfile_iocb_ptr, p_code);
283                if p_code ^= 0 & p_code ^= error_table_$locked_by_this_process then
284                     return;
285 
286                goto NEXT;
287 
288 NEXT:
289                journal_entry_ptr = journal_entry.prev_ptr;
290                journal_control_block.latest_entry_ptr = journal_entry_ptr;
291           end;
292           return;
293 
294 clean_up:
295      proc;
296 
297           if ak_info_ptr ^= null () then
298                free ak_info;
299           if gk_info_ptr ^= null () then
300                free gk_info;
301           if rs_info_ptr ^= null () then
302                free rs_info;
303           call rcprm_registry_util_$turn_off_privs (privileges_string);
304 
305      end clean_up;
306 ^L
307 %include journal_entry;
308 %include journal_control_block;
309 %include ak_info;
310 %include rs_info;
311 %include iox_dcls;
312      end;                                                   /* end rollback */