/* Program Name : FILERPRO.C */ /* Original Author : C. K. Hung */ /* Date : 17-MAY-1991 */ /* Program Description : */ /* : */ /* Revision History follows */ /* 03-Jun-1999 JL usage of __FIB */ #include "global.h" #include "dx.h" #include "filer.h" #include "filerpro.h" #include "filerque.h" #include "filersta.h" #include "inquire.h" #include #include #include /* ** ** INTERNAL FUNCTION PROTOTYPING ** **/ static int filer_protection$2(char *, unsigned short, char *, unsigned short); static int chprot$1(char *, unsigned short *, char *); /* **++ ** FUNCTIONAL DESCRIPTION: ** ** tbs ** **-- **/ int filer_protection() { if (DX_CURRENT_DIRECTORY.filemode == multiple) filer_multiple_protection(); else filer_single_protection(); return DX__NORMAL; } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** to be specified ** **-- **/ int filer_multiple_protection() { char errmsg[MAXFILESPEC+1]; char spro[5], /** PROTECTION CODES **/ opro[5], gpro[5], wpro[5]; char original_prot[28]; getpro(DX_CURRENT_FILE->fpro, spro, opro, gpro, wpro); strcpy(original_prot, "S"); if (strlen(spro) > 0) sprintf(original_prot, "%s%c%s", original_prot, ':', spro); strcat(original_prot, ","); strcat(original_prot, "O"); if (strlen(opro) > 0) sprintf(original_prot, "%s%c%s", original_prot, ':', opro); strcat(original_prot, ","); strcat(original_prot, "G"); if (strlen(gpro) > 0) sprintf(original_prot, "%s%c%s", original_prot, ':', gpro); strcat(original_prot, ","); strcat(original_prot, "W"); if (strlen(wpro) > 0) sprintf(original_prot, "%s%c%s", original_prot, ':', wpro); strcpy(errmsg, "Error setting file protection"); multi_get_userinput_and_exec( filer_protection$1, "Multiple Set Protection", "Enter File Protection Spec: ", original_prot, errmsg); return DX__NORMAL; } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** FILER_SINGLE_PROTECTION() calls FILER_PROTECTION$1 to change ** the file protection ** **-- **/ int filer_single_protection() { char errmsg[MAXFILESPEC+1]; char fn[MAXFILESPEC+1]; char spro[5], /** PROTECTION CODES **/ opro[5], gpro[5], wpro[5]; char original_prot[28]; if (!strcmp(DX_CURRENT_FILE->fn, "[-]")) { signal_err("Set protection of a parent directory file not allowed", bell); } else { find_full_path_name(DX_CURRENT_FILE->fn, fn, cntrl_info_block.cur_win); getpro(DX_CURRENT_FILE->fpro, spro, opro, gpro, wpro); strcpy(original_prot, "S"); if (strlen(spro) > 0) sprintf(original_prot, "%s%c%s", original_prot, ':', spro); strcat(original_prot, ","); strcat(original_prot, "O"); if (strlen(opro) > 0) sprintf(original_prot, "%s%c%s", original_prot, ':', opro); strcat(original_prot, ","); strcat(original_prot, "G"); if (strlen(gpro) > 0) sprintf(original_prot, "%s%c%s", original_prot, ':', gpro); strcat(original_prot, ","); strcat(original_prot, "W"); if (strlen(wpro) > 0) sprintf(original_prot, "%s%c%s", original_prot, ':', wpro); strcpy(errmsg, "Error setting file protections"); get_userinput_and_execute( filer_protection$1, "Set File Protection", "Enter File Protection Spec: ", original_prot, errmsg, fn); } return DX__NORMAL; } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** FILER_PROTECTION$1() calls FILER_PROTECTION$2 to ** change filer protection ** **-- **/ int filer_protection$1(protstr, from, errmsg) char *protstr; char *from; char *errmsg; { unsigned short protcode; int i; struct fil_dx_tag temp_entry; if (chprot(from, protstr, errmsg, &protcode) != DX__NORMAL) return DX__ERROR; if (filer_protection$2( from, protcode, errmsg, cntrl_info_block.cur_win) == DX__ERROR) { return DX__ERROR; } /* ** Update filer cache **/ if (filestat(from, &temp_entry, errmsg) == DX__ERROR) { return DX__ERROR; } if (update_filer_cache( temp_entry, change_to_filer_cache, errmsg) == DX__ERROR) { return DX__ERROR; } /** Update other windows **/ for (i = 0; i < cntrl_info_block.windows; i++) { if (i != cntrl_info_block.cur_win) { if (filer_protection$2(from, protcode, errmsg, i) == DX__ERROR) { return DX__ERROR; } } } return DX__NORMAL; } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** FILER_PROTECTION$2() changes file protection and ** update FILER display ** **-- **/ static int filer_protection$2( char *from, unsigned short protcode, char *errmsg, unsigned short win) { char full_path_name[MAXFILESPEC+1]; struct fil_dx_tag *p; char str[MAXFILESPEC+1]; $DESCRIPTOR(str_descrip, str); /* ** Update FILER **/ if (cntrl_info_block.cur_win == win) { p = DX_CURRENT_FILE; } else { for (p = cntrl_info_block.dir_dx[win].dir_filelist->forward; p != cntrl_info_block.dir_dx[win].non_dir_filelist; p = p->forward) { if (p == cntrl_info_block.dir_dx[win].dir_filelist) { p = cntrl_info_block.dir_dx[win].non_dir_filelist; } else { find_full_path_name(p->fn, full_path_name, win); if (!strcmp(full_path_name, from)) { break; } } } if (p == cntrl_info_block.dir_dx[win].non_dir_filelist) { return DX__NORMAL; } } p->fpro = protcode; format_filer_entry(p, str, win); if (cntrl_info_block.dir_dx[win].form == short_form) { LENGTH(str_descrip) = strlen(str); if (p->fn[ strlen(p->fn)-1 ] != ']') { check_OK(smg$put_chars ( &cntrl_info_block.dir_dx[win].filer_display.id, &str_descrip, &p->beg_y, &p->beg_x, 0, 0, 0, 0)) } else { check_OK(smg$put_chars ( &cntrl_info_block.dir_dx[win].filer_display.id, &str_descrip, &p->beg_y, &p->beg_x, 0, &SMG$M_BOLD, 0, 0)) } } else { if (p->fn[ strlen(p->fn)-1 ] != ']') { LENGTH(str_descrip) = strlen(str); check_OK(smg$put_chars ( &cntrl_info_block.dir_dx[win].filer_display.id, &str_descrip, &p->beg_y, &p->beg_x, &SMG$M_ERASE_TO_EOL, 0, 0, 0)) } else { LENGTH(str_descrip) = 1; check_OK(smg$put_chars ( &cntrl_info_block.dir_dx[win].filer_display.id, &str_descrip, &p->beg_y, &1, 0, 0, 0, 0)) memcpy (str, str+1, strlen(str)); LENGTH(str_descrip) = 30; check_OK(smg$put_chars ( &cntrl_info_block.dir_dx[win].filer_display.id, &str_descrip, &p->beg_y, &2, 0, &SMG$M_BOLD, 0, 0)) memcpy (str, str+30, strlen(str)-30+1); LENGTH(str_descrip) = strlen(str); check_OK(smg$put_chars ( &cntrl_info_block.dir_dx[win].filer_display.id, &str_descrip, &p->beg_y, &32, &SMG$M_ERASE_TO_EOL, 0, 0, 0)) } } check_OK(smg$set_cursor_abs ( &cntrl_info_block.dir_dx[win].filer_display.id, &p->beg_y, &p->beg_x)) return DX__NORMAL; } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** CHPROT() uses ACP services to change a file's protection. ** Use of RMS service will fail if the user tries to change ** a file's protection when he does not have WRITE or DELETE privilege. ** **-- **/ int chprot(from, protstr, errmsg, protcode) char *from; char *protstr; char *errmsg; unsigned short *protcode; { /** VARIABLES used by ACP **/ unsigned short int fpro; /** File Protection **/ struct { /** Access Control Block **/ unsigned short w_size; unsigned short w_type; char *l_addr; } acb[] = { { 2, ATR$C_FPRO, &fpro }, { 0, 0, (char *)NULL }, }; int iosb[2]; static struct fibdef fib; $DESCRIPTOR(fib_descriptor, (char *)&fib); char short_filename[MAXFILESPEC+1]; $DESCRIPTOR (filespec_descriptor, short_filename); unsigned short chan; /** I/O channel **/ /** LOCAL variables **/ char *cp; int status; int i; struct filespec_list_tag *s; /* ** Initialization for ACP **/ LENGTH(fib_descriptor) = sizeof (struct fibdef); for (i = 0; i <= 2; i++) __FIB(fib,fib$r_did_overlay,fib$w_did[i]) = DX_CURRENT_FILE->did[i]; if ((cp = strchr(from, ']')) == 0) strcpy(short_filename, from); else strcpy(short_filename, cp+1); /* ** Find the I/O channel for this file **/ for (s = DX_CURRENT_DIRECTORY.cur_filter.name_filespec_list; s != (struct filespec_list_tag *)NULL; s = s->next) { struct w_dids_tag *t; for (t = s->w_dids; t != (struct w_dids_tag *)NULL; t = t->next) { if (t->did[0] == DX_CURRENT_FILE->did[0] && t->did[1] == DX_CURRENT_FILE->did[1] && t->did[2] == DX_CURRENT_FILE->did[2]) { chan = t->chan; break; } } } LENGTH(filespec_descriptor) = strlen(short_filename); check_OK(sys$qiow (0, chan, IO$_ACCESS, iosb, 0, 0, &fib_descriptor, &filespec_descriptor, 0, 0, acb, 0)) if (iosb[0] != SS$_NORMAL) { /** No READ access **/ strcpy(errmsg, "Insufficient privilege for read operation"); return DX__ERROR; } else { *protcode = fpro; if ((status = chprot$1(protstr, protcode, errmsg)) == DX__NORMAL) fpro = *protcode; check_OK(sys$qiow (0, chan, IO$_MODIFY, iosb, 0, 0, &fib_descriptor, &filespec_descriptor, 0, 0, acb, 0)) if (iosb[0] != SS$_NORMAL) { /** No MODIFY access **/ strcpy(errmsg, "Error setting file protections - insufficient privileges"); return DX__ERROR; } } return status; } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** to be specified ** **-- **/ static int chprot$1(protstr, protcode, errmsg) char *protstr; unsigned short int *protcode; char *errmsg; { char *cp1, *cp2; unsigned short int clear_bits, set_bits; char protstr1[80]; strcpy(protstr1, protstr); cp1 = protstr1; cp2 = strchr(cp1, ','); while (cp2 != NULL) { *cp2 = EOS; if (getprotbits(cp1, &clear_bits, &set_bits) == -1) { strcpy(errmsg, "File protections syntax error, re-specify"); return -1; } *protcode &= ~clear_bits; *protcode |= set_bits; cp1 = cp2+1; cp2 = strchr(cp1, ','); } if (getprotbits(cp1, &clear_bits, &set_bits) == -1) { strcpy(errmsg, "File protections syntax error, re-specify"); return -1; } *protcode &= ~clear_bits; *protcode |= set_bits; return DX__NORMAL; } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** to be specified ** **-- **/ int getprotbits(protsubstr, clear_bitsp, set_bitsp) char *protsubstr; unsigned short int *clear_bitsp; unsigned short int *set_bitsp; { char *cp; int shifts; cp = protsubstr; switch (*cp) { case 'S': *clear_bitsp = 0xF; shifts = 0; break; case 'O': *clear_bitsp = 0xF0; shifts = 4; break; case 'G': *clear_bitsp = 0xF00; shifts = 8; break; case 'W': *clear_bitsp = 0xF000; shifts = 12; break; default: return -1; } cp++; *set_bitsp = 0xF; /** No access at all **/ if (*cp == ':') for (cp++; *cp; cp++) switch (*cp) { case 'r': case 'R': *set_bitsp &= 0xE; break; case 'w': case 'W': *set_bitsp &= 0xD; break; case 'e': case 'E': *set_bitsp &= 0xB; break; case 'd': case 'D': *set_bitsp &= 0x7; break; default: return -1; } else if (*cp != EOS) return -1; *set_bitsp = (*set_bitsp << shifts); return DX__NORMAL; }