/* Program Name : FILERWIN.C */ /* Original Author : C. K. Hung */ /* Date : 1-MAY-1991 */ /* Program Description : */ /* : */ /* Revision History follows */ #include "global.h" #include "dx.h" #include "filer.h" #include "filerkpd.h" #include "filerque.h" #include "filerwin.h" #include "findfile.h" #include "inquire.h" #include /* ** ** INTERNAL FUNCTION PROTOTYPING ** **/ static struct fil_dx_tag *find_current_file(unsigned short int); /* **++ ** FUNCTIONAL DESCRIPTION: ** ** tbs ** **-- **/ int filer_split_win() { int total_rows, dir_info_pbd_row, prev_win; struct fil_dx_tag *p, *q; struct filespec_list_tag *r; unsigned short int windows; char errmsg[255]; int i; int rows_in_page, current_page; char row_str[81]; $DESCRIPTOR(row_str_descrip, row_str); char page_str[81]; $DESCRIPTOR(page_str_descrip, page_str); int row_beg_y; int (*cstat)(); windows = cntrl_info_block.windows; if (windows >= MAXWINDOWS) { signal_err("Maximum number of windows exceeded", bell); return DX__ERROR; } else if (cntrl_info_block.pasteboard_rows < CMDS_RSV_LNS+(windows+1)*(DIRINFO_RSV_LNS+4)) { sprintf(errmsg, "Terminal page length too small for %d windows", windows+1); signal_err(errmsg, bell); return DX__ERROR; } for (i = cntrl_info_block.windows; i >= 0; i--) { if (i >= cntrl_info_block.cur_win+1) { cntrl_info_block.dir_dx[i] = cntrl_info_block.dir_dx[i-1]; } } /* ** Shrink the existing displays by reducing ROWS and BEG_Y fields ** in DIR_INFO_DISPLAY and FILER_DISPLAY, then do re-pasting. **/ total_rows = 0; for (i = 0; i <= cntrl_info_block.windows; i++) { cntrl_info_block.dir_dx[i].dir_info_display.rows = (cntrl_info_block.pasteboard_rows - CMDS_RSV_LNS - total_rows) / (windows + 1 - i); cntrl_info_block.dir_dx[i].dir_info_display.beg_y = CMDS_RSV_LNS + total_rows; total_rows += cntrl_info_block.dir_dx[i].dir_info_display.rows; cntrl_info_block.dir_dx[i].filer_display.view_rows = cntrl_info_block.dir_dx[i].dir_info_display.rows - DIRINFO_RSV_LNS; cntrl_info_block.dir_dx[i].filer_display.beg_y = 2 + cntrl_info_block.dir_dx[i].dir_info_display.beg_y; if (i != cntrl_info_block.cur_win+1) { /** Update dir_info_display **/ check_OK(smg$change_virtual_display ( &cntrl_info_block.dir_dx[i].dir_info_display.id, &cntrl_info_block.dir_dx[i].dir_info_display.rows, 0, 0, 0, 0)) check_OK(smg$move_virtual_display ( &cntrl_info_block.dir_dx[i].dir_info_display.id, &cntrl_info_block.pasteboard_id, &cntrl_info_block.dir_dx[i].dir_info_display.beg_y, &cntrl_info_block.dir_dx[i].dir_info_display.beg_x, 0)) put_filer_title(i); put_filer_stat(i); current_page = 1+(cntrl_info_block.dir_dx[i].cur_file->beg_y-1) / cntrl_info_block.dir_dx[i].filer_display.view_rows; sprintf(page_str, "Pg %d", current_page); LENGTH(page_str_descrip) = strlen(page_str); sprintf(row_str, "Row %d", cntrl_info_block.dir_dx[i].cur_file->beg_y); LENGTH(row_str_descrip) = strlen(row_str); check_OK(smg$begin_display_update ( &cntrl_info_block.dir_dx[i].dir_info_display.id)) check_OK(smg$draw_line ( &cntrl_info_block.dir_dx[i].dir_info_display.id, &cntrl_info_block.dir_dx[i].dir_info_display.rows, &1, &cntrl_info_block.dir_dx[i].dir_info_display.rows, &cntrl_info_block.dir_dx[i].dir_info_display.width, 0, 0)) check_OK(smg$put_chars ( &cntrl_info_block.dir_dx[i].dir_info_display.id, &page_str_descrip, &cntrl_info_block.dir_dx[i].dir_info_display.rows, &2, 0, &SMG$M_BOLD, 0, 0)) row_beg_y = LENGTH(page_str_descrip)+4; check_OK(smg$put_chars ( &cntrl_info_block.dir_dx[i].dir_info_display.id, &row_str_descrip, &cntrl_info_block.dir_dx[i].dir_info_display.rows, &row_beg_y, 0, &SMG$M_BOLD, 0, 0)) check_OK(smg$end_display_update ( &cntrl_info_block.dir_dx[i].dir_info_display.id)) /** Update filer_display **/ cntrl_info_block.dir_dx[i].filer_display.rows = max (cntrl_info_block.dir_dx[i].non_dir_filelist->backward->beg_y, cntrl_info_block.dir_dx[i].filer_display.view_rows); check_OK(smg$move_virtual_display ( &cntrl_info_block.dir_dx[i].filer_display.id, &cntrl_info_block.pasteboard_id, &cntrl_info_block.dir_dx[i].filer_display.beg_y, &cntrl_info_block.dir_dx[i].filer_display.beg_x, 0)) check_OK(smg$change_virtual_display ( &cntrl_info_block.dir_dx[i].filer_display.id, &cntrl_info_block.dir_dx[i].filer_display.rows, 0, 0, 0, 0)) check_OK(smg$change_viewport ( &cntrl_info_block.dir_dx[i].filer_display.id, 0, 0, &cntrl_info_block.dir_dx[i].filer_display.view_rows, 0)) change_filer_viewport(i); } } highlight_filer_current_file(); unhighlight_filer_current_file(); /** Assign the new display attributes **/ cntrl_info_block.windows++; prev_win = cntrl_info_block.cur_win; cntrl_info_block.cur_win++; /* ** New window will inherite most of the attributes from the original ** window. Different attributes are modified follows. **/ strcpy(DX_CURRENT_DIRECTORY.search_pattern, "*"); /* ** Modify DIR_INFO virtual displays **/ check_OK(smg$create_virtual_display ( &DX_CURRENT_DIRECTORY.dir_info_display.rows, &cntrl_info_block.pasteboard_width, &DX_CURRENT_DIRECTORY.dir_info_display.id, &SMG$M_TRUNC_ICON, 0, 0)) check_OK(smg$paste_virtual_display ( &DX_CURRENT_DIRECTORY.dir_info_display.id, &cntrl_info_block.pasteboard_id, &DX_CURRENT_DIRECTORY.dir_info_display.beg_y, &1, 0)) put_filer_title(cntrl_info_block.cur_win); put_filer_stat(cntrl_info_block.cur_win); check_OK(smg$draw_line ( &DX_CURRENT_DIRECTORY.dir_info_display.id, &DX_CURRENT_DIRECTORY.dir_info_display.rows, &1, &DX_CURRENT_DIRECTORY.dir_info_display.rows, &DX_CURRENT_DIRECTORY.dir_info_display.width, 0, 0)) check_OK(smg$set_cursor_abs ( &cntrl_info_block.commands_display.id, &cntrl_info_block.commands_display.rows, &cntrl_info_block.commands_display.width)) /* ** Output 'working...' message if total processing time ** is longer than 3 seconds. Needs to disable broadcast message ** first because of interference. **/ #ifndef DEBUG check_OK(smg$disable_broadcast_trapping ( &cntrl_info_block.pasteboard_id)) cstat = signal(SIGALRM, filter_alarm_working); alarm(1); #endif /* ** Copy to new filespec lists - ** NAME_FILESPEC_LIST, EXCLUDE_FILESPEC_LIST **/ copy_filespec_list( cntrl_info_block.dir_dx[prev_win].cur_filter.name_filespec_list, &DX_CURRENT_DIRECTORY.cur_filter.name_filespec_list); copy_filespec_list( cntrl_info_block.dir_dx[prev_win].cur_filter.exclude_filespec_list, &DX_CURRENT_DIRECTORY.cur_filter.exclude_filespec_list); /* ** Copy to new filelists - ** NON_DIR_FILELIST, DIR_FILELIST, EXCLUDE_FILELIST **/ copy_filelist( cntrl_info_block.dir_dx[prev_win].non_dir_filelist, &DX_CURRENT_DIRECTORY.non_dir_filelist, DX_CURRENT_DIRECTORY.sortby, DX_CURRENT_DIRECTORY.sortorder); copy_filelist( cntrl_info_block.dir_dx[prev_win].dir_filelist, &DX_CURRENT_DIRECTORY.dir_filelist, DX_CURRENT_DIRECTORY.sortby, DX_CURRENT_DIRECTORY.sortorder); copy_filelist( cntrl_info_block.dir_dx[prev_win].exclude_filelist, &DX_CURRENT_DIRECTORY.exclude_filelist, DX_CURRENT_DIRECTORY.sortby, DX_CURRENT_DIRECTORY.sortorder); /* ** Modify FILER virtual displays **/ DX_CURRENT_DIRECTORY.filer_display.rows = max (DX_CURRENT_DIRECTORY.non_dir_filelist->backward->beg_y, DX_CURRENT_DIRECTORY.filer_display.view_rows); check_OK(smg$create_virtual_display ( &DX_CURRENT_DIRECTORY.filer_display.rows, &DX_CURRENT_DIRECTORY.filer_display.width, &DX_CURRENT_DIRECTORY.filer_display.id, 0, 0, 0)) check_OK(smg$create_viewport ( &DX_CURRENT_DIRECTORY.filer_display.id, &DX_CURRENT_DIRECTORY.filer_display.view_beg_y, &DX_CURRENT_DIRECTORY.filer_display.view_beg_x, &DX_CURRENT_DIRECTORY.filer_display.view_rows, &DX_CURRENT_DIRECTORY.filer_display.view_width)) /* ** Find current file pointer in the new window **/ DX_CURRENT_FILE = find_current_file(prev_win); /* ** Write the new window **/ write_to_filer(DX_CURRENT_DIRECTORY.dir_filelist); write_to_filer(DX_CURRENT_DIRECTORY.non_dir_filelist); change_filer_viewport(cntrl_info_block.cur_win); highlight_filer_current_file(); check_OK(smg$paste_virtual_display ( &DX_CURRENT_DIRECTORY.filer_display.id, &cntrl_info_block.pasteboard_id, &DX_CURRENT_DIRECTORY.filer_display.beg_y, &DX_CURRENT_DIRECTORY.filer_display.beg_x, 0)) /* ** Set the signal back to system default **/ #ifndef DEBUG alarm(0); signal(SIGALRM, cstat); check_OK(smg$erase_chars ( &cntrl_info_block.commands_display.id, &10, &2, &1)) check_OK(smg$set_broadcast_trapping ( &cntrl_info_block.pasteboard_id, broadcast_routine, 0)) #endif; return DX__NORMAL; } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** tbs ** **-- **/ static struct fil_dx_tag *find_current_file( unsigned short int prev_win) { struct fil_dx_tag *p, *q; for (p = cntrl_info_block.dir_dx[prev_win].dir_filelist->forward, q = DX_CURRENT_DIRECTORY.dir_filelist->forward; p != cntrl_info_block.dir_dx[prev_win].non_dir_filelist; p = p->forward, q = q->forward) { if (p == cntrl_info_block.dir_dx[prev_win].cur_file) { return q; } else if (p == cntrl_info_block.dir_dx[prev_win].dir_filelist) { p = cntrl_info_block.dir_dx[prev_win].non_dir_filelist; q = DX_CURRENT_DIRECTORY.non_dir_filelist; } } return DX__ERROR; } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** tbs ** **-- **/ int filer_delete_win() { int i, w; int num_of_scrolls; struct dir_dx_tag prev_dir_dx; int total_rows; if (cntrl_info_block.windows == 1) { signal_err("There is only one window", bell); return DX__ERROR; } prev_dir_dx = DX_CURRENT_DIRECTORY; for (w = cntrl_info_block.cur_win; w < cntrl_info_block.windows-1; w++) { cntrl_info_block.dir_dx[w] = cntrl_info_block.dir_dx[w+1]; } if (cntrl_info_block.cur_win == cntrl_info_block.windows-1) { cntrl_info_block.cur_win--; } cntrl_info_block.windows--; total_rows = 0; for (w = 0; w < cntrl_info_block.windows; w++) { int display_rows; display_rows = (cntrl_info_block.pasteboard_rows-CMDS_RSV_LNS-total_rows)/ (cntrl_info_block.windows-w); cntrl_info_block.dir_dx[w].dir_info_display.beg_y = CMDS_RSV_LNS + total_rows; num_of_scrolls = display_rows - cntrl_info_block.dir_dx[w].dir_info_display.rows; cntrl_info_block.dir_dx[w].dir_info_display.rows = display_rows; total_rows += cntrl_info_block.dir_dx[w].dir_info_display.rows; cntrl_info_block.dir_dx[w].filer_display.beg_y = 2 + cntrl_info_block.dir_dx[w].dir_info_display.beg_y; check_OK(smg$begin_pasteboard_update ( &cntrl_info_block.pasteboard_id)) check_OK(smg$move_virtual_display ( &cntrl_info_block.dir_dx[w].dir_info_display.id, &cntrl_info_block.pasteboard_id, &cntrl_info_block.dir_dx[w].dir_info_display.beg_y, &cntrl_info_block.dir_dx[w].dir_info_display.beg_x, 0)) check_OK(smg$change_virtual_display ( &cntrl_info_block.dir_dx[w].dir_info_display.id, &cntrl_info_block.dir_dx[w].dir_info_display.rows, 0, 0, 0, 0)) check_OK(smg$move_virtual_display ( &cntrl_info_block.dir_dx[w].filer_display.id, &cntrl_info_block.pasteboard_id, &cntrl_info_block.dir_dx[w].filer_display.beg_y, &cntrl_info_block.dir_dx[w].filer_display.beg_x, 0)) /** Adjust filer_display size **/ if (cntrl_info_block.dir_dx[w].filer_display.rows < cntrl_info_block.dir_dx[w].dir_info_display.rows - 3) { cntrl_info_block.dir_dx[w].filer_display.rows = cntrl_info_block.dir_dx[w].dir_info_display.rows - 3; check_OK(smg$change_virtual_display ( &cntrl_info_block.dir_dx[w].filer_display.id, &cntrl_info_block.dir_dx[w].filer_display.rows, 0, 0, 0, 0)) } for (i = 0; i < num_of_scrolls; i++) { check_OK(smg$insert_line ( &cntrl_info_block.dir_dx[w].dir_info_display.id, &3, $DESCR (" "), &SMG$M_DOWN, 0, 0, 0, 0)) /** Adjust filer_display **/ cntrl_info_block.dir_dx[w].filer_display.view_rows++; if (cntrl_info_block.dir_dx[w].filer_display.view_beg_y > 1 && cntrl_info_block.dir_dx[w].filer_display.view_beg_y + cntrl_info_block.dir_dx[w].filer_display.view_rows - 1 > cntrl_info_block.dir_dx[w].non_dir_filelist->backward->beg_y) { cntrl_info_block.dir_dx[w].filer_display.view_beg_y--; } check_OK(smg$change_viewport ( &cntrl_info_block.dir_dx[w].filer_display.id, &cntrl_info_block.dir_dx[w].filer_display.view_beg_y, 0, &cntrl_info_block.dir_dx[w].filer_display.view_rows, 0)) } check_OK(smg$end_pasteboard_update ( &cntrl_info_block.pasteboard_id)) /** Reposition the cursor in the current display **/ change_filer_viewport(w); } /* ** Free resoueces used by the window deleted **/ free_filespec_list( &prev_dir_dx.cur_filter.name_filespec_list); free_filespec_list( &prev_dir_dx.cur_filter.exclude_filespec_list); free_filelist( &prev_dir_dx.non_dir_filelist); free_filelist( &prev_dir_dx.dir_filelist); free_filelist( &prev_dir_dx.exclude_filelist); check_OK(smg$delete_virtual_display ( &prev_dir_dx.dir_info_display.id)) check_OK(smg$delete_virtual_display ( &prev_dir_dx.filer_display.id)) return DX__NORMAL; } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** tbs ** **-- **/ int filer_one_win() { int i; int num_of_scrolls; if (cntrl_info_block.windows == 1) { signal_err("There is only one window", bell); return DX__ERROR; } /** Make the current displays the topmost displays **/ check_OK(smg$repaste_virtual_display ( &DX_CURRENT_DIRECTORY.filer_display.id, &cntrl_info_block.pasteboard_id, &DX_CURRENT_DIRECTORY.filer_display.beg_y, &DX_CURRENT_DIRECTORY.filer_display.beg_x, 0)) check_OK(smg$repaste_virtual_display ( &DX_CURRENT_DIRECTORY.dir_info_display.id, &cntrl_info_block.pasteboard_id, &DX_CURRENT_DIRECTORY.dir_info_display.beg_y, &DX_CURRENT_DIRECTORY.dir_info_display.beg_x, &DX_CURRENT_DIRECTORY.filer_display.id)) /** Scroll upward **/ num_of_scrolls = 0; for (i = 0; i < cntrl_info_block.cur_win; i++) { num_of_scrolls += cntrl_info_block.dir_dx[i].dir_info_display.rows; } for (i = 0; i < num_of_scrolls; i++) { check_OK(smg$begin_pasteboard_update ( &cntrl_info_block.pasteboard_id)) /** Adjust dir_info_display **/ DX_CURRENT_DIRECTORY.dir_info_display.beg_y--; check_OK(smg$move_virtual_display ( &DX_CURRENT_DIRECTORY.dir_info_display.id, &cntrl_info_block.pasteboard_id, &DX_CURRENT_DIRECTORY.dir_info_display.beg_y, &DX_CURRENT_DIRECTORY.dir_info_display.beg_x, 0)) DX_CURRENT_DIRECTORY.dir_info_display.rows++; check_OK(smg$change_virtual_display ( &DX_CURRENT_DIRECTORY.dir_info_display.id, &DX_CURRENT_DIRECTORY.dir_info_display.rows, 0, 0, 0, 0)) check_OK(smg$insert_line ( &DX_CURRENT_DIRECTORY.dir_info_display.id, &3, $DESCR (" "), &SMG$M_DOWN, 0, 0, 0, 0)) /** Adjust filer_display **/ DX_CURRENT_DIRECTORY.filer_display.beg_y--; check_OK(smg$move_virtual_display ( &DX_CURRENT_DIRECTORY.filer_display.id, &cntrl_info_block.pasteboard_id, &DX_CURRENT_DIRECTORY.filer_display.beg_y, &DX_CURRENT_DIRECTORY.filer_display.beg_x, 0)) if (DX_CURRENT_DIRECTORY.filer_display.view_beg_y > 1) { DX_CURRENT_DIRECTORY.filer_display.view_beg_y--; } DX_CURRENT_DIRECTORY.filer_display.view_rows++; if (DX_CURRENT_DIRECTORY.filer_display.rows < DX_CURRENT_DIRECTORY.filer_display.view_rows) { /** Increase the size of filer_display **/ DX_CURRENT_DIRECTORY.filer_display.rows = DX_CURRENT_DIRECTORY.filer_display.view_rows; check_OK(smg$change_virtual_display ( &DX_CURRENT_DIRECTORY.filer_display.id, &DX_CURRENT_DIRECTORY.filer_display.rows, 0, 0, 0, 0)) } check_OK(smg$change_viewport ( &DX_CURRENT_DIRECTORY.filer_display.id, &DX_CURRENT_DIRECTORY.filer_display.view_beg_y, 0, &DX_CURRENT_DIRECTORY.filer_display.view_rows, 0)) check_OK(smg$end_pasteboard_update ( &cntrl_info_block.pasteboard_id)) } /** Scroll downward **/ num_of_scrolls = 0; for (i = cntrl_info_block.cur_win+1; i < cntrl_info_block.windows; i++) { num_of_scrolls += cntrl_info_block.dir_dx[i].dir_info_display.rows; } for (i = 0; i < num_of_scrolls; i++) { check_OK(smg$begin_pasteboard_update ( &cntrl_info_block.pasteboard_id)) /** Adjust dir_info_display **/ DX_CURRENT_DIRECTORY.dir_info_display.rows++; check_OK(smg$change_virtual_display ( &DX_CURRENT_DIRECTORY.dir_info_display.id, &DX_CURRENT_DIRECTORY.dir_info_display.rows, 0, 0, 0, 0)) check_OK(smg$insert_line ( &DX_CURRENT_DIRECTORY.dir_info_display.id, &3, $DESCR (" "), &SMG$M_DOWN, 0, 0, 0, 0)) /** Adjust filer_display **/ DX_CURRENT_DIRECTORY.filer_display.view_rows++; if (DX_CURRENT_DIRECTORY.filer_display.rows < DX_CURRENT_DIRECTORY.filer_display.view_rows) { /** Increase the size of filer_display **/ DX_CURRENT_DIRECTORY.filer_display.rows = DX_CURRENT_DIRECTORY.filer_display.view_rows; check_OK(smg$change_virtual_display ( &DX_CURRENT_DIRECTORY.filer_display.id, &DX_CURRENT_DIRECTORY.filer_display.rows, 0, 0, 0, 0)) } if (DX_CURRENT_DIRECTORY.filer_display.view_beg_y > 1 && DX_CURRENT_DIRECTORY.filer_display.view_beg_y + DX_CURRENT_DIRECTORY.filer_display.view_rows - 1 > DX_CURRENT_DIRECTORY.non_dir_filelist->backward->beg_y) { DX_CURRENT_DIRECTORY.filer_display.view_beg_y--; } check_OK(smg$change_viewport ( &DX_CURRENT_DIRECTORY.filer_display.id, &DX_CURRENT_DIRECTORY.filer_display.view_beg_y, 0, &DX_CURRENT_DIRECTORY.filer_display.view_rows, 0)) check_OK(smg$end_pasteboard_update ( &cntrl_info_block.pasteboard_id)) } /** Reposition the cursor in the current display **/ change_filer_viewport(cntrl_info_block.cur_win); /* ** Free resoueces used by the other window **/ for (i = 0; i < cntrl_info_block.windows; i++) { if (i != cntrl_info_block.cur_win) { free_filespec_list( &cntrl_info_block.dir_dx[i].cur_filter.name_filespec_list); free_filespec_list( &cntrl_info_block.dir_dx[i].cur_filter.exclude_filespec_list); free_filelist( &cntrl_info_block.dir_dx[i].non_dir_filelist); free_filelist( &cntrl_info_block.dir_dx[i].dir_filelist); free_filelist( &cntrl_info_block.dir_dx[i].exclude_filelist); check_OK(smg$delete_virtual_display ( &cntrl_info_block.dir_dx[i].dir_info_display.id)) check_OK(smg$delete_virtual_display ( &cntrl_info_block.dir_dx[i].filer_display.id)) } } /** Make the first display the current display **/ cntrl_info_block.dir_dx[0] = DX_CURRENT_DIRECTORY; cntrl_info_block.cur_win = 0; cntrl_info_block.windows = 1; return DX__NORMAL; } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** tbs ** **-- **/ int filer_next_win() { char errmsg[MAXFILESPEC+1]; if (cntrl_info_block.windows == 1) { signal_err("There is only one window", bell); return DX__ERROR; } unhighlight_filer_current_file(); cntrl_info_block.cur_win++; if (cntrl_info_block.cur_win >= cntrl_info_block.windows) { cntrl_info_block.cur_win = 0; } setddir(DX_CURRENT_DIRECTORY.cur_dir, errmsg); highlight_filer_current_file(); } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** tbs ** **-- **/ int filer_prev_win() { char errmsg[MAXFILESPEC+1]; if (cntrl_info_block.windows == 1) { signal_err("There is only one window", bell); return DX__ERROR; } unhighlight_filer_current_file(); cntrl_info_block.cur_win--; if ((short) cntrl_info_block.cur_win < 0) { cntrl_info_block.cur_win = cntrl_info_block.windows-1; } setddir(DX_CURRENT_DIRECTORY.cur_dir, errmsg); highlight_filer_current_file(); } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** tbs ** **-- **/ void filer_exitset() { /* ** Scroll screen up 1 line **/ check_OK(smg$set_physical_cursor ( &cntrl_info_block.pasteboard_id, &cntrl_info_block.pasteboard_rows, &1)) fprintf(stderr, "\033E"); /* ** Exit without resetting default directory back to the ** original directory **/ exit(SS$_NORMAL); }