/* Program Name : FINDFILE.C */ /* Original Author : C. K. Hung */ /* Date : 7-12-89 */ /* Program Description : */ /* : */ /* Revision History follows */ /* 03-Jun-1999 JL usage of __FIB */ #include "global.h" #include "filerque.h" #include "findfile.h" #include "filerdel.h" #include "filerflt.h" #include "filersrt.h" #include "inquire.h" #include #include #include #include #include /* **++ ** FUNCTIONAL DESCRIPTION: ** ** FIND_DIRECT_FILE() searchs all the directory files in the directory. ** Parent directory file is also included. ** **-- **/ int find_direct_file() { /* ** VARIABLES USED BY ACP SERVICES **/ unsigned int iosb[2]; static struct fibdef fib; struct dsc$descriptor_s fib_descrip = { sizeof (struct fibdef), DSC$K_DTYPE_T, DSC$K_CLASS_S, (char *)&fib }; unsigned short len; char filespec[MAXFILESPEC+1]; $DESCRIPTOR (filespec_descrip, filespec); unsigned long fch; /** File characteristics blocks **/ struct sbkdef asb; /** Statistics Block **/ DATE_TIME cdat, /** 64-bit Creation Date **/ rdat, /** 64-bit Revision Date **/ edat, /** 64-bit Expiration Date **/ bdat; /** 64-bit Backup Date **/ unsigned short int fpro; /** File Protection **/ struct { /** Access Control Block **/ unsigned short w_size; unsigned short w_type; char *l_addr; } acb[] = { { ATR$S_UCHAR, ATR$C_UCHAR, (char *)&fch }, { ATR$S_STATBLK, ATR$C_STATBLK, (char *)&asb }, { ATR$S_CREDATE, ATR$C_CREDATE, (char *)&cdat }, { ATR$S_REVDATE, ATR$C_REVDATE, (char *)&rdat }, { ATR$S_EXPDATE, ATR$C_EXPDATE, (char *)&edat }, { ATR$S_BAKDATE, ATR$C_BAKDATE, (char *)&bdat }, { ATR$S_FPRO, ATR$C_FPRO, (char *)&fpro }, { 0, 0, (char *)NULL } }; /* ** NON-ACP VARABLES **/ register int i; int total_dids; char equ_name[MAXFILESPEC+1]; int total_devices; char dev_name[MAXFILESPEC+1]; struct fil_dx_tag temp_entry; struct fil_dx_tag *new_entry; int allocate_size; char str[128]; $DESCRIPTOR (str_descrip, str); struct filespec_list_tag *p; struct w_dids_tag *q; /* ** Create a new list head. ** Free up memory for old list first. **/ free_filelist(&DX_CURRENT_DIRECTORY.dir_filelist); if ((DX_CURRENT_DIRECTORY.dir_filelist = create_MARKER()) == (struct fil_dx_tag *)NULL) { signal_err("Error creating MARKER for directory file list", bell); return DX__ERROR; } /* ** Insert parent directory entry **/ if (DX_CURRENT_DIRECTORY.par_dir[0] != EOS) { strcpy (temp_entry.fn, "[-]"); temp_entry.state = waiting; insert_filelist_entry( DX_CURRENT_DIRECTORY.dir_filelist, temp_entry, DX_CURRENT_DIRECTORY.sortby, DX_CURRENT_DIRECTORY.sortorder); } /* ** Find out the number of equivalent names of current directory **/ total_dids = 0; equ_name[0] = EOS; total_devices = 0; dev_name[0] = EOS; for (p = DX_CURRENT_DIRECTORY.cur_filter.name_filespec_list; p; p = p->next) { for (q = p->w_dids; q; q = q->next) { size_t len; if (strcmp (q->equivalent_name, equ_name)) { total_dids++; strcpy (equ_name, q->equivalent_name); } len = strcspn (q->equivalent_name, "["); if (strncmp (q->equivalent_name, dev_name, len)) { total_devices++; strncpy (dev_name, q->equivalent_name, len); } } } /* ** Find all the directory files in this directory **/ strcpy(str, "*.DIR;1"); LENGTH(str_descrip) = strlen(str); for (p = DX_CURRENT_DIRECTORY.cur_filter.name_filespec_list; p; p = p->next) { for (q = p->w_dids; q; q = q->next) { for (i = 0; i <= 2; i++) __FIB(fib,fib$r_did_overlay,fib$w_did[i]) = q->did[i]; filespec[0] = EOS; for (i = 0; i <= 2; i++) { temp_entry.did[i] = q->did[i]; } /* ** Initialize FIB to indicate to ACP that a directory ** look-up operation is desired. **/ __FIB(fib,fib$r_nmctl_overlay,fib$w_nmctl) = FIB$M_WILD; fib.fib$l_wcc = 0; check_OK(sys$qiow ( 0, q->chan, IO$_ACCESS, iosb, 0, 0, &fib_descrip, &str_descrip, &len, &filespec_descrip, acb, 0 )) while (iosb[0] == SS$_NORMAL || ((iosb[0] == SS$_NOPRIV || iosb[0] == SS$_NOSUCHFILE) && filespec[0])) { size_t len1; if (total_dids <= 1) { strcpy (temp_entry.fn, "[."); len1 = strcspn (filespec, "."); strncat (temp_entry.fn, filespec, len1); strcat (temp_entry.fn, "]"); } else { if (total_devices <= 1) { strcpy (temp_entry.fn, strchr (q->equivalent_name, '[')); } else { strcpy (temp_entry.fn, q->equivalent_name); } temp_entry.fn[strlen(temp_entry.fn)-1] = '.'; len1 = strcspn (filespec, "."); strncat (temp_entry.fn, filespec, len1); strcat (temp_entry.fn, "]"); } DX_CURRENT_DIRECTORY.subdir++; if (iosb[0] == SS$_NOPRIV) { temp_entry.filesize = 0; temp_entry.fpro = 0Xffff; /** Insufficient privilege **/ convert_date_string ( "17-NOV-1858 00:00:00.00", &temp_entry.cdat); memcpy(&temp_entry.rdat, &temp_entry.cdat, sizeof (DATE_TIME)); memcpy(&temp_entry.edat, &temp_entry.cdat, sizeof (DATE_TIME)); memcpy(&temp_entry.bdat, &temp_entry.cdat, sizeof (DATE_TIME)); } else if (iosb[0] == SS$_NOSUCHFILE) { temp_entry.filesize = 0; temp_entry.fpro = 0Xfffe; /** No such file **/ convert_date_string ( "17-NOV-1858 00:00:00.00", &temp_entry.cdat); memcpy(&temp_entry.rdat, &temp_entry.cdat, sizeof (DATE_TIME)); memcpy(&temp_entry.edat, &temp_entry.cdat, sizeof (DATE_TIME)); memcpy(&temp_entry.bdat, &temp_entry.cdat, sizeof (DATE_TIME)); } else { for (i = 0; i <= 2; i++) { temp_entry.fid[i] = __FIB(fib,fib$r_fid_overlay,fib$w_fid[i]); } temp_entry.filesize = (asb.sbk$w_filesizh << 16)+asb.sbk$w_filesizl; memcpy(&temp_entry.cdat, &cdat, sizeof (DATE_TIME)); memcpy(&temp_entry.rdat, &rdat, sizeof (DATE_TIME)); memcpy(&temp_entry.edat, &edat, sizeof (DATE_TIME)); memcpy(&temp_entry.bdat, &bdat, sizeof (DATE_TIME)); temp_entry.fpro = fpro; } temp_entry.state = waiting; if (insert_filelist_entry( DX_CURRENT_DIRECTORY.dir_filelist, temp_entry, DX_CURRENT_DIRECTORY.sortby, DX_CURRENT_DIRECTORY.sortorder) == DX__NORMAL) { DX_CURRENT_DIRECTORY.tot_files++; DX_CURRENT_DIRECTORY.tot_blocks += temp_entry.filesize; } check_OK(sys$qiow ( 0, q->chan, IO$_ACCESS, iosb, 0, 0, &fib_descrip, &str_descrip, &len, &filespec_descrip, acb, 0 )) } } } return DX__NORMAL; } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** FIND_NON_DIRECT_FILE() searchs all the files except directory files ** in the directory that meet user specified file specification ** **-- **/ int find_non_direct_file() { /* ** VARIABLES USED BY ACP SERVICES **/ unsigned int iosb[2]; static struct fibdef fib; struct dsc$descriptor_s fib_descrip = { sizeof (struct fibdef), DSC$K_DTYPE_T, DSC$K_CLASS_S, (char *)&fib }; unsigned short len; char filespec[MAXFILESPEC+1]; $DESCRIPTOR (filespec_descrip, filespec); unsigned long fch; /** File characteristics blocks **/ struct sbkdef asb; /** Statistics Block **/ DATE_TIME cdat, /** 64-bit Creation Date **/ rdat, /** 64-bit Revision Date **/ edat, /** 64-bit Expiration Date **/ bdat; /** 64-bit Backup Date **/ unsigned short int fpro; /** File Protection **/ struct { /** Access Control Block **/ unsigned short w_size; unsigned short w_type; char *l_addr; } acb[] = { { ATR$S_UCHAR, ATR$C_UCHAR, (char *)&fch }, { ATR$S_STATBLK, ATR$C_STATBLK, (char *)&asb }, { ATR$S_CREDATE, ATR$C_CREDATE, (char *)&cdat }, { ATR$S_REVDATE, ATR$C_REVDATE, (char *)&rdat }, { ATR$S_EXPDATE, ATR$C_EXPDATE, (char *)&edat }, { ATR$S_BAKDATE, ATR$C_BAKDATE, (char *)&bdat }, { ATR$S_FPRO, ATR$C_FPRO, (char *)&fpro }, { 0, 0, (char *)NULL } }; /* ** NON-ACP VARABLES **/ register int i; int total_dids; char equ_name[MAXFILESPEC+1]; int total_devices; char dev_name[MAXFILESPEC+1]; struct fil_dx_tag temp_entry; struct fil_dx_tag *new_entry; int allocate_size; char str[128]; $DESCRIPTOR (str_descrip, str); struct filespec_list_tag *p; struct w_dids_tag *q; /* ** Create a new list head. ** Free up memory for old list first. **/ free_filelist(&DX_CURRENT_DIRECTORY.non_dir_filelist); if ((DX_CURRENT_DIRECTORY.non_dir_filelist = create_MARKER()) == (struct fil_dx_tag *)NULL) { signal_err("Error creating MARKER for non-directory file list", bell); return DX__ERROR; } total_dids = 0; equ_name[0] = EOS; total_devices = 0; dev_name[0] = EOS; for (p = DX_CURRENT_DIRECTORY.cur_filter.name_filespec_list; p; p = p->next) { for (q = p->w_dids; q; q = q->next) { size_t len; if (strcmp (q->equivalent_name, equ_name)) { total_dids++; strcpy (equ_name, q->equivalent_name); } len = strcspn (q->equivalent_name, "["); if (strncmp (q->equivalent_name, dev_name, len)) { total_devices++; strncpy (dev_name, q->equivalent_name, len); } } } for (p = DX_CURRENT_DIRECTORY.cur_filter.name_filespec_list; p; p = p->next) { /* ** Find all the files in this directory that meet the criteria **/ strcpy(str, p->name); LENGTH(str_descrip) = strlen(str); for (q = p->w_dids; q; q = q->next) { for (i = 0; i <= 2; i++) __FIB(fib,fib$r_did_overlay,fib$w_did[i]) = q->did[i]; filespec[0] = EOS; for (i = 0; i <= 2; i++) { temp_entry.did[i] = q->did[i]; } /* ** Initialize FIB to indicate to ACP that a directory ** look-up operation is desired. **/ __FIB(fib,fib$r_nmctl_overlay,fib$w_nmctl) = FIB$M_WILD; fib.fib$l_wcc = 0; check_OK(sys$qiow ( 0, q->chan, IO$_ACCESS, iosb, 0, 0, &fib_descrip, &str_descrip, &len, &filespec_descrip, acb, 0 )) while (iosb[0] == SS$_NORMAL || ((iosb[0] == SS$_NOPRIV || iosb[0] == SS$_NOSUCHFILE) && filespec[0])) { if (!strstr (filespec, ".DIR;1")) { if (total_dids <= 1) { strcpy(temp_entry.fn, filespec); } else if (total_devices <= 1) { sprintf (temp_entry.fn, "%s%s", strchr (q->equivalent_name, '['), filespec); } else { sprintf (temp_entry.fn, "%s%s", q->equivalent_name, filespec); } if (iosb[0] == SS$_NOPRIV) { temp_entry.filesize = 0; temp_entry.fpro = 0Xffff; /** Insufficient privilege **/ convert_date_string ( "17-NOV-1858 00:00:00.00", &temp_entry.cdat); memcpy(&temp_entry.rdat, &temp_entry.cdat, sizeof (DATE_TIME)); memcpy(&temp_entry.edat, &temp_entry.cdat, sizeof (DATE_TIME)); memcpy(&temp_entry.bdat, &temp_entry.cdat, sizeof (DATE_TIME)); } else if (iosb[0] == SS$_NOSUCHFILE) { temp_entry.filesize = 0; temp_entry.fpro = 0Xfffe; /** No such file **/ convert_date_string ( "17-NOV-1858 00:00:00.00", &temp_entry.cdat); memcpy(&temp_entry.rdat, &temp_entry.cdat, sizeof (DATE_TIME)); memcpy(&temp_entry.edat, &temp_entry.cdat, sizeof (DATE_TIME)); memcpy(&temp_entry.bdat, &temp_entry.cdat, sizeof (DATE_TIME)); } else { for (i = 0; i <= 2; i++) { temp_entry.fid[i] = __FIB(fib,fib$r_fid_overlay,fib$w_fid[i]); } temp_entry.filesize = (asb.sbk$w_filesizh << 16)+asb.sbk$w_filesizl; memcpy(&temp_entry.cdat, &cdat, sizeof (DATE_TIME)); memcpy(&temp_entry.rdat, &rdat, sizeof (DATE_TIME)); memcpy(&temp_entry.edat, &edat, sizeof (DATE_TIME)); memcpy(&temp_entry.bdat, &bdat, sizeof (DATE_TIME)); temp_entry.fpro = fpro; } temp_entry.state = waiting; if (iosb[0] != SS$_NORMAL) { if (!filter_exclude( temp_entry.fn, DX_CURRENT_DIRECTORY.exclude_filelist)) { if (insert_filelist_entry( DX_CURRENT_DIRECTORY.non_dir_filelist, temp_entry, DX_CURRENT_DIRECTORY.sortby, DX_CURRENT_DIRECTORY.sortorder) == DX__NORMAL) { DX_CURRENT_DIRECTORY.tot_files++; DX_CURRENT_DIRECTORY.tot_blocks += temp_entry.filesize; } } } else if (filter_OK( temp_entry, DX_CURRENT_DIRECTORY.exclude_filelist, DX_CURRENT_DIRECTORY.cur_filter)) { if (insert_filelist_entry( DX_CURRENT_DIRECTORY.non_dir_filelist, temp_entry, DX_CURRENT_DIRECTORY.sortby, DX_CURRENT_DIRECTORY.sortorder) == DX__NORMAL) { DX_CURRENT_DIRECTORY.tot_files++; DX_CURRENT_DIRECTORY.tot_blocks += temp_entry.filesize; } } } check_OK(sys$qiow ( 0, q->chan, IO$_ACCESS, iosb, 0, 0, &fib_descrip, &str_descrip, &len, &filespec_descrip, acb, 0 )) } } } return DX__NORMAL; } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** FIND_EXCLUDE_FILE() searchs all the files except directory files ** in the directory that meet "EXCLUDE" qualifier ** **-- **/ int find_exclude_file(exclude_listp, cur_filter, sortby, sortorder) struct fil_dx_tag **exclude_listp; struct cur_filter_tag cur_filter; enum sortbys sortby; enum sortorders sortorder; { /* ** VARIABLES USED BY ACP SERVICES **/ unsigned int iosb[2]; static struct fibdef fib; struct dsc$descriptor_s fib_descrip = { sizeof (struct fibdef), DSC$K_DTYPE_T, DSC$K_CLASS_S, (char *)&fib }; unsigned short len; char filespec[MAXFILESPEC+1]; $DESCRIPTOR (filespec_descrip, filespec); /* ** NON-ACP VARABLES **/ struct fil_dx_tag *new_list; register int i; int total_dids; char equ_name[MAXFILESPEC+1]; int total_devices; char dev_name[MAXFILESPEC+1]; struct fil_dx_tag temp_entry; int allocate_size; char str[128]; $DESCRIPTOR (str_descrip, str); struct filespec_list_tag *p; struct w_dids_tag *q; /* ** Create a new list head. ** Free up memory for old list at the end. **/ if ((new_list = create_MARKER()) == (struct fil_dx_tag *)NULL) { return DX__ERROR; } total_dids = 0; equ_name[0] = EOS; total_devices = 0; dev_name[0] = EOS; for (p = cur_filter.name_filespec_list; p; p = p->next) { for (q = p->w_dids; q; q = q->next) { size_t len; if (strcmp (q->equivalent_name, equ_name)) { total_dids++; strcpy (equ_name, q->equivalent_name); } len = strcspn (q->equivalent_name, "["); if (strncmp (q->equivalent_name, dev_name, len)) { total_devices++; strncpy (dev_name, q->equivalent_name, len); } } } for (p = cur_filter.exclude_filespec_list; p; p = p->next) { /* ** Find all the files in this directory that meet the criteria **/ strcpy(str, p->name); LENGTH(str_descrip) = strlen(str); for (q = p->w_dids; q; q = q->next) { for (i = 0; i <= 2; i++) __FIB(fib,fib$r_did_overlay,fib$w_did[i]) = q->did[i]; filespec[0] = EOS; for (i = 0; i <= 2; i++) { temp_entry.did[i] = q->did[i]; } /* ** Initialize FIB to indicate to ACP that a directory ** look-up operation is desired. **/ __FIB(fib,fib$r_nmctl_overlay,fib$w_nmctl) = FIB$M_WILD; fib.fib$l_wcc = 0; check_OK(sys$qiow ( 0, q->chan, IO$_ACCESS, iosb, 0, 0, &fib_descrip, &str_descrip, &len, &filespec_descrip, 0, 0 )) while (iosb[0] == SS$_NORMAL || ((iosb[0] == SS$_NOPRIV || iosb[0] == SS$_NOSUCHFILE) && filespec[0])) { if (!strstr (filespec, ".DIR;1")) { if (total_dids <= 1) { strcpy(temp_entry.fn, filespec); } else if (total_devices <= 1) { sprintf (temp_entry.fn, "%s%s", strchr (q->equivalent_name, '['), filespec); } else { sprintf (temp_entry.fn, "%s%s", q->equivalent_name, filespec); } insert_filelist_entry( new_list, temp_entry, sortby, sortorder); } check_OK(sys$qiow ( 0, q->chan, IO$_ACCESS, iosb, 0, 0, &fib_descrip, &str_descrip, &len, &filespec_descrip, 0, 0 )) } } } free_filelist(exclude_listp); *exclude_listp = new_list; return DX__NORMAL; } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** FIND_MATCH_FILE() matchs the file with all the files that ** meets the filter 'NAME' criteria. It return 1 ** if there's a match; otherwise, 0 is returned. ** **-- **/ int find_match_file( char *candidate_file, unsigned short int win) { /* ** VARIABLES USED BY ACP SERVICES **/ unsigned int iosb[2]; static struct fibdef fib; struct dsc$descriptor_s fib_descrip = { sizeof (struct fibdef), DSC$K_DTYPE_T, DSC$K_CLASS_S, (char *)&fib }; unsigned short len; char filespec[MAXFILESPEC+1]; $DESCRIPTOR (filespec_descrip, filespec); /* ** NON-ACP VARABLES **/ register int i; char str[128]; $DESCRIPTOR (str_descrip, str); int total_dids; char equ_name[MAXFILESPEC+1]; int total_devices; char dev_name[MAXFILESPEC+1]; struct filespec_list_tag *p; struct w_dids_tag *q; char fn[MAXFILESPEC+1]; struct fil_dx_tag *head; struct fil_dx_tag temp_entry, *s, *t, *u; int found = 0; char errmsg[256]; if ((head = create_MARKER()) == (struct fil_dx_tag *)NULL) { signal_err("Insufficient virtual memory", bell); return 0; } total_dids = 0; equ_name[0] = EOS; total_devices = 0; dev_name[0] = EOS; for (p = cntrl_info_block.dir_dx[win].cur_filter.name_filespec_list; p; p = p->next) { for (q = p->w_dids; q; q = q->next) { size_t len; if (strcmp (q->equivalent_name, equ_name)) { total_dids++; strcpy (equ_name, q->equivalent_name); } len = strcspn (q->equivalent_name, "["); if (strncmp (q->equivalent_name, dev_name, len)) { total_devices++; strncpy (dev_name, q->equivalent_name, len); } } } /* ** Search for all files that match the filespec **/ for (p = cntrl_info_block.dir_dx[win].cur_filter.name_filespec_list; p; p = p->next) { /* ** Find all the files in this directory that meet the criteria **/ strcpy(str, p->name); LENGTH(str_descrip) = strlen(str); for (q = p->w_dids; q; q = q->next) { for (i = 0; i <= 2; i++) __FIB(fib,fib$r_did_overlay,fib$w_did[i]) = q->did[i]; filespec[0] = EOS; /* ** Initialize FIB to indicate to ACP that a directory ** look-up operation is desired. **/ __FIB(fib,fib$r_nmctl_overlay,fib$w_nmctl) = FIB$M_WILD; fib.fib$l_wcc = 0; check_OK(sys$qiow ( 0, q->chan, IO$_ACCESS, iosb, 0, 0, &fib_descrip, &str_descrip, &len, &filespec_descrip, 0, 0 )) while (iosb[0] == SS$_NORMAL || ((iosb[0] == SS$_NOPRIV || iosb[0] == SS$_NOSUCHFILE) && filespec[0])) { filespec[len] = EOS; /** Only full path name is needed **/ sprintf (temp_entry.fn, "%s%s", q->equivalent_name, filespec); insert_filelist_entry( head, temp_entry, cntrl_info_block.dir_dx[win].sortby, cntrl_info_block.dir_dx[win].sortorder); check_OK(sys$qiow ( 0, q->chan, IO$_ACCESS, iosb, 0, 0, &fib_descrip, &str_descrip, &len, &filespec_descrip, 0, 0 )) } } } /* ** Delete a file from non-directory file list if it is no ** longer belong to the list due to an insertion of ** another file (i.e. remove A.A;13 if A.A;14 was added ** in this directory and the file spec is *.*; for the ** latest version.) **/ for (u = head->forward; u != head; u = u->forward) { if (!strcmp (candidate_file, u->fn)) { for (s = cntrl_info_block.dir_dx[win].non_dir_filelist->forward; s != cntrl_info_block.dir_dx[win].non_dir_filelist; s = s->forward) { find_full_path_name(s->fn, fn, win); for (t = head->forward; t != head; t = t->forward) { if (!strcmp (fn, t->fn)) { break; } } if (t == head) { filer_delete$2(fn, errmsg, win); break; } } found++; break; } } free_filelist(&head); return found; } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** FIND_QUEUE_FILE() matchs the file with all the files in the ** cache queue that meets the filter 'NAME' criteria. It return 1 ** if there's a match; otherwise, 0 is returned. ** **-- **/ int find_queue_file(candidate_fid, elementp) unsigned short int candidate_fid[3]; struct filer_cache_tag *elementp; { /* ** VARIABLES USED BY ACP SERVICES **/ unsigned int iosb[2]; static struct fibdef fib; struct dsc$descriptor_s fib_descrip = { sizeof (struct fibdef), DSC$K_DTYPE_T, DSC$K_CLASS_S, (char *)&fib }; unsigned short len; char filespec[MAXFILESPEC+1]; $DESCRIPTOR (filespec_descrip, filespec); /* ** NON-ACP VARABLES **/ register int i; char str[128]; $DESCRIPTOR (str_descrip, str); int total_dids; char equ_name[MAXFILESPEC+1]; int total_devices; char dev_name[MAXFILESPEC+1]; struct filespec_list_tag *p; struct w_dids_tag *q; char fn[MAXFILESPEC+1]; struct fil_dx_tag *head; struct fil_dx_tag temp_entry, *s, *t, *u; int found = 0; char errmsg[256]; if ((head = create_MARKER()) == (struct fil_dx_tag *)NULL) { signal_err("Insufficient virtual memory", bell); return 0; } total_dids = 0; equ_name[0] = EOS; total_devices = 0; dev_name[0] = EOS; for (p = elementp->cur_filter.name_filespec_list; p; p = p->next) { for (q = p->w_dids; q; q = q->next) { size_t len; if (strcmp (q->equivalent_name, equ_name)) { total_dids++; strcpy (equ_name, q->equivalent_name); } len = strcspn (q->equivalent_name, "["); if (strncmp (q->equivalent_name, dev_name, len)) { total_devices++; strncpy (dev_name, q->equivalent_name, len); } } } /* ** Search for all files that match the filespec **/ for (p = elementp->cur_filter.name_filespec_list; p; p = p->next) { /* ** Find all the files in this directory that meet the criteria **/ strcpy(str, p->name); LENGTH(str_descrip) = strlen(str); for (q = p->w_dids; q; q = q->next) { for (i = 0; i <= 2; i++) __FIB(fib,fib$r_did_overlay,fib$w_did[i]) = q->did[i]; filespec[0] = EOS; /* ** Initialize FIB to indicate to ACP that a directory ** look-up operation is desired. **/ __FIB(fib,fib$r_nmctl_overlay,fib$w_nmctl) = FIB$M_WILD; fib.fib$l_wcc = 0; check_OK(sys$qiow ( 0, q->chan, IO$_ACCESS, iosb, 0, 0, &fib_descrip, &str_descrip, &len, &filespec_descrip, 0, 0 )) while (iosb[0] == SS$_NORMAL || ((iosb[0] == SS$_NOPRIV || iosb[0] == SS$_NOSUCHFILE) && filespec[0])) { filespec[len] = EOS; if (total_dids <= 1) { strcpy(temp_entry.fn, filespec); } else if (total_devices <= 1) { sprintf (temp_entry.fn, "%s%s", strchr (q->equivalent_name, '['), filespec); } else { sprintf (temp_entry.fn, "%s%s", q->equivalent_name, filespec); } for (i = 0; i <= 2; i++) { temp_entry.fid[i] = __FIB(fib,fib$r_fid_overlay,fib$w_fid[i]); } insert_filelist_entry( head, temp_entry, elementp->sortby, elementp->sortorder); check_OK(sys$qiow ( 0, q->chan, IO$_ACCESS, iosb, 0, 0, &fib_descrip, &str_descrip, &len, &filespec_descrip, 0, 0 )) } } } /* ** Delete a file from non-directory file list if it is no ** longer belong to the list due to an insertion of ** another file (i.e. remove A.A;13 if A.A;14 was added ** in this directory and the file spec is *.*; for the ** latest version.) **/ for (u = head->forward; u != head; u = u->forward) { if (candidate_fid[0] == u->fid[0] && candidate_fid[1] == u->fid[1] && candidate_fid[2] == u->fid[2]) { for (s = elementp->non_dir_filelist->forward; s != elementp->non_dir_filelist; s = s->forward) { for (t = head->forward; t != head; t = t->forward) { if (s->fid[0] == t->fid[0] && s->fid[1] == t->fid[1] && s->fid[2] == t->fid[2]) { break; } } if (t == head) { /** This file is no longer belong to the list **/ elementp->tot_files--; elementp->tot_blocks -= s->filesize; remove_filelist_entry(&s); break; } } found++; break; } } free_filelist(&head); return found; } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** tbs ** **-- **/ struct fil_dx_tag * create_MARKER() { struct fil_dx_tag *MARKER; int allocate_size; /* ** Allocate virtual memory for MARKER **/ allocate_size = sizeof (struct fil_dx_tag); check_OK(lib$get_vm ( &allocate_size, &MARKER, 0)) /* ** Initialize MARKER **/ MARKER->fid[0] = MARKER->fid[1] = MARKER->fid[2] = 0; MARKER->did[0] = MARKER->did[1] = MARKER->did[2] = 0; MARKER->fn[0] = EOS; MARKER->filesize = 0; MARKER->fpro = 0xffff; MARKER->state = waiting; MARKER->beg_y = MARKER->beg_x = 0; MARKER->forward = MARKER->backward = MARKER; return MARKER; } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** ADD_FILELIST_ENTRY() insert a entry to the list ** **-- **/ int add_filelist_entry(before, after, current) struct fil_dx_tag *before; struct fil_dx_tag *after; struct fil_dx_tag *current; { /* ** Test if FORWARD and BACKWARD links are correct **/ if (before->forward != after) return DX__ERROR; if (before != after->backward) return DX__ERROR; /* ** Re-link with new entry **/ before->forward = current; current->backward = before; after->backward = current; current->forward = after; return DX__NORMAL; } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** FREE_FILELIST() frees up the memory used by the list ** **-- **/ int free_filelist(MARKER) struct fil_dx_tag **MARKER; { struct fil_dx_tag *f, *g; if (*MARKER != (struct fil_dx_tag *)NULL) { f = (*MARKER)->forward; while (f != *MARKER) { g = f->forward; remove_filelist_entry(&f); f = g; } remove_filelist_entry(MARKER); *MARKER = (struct fil_dx_tag *)NULL; } return DX__NORMAL; } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** REMOVE_FILELIST_ENTRY() removes a entry from the list ** **-- **/ int remove_filelist_entry(file_entry) struct fil_dx_tag **file_entry; { struct fil_dx_tag *before, *after; int allocate_size; before = (*file_entry)->backward; after = (*file_entry)->forward; before->forward = after; after->backward = before; allocate_size = sizeof (struct fil_dx_tag); check_OK(lib$free_vm( &allocate_size, file_entry, 0)) return DX__NORMAL; } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** INSERT_FILELIST_ENTRY() finds a slot to insert a new entry. ** It searchs starting from the list head using the current sorting ** cirteria and order. ** **-- **/ int insert_filelist_entry(l, e, sortby, sortorder) struct fil_dx_tag *l; struct fil_dx_tag e; enum sortbys sortby; enum sortorders sortorder; { struct fil_dx_tag *f, *g; int allocate_size; int i; int (*cmpfunc)(struct fil_dx_tag *, struct fil_dx_tag *, enum sortorders); if (e.fn[strlen(e.fn)-1] == ']') { cmpfunc = sort_by_dir; } else { switch (sortby) { case sortname: cmpfunc = sort_by_name; break; case sorttype: cmpfunc = sort_by_type; break; case sortcredate: cmpfunc = sort_by_credate; break; case sortrevdate: cmpfunc = sort_by_revdate; break; case sortexpdate: cmpfunc = sort_by_expdate; break; case sortbakdate: cmpfunc = sort_by_bakdate; break; case sortsize: cmpfunc = sort_by_size; break; case sortmark: cmpfunc = sort_by_mark; break; } } for (g = l->forward; g != l; g = g->forward) { if (e.did[0] == g->did[0] && e.did[1] == g->did[1] && e.did[2] == g->did[2]) { if (!strcmp (g->fn, e.fn)) { /** A file with the same name found **/ return DX__DONTCARE; } if (sortorder == ascending) { if ((*cmpfunc)(&e, g, ascending) <= 0) break; } else { if ((*cmpfunc)(&e, g, descending) >= 0) break; } } } /* ** Allocate virtual memory for the new entry **/ allocate_size = sizeof (struct fil_dx_tag); check_OK(lib$get_vm ( &allocate_size, &f, 0)) for (i = 0; i <= 2; i++) { f->fid[i] = e.fid[i]; f->did[i] = e.did[i]; } f->filesize = e.filesize; memcpy(&f->cdat, &e.cdat, sizeof (DATE_TIME)); memcpy(&f->rdat, &e.rdat, sizeof (DATE_TIME)); memcpy(&f->edat, &e.edat, sizeof (DATE_TIME)); memcpy(&f->bdat, &e.bdat, sizeof (DATE_TIME)); f->fpro = e.fpro; strcpy(f->fn, e.fn); f->state = e.state; f->beg_y = e.beg_y; f->beg_x = e.beg_x; f->forward = e.forward; f->backward = e.backward; return add_filelist_entry(g->backward, g, f); }