/***************************************************************************** Application ASH: chmod.c (c) Pierre Adriaans 1994 ------------------------------------------------------------------------------ Module de gestion des chmod. *****************************************************************************/ #include "ash.h" /* Table de mode */ struct ModTable_s { int On; /* Flag On ou Off */ int Mode; /* Valeur du flag */ }; typedef struct ModTable_s ModTable_t; /* Table complete initialisee a Off */ static ModTable_t ModTable[12] = { { 0,S_IRUSR }, { 0,S_IWUSR }, { 0,S_IXUSR }, { 0,S_IRGRP }, { 0,S_IWGRP }, { 0,S_IXGRP }, { 0,S_IROTH }, { 0,S_IWOTH }, { 0,S_IXOTH }, { 0,S_ISUID }, { 0,S_ISGID }, { 0,S_ISVTX } }; extern DirList_t *List[NB_MAX_WINS], *Current[NB_MAX_WINS], *Dummy; extern AnswerBoxItem_t *InfoMsg; extern int AL; extern char DummyStr[DUMMYSTR_SIZE],WorkingDir[NB_MAX_WINS][FILENAME_LENGTH]; extern InvZone_t InvZone[NB_MAX_WINS]; /***************************************************************************** ChangeMod() ------------------------------------------------------------------------------ Input,Output: / Process: achangement du mode d'un ou de plusieurs fichiers en interractif *****************************************************************************/ void ChangeMod(void) { int Nb,i,l,c,Key,Mode,On; char Line[60]; ModTable_t ModTableOn[12],ModTableOff[12]; GetNbTagged(List[AL],&Nb,&i); if(Nb == 0 && strcmp(Current[AL]->Info.Name,"..") == 0) { InitAnswerBoxItem(&InfoMsg); AddAnswerBoxItem(&InfoMsg,"Changing mode for '..' is too dangerous."); InfoBox(ErrorNorm,ErrorInv," Change Mode ",InfoMsg,0,0,DOUBLE_FRAMED); return; } if(Nb == 0) { Line[0] = F_BDSD; for(i=1;i<43;i++) Line[i] = F_S_HO; Line[i] = F_SDBD; Line[i+1] = 0; /* Changement pour le fichier courant */ for(i=0;i<12;i++) if(__TEST__(Current[AL]->Info.s.st_mode,ModTable[i].Mode)) ModTable[i].On = 1; else ModTable[i].On = 0; OpenWin(3,15,20,50,FileOpNorm,UNFRAMED,SHADED); PaintFrame(4,18,18,44,FileOpNorm,DOUBLE_FRAMED); WriteString(Line,FileOpNorm,7,18); WriteString(Line,FileOpNorm,17,18); SetActiveWindow(5,20,16,41); if(IS_DIR(Current[AL]->Info.s.st_mode)) { WriteString("Changing mode for the directory",FileOpNorm,5,24); if(strlen(Current[AL]->Info.Name + 1) < 40) WriteString(Current[AL]->Info.Name + 1,FileOpNorm,6, 39 - strlen(Current[AL]->Info.Name + 1) / 2); else { strcpy(DummyStr,"/..."); strcat(DummyStr,Current[AL]->Info.Name + 1 + (strlen(Current[AL]->Info.Name + 1) - 33)); WriteString(DummyStr,FileOpNorm,6,39 - strlen(DummyStr) / 2); } } else { WriteString("Changing mode for the file",FileOpNorm,5,27); if(strlen(Current[AL]->Info.Name) < 40) WriteString(Current[AL]->Info.Name,FileOpNorm,6, 39 - strlen(Current[AL]->Info.Name) / 2); else { strcpy(DummyStr,"/..."); strcat(DummyStr,Current[AL]->Info.Name + (strlen(Current[AL]->Info.Name) - 33)); WriteString(DummyStr,FileOpNorm,6,39 - strlen(DummyStr) / 2); } } GotoXY(8,20); Printf(" User: Read [ ] Set-uid [ ]\n"); Printf(" Write [ ] Set-gid [ ]\n"); Printf(" Execute [ ] Sticky bit [ ]\n"); Printf(" Group: Read [ ]\n"); Printf(" Write [ ]\n"); Printf(" Execute [ ]\n"); Printf(" Other: Read [ ]\n"); Printf(" Write [ ]\n"); Printf(" Execute [ ]\n"); GotoXY(18,20); Printf("Up/Down arrows to move, Space to change.\n"); Printf(" Enter to change mode to settings.\n"); Printf(" Ctrl-C (Esc) to cancel."); for(i=0,l=8,c=38; i<9; i++,l++) if(ModTable[i].On) PutChar('X',l,c); for(l=8,c=56; i<12; i++,l++) if(ModTable[i].On) PutChar('X',l,c); l=8; c=38; i=0; GotoXY(l,c); fflush(stdout); while((Key = ReadKbd()) != CR) { switch(Key) { case K_DOWN: if(i<11) { i++; if(i == 9) { l=8; c=56; } else l++; GotoXY(l,c); } break; case CTRL_C: case DELETE: case ESC: CloseWin(); return; break; case K_UP: if(i>0) { i--; if(i==8) { l=16; c=38; } else l--; GotoXY(l,c); } break; case SPACE: ModTable[i].On = !ModTable[i].On; if(ModTable[i].On) PutChar('X',l,c); else PutChar(' ',l,c); } fflush(stdout); } CloseWin(); Mode = Current[AL]->Info.s.st_mode; for(i=0;i<12;i++) if(ModTable[i].On) Mode |= ModTable[i].Mode; else Mode &= ~(ModTable[i].Mode); strcpy(DummyStr,WorkingDir[AL]); if(DummyStr[strlen(DummyStr) - 1] != PATH_SEPARATOR_CHAR) strcat(DummyStr,PATH_SEPARATOR_STR); if(IS_DIR(Current[AL]->Info.s.st_mode)) strcat(DummyStr,(Current[AL]->Info.Name) + 1); else strcat(DummyStr,Current[AL]->Info.Name); if(chmod(DummyStr,Mode) == -1) { InitAnswerBoxItem(&InfoMsg); if(IS_DIR(Current[AL]->Info.s.st_mode)) AddAnswerBoxItem(&InfoMsg, "Impossible to change the mode for the directory"); else AddAnswerBoxItem(&InfoMsg, "Impossible to change the mode for the file"); AddAnswerBoxItem(&InfoMsg,DummyStr); switch(errno) { case ENOENT: AddAnswerBoxItem(&InfoMsg,"File or directory not found."); break; case EACCES: case EPERM: AddAnswerBoxItem(&InfoMsg,"Permission denied."); break; case EROFS: AddAnswerBoxItem(&InfoMsg,"File system is read-only."); break; case ENOLINK: AddAnswerBoxItem(&InfoMsg,"Remote link no longer active."); break; case EMULTIHOP: AddAnswerBoxItem(&InfoMsg,"Multiple remote machines link."); break; } InfoBox(ErrorNorm,ErrorInv," Change Mode ",InfoMsg,0,0,DOUBLE_FRAMED); } else Current[AL]->Info.s.st_mode = Mode; } else { Line[0] = F_BDSD; for(i=1;i<53;i++) Line[i] = F_S_HO; Line[i] = F_SDBD; Line[i+1] = 0; memcpy(ModTableOn,ModTable,sizeof(struct ModTable_s) * 12); memcpy(ModTableOff,ModTable,sizeof(struct ModTable_s) * 12); for(i=0;i<12;i++) { ModTableOn[i].On = 0; ModTableOff[i].On = 0; } OpenWin(3,10,20,60,FileOpNorm,UNFRAMED,SHADED); PaintFrame(4,13,18,54,FileOpNorm,DOUBLE_FRAMED); WriteString(Line,FileOpNorm,6,13); WriteString(Line,FileOpNorm,17,13); SetActiveWindow(5,15,16,51); sprintf(DummyStr,"Changing mode for %d files",Nb); WriteString(DummyStr,FileOpNorm,5,39 - strlen(DummyStr) / 2); GotoXY(7,15); Printf(" Set Unset Set Unset\n"); Printf(" User: Read [ ] [ ] Set-uid [ ] [ ]\n"); Printf(" Write [ ] [ ] Set-gid [ ] [ ]\n"); Printf(" Execute [ ] [ ] Sticky bit [ ] [ ]\n"); Printf(" Group: Read [ ] [ ]\n"); Printf(" Write [ ] [ ]\n"); Printf(" Execute [ ] [ ]\n"); Printf(" Other: Read [ ] [ ]\n"); Printf(" Write [ ] [ ]\n"); Printf(" Execute [ ] [ ]\n"); GotoXY(18,15); Printf("Up/Down/Left/Right arrows to move, Space to change\n"); Printf(" Enter to change modes to settings.\n"); Printf(" Ctrl-C (Esc) to cancel."); i = 0; l = 8; c = 33; On = 1; GotoXY(l,c); fflush(stdout); while((Key = ReadKbd()) != CR) { switch(Key) { case K_DOWN: if(i<11) { i++; if(i == 9) { c += 22; l = 8; } else l++; GotoXY(l,c); } break; case K_UP: if(i>0) { i--; if(i == 8) { c -= 22; l = 16; } else l--; GotoXY(l,c); } break; case K_LEFT: case K_RIGHT: if(On) c += 4; else c -=4; On = !On; GotoXY(l,c); break; case SPACE: if(On) { ModTableOn[i].On = !ModTableOn[i].On; if(ModTableOn[i].On) PutChar('X',l,c); else PutChar(' ',l,c); } else { ModTableOff[i].On = !ModTableOff[i].On; if(ModTableOff[i].On) PutChar('X',l,c); else PutChar(' ',l,c); } break; case ESC: case DELETE: case CTRL_C: CloseWin(); return; } fflush(stdout); } CloseWin(); for(Dummy = List[AL]; Dummy != (DirList_t *)NULL; Dummy = Dummy->Suivant) if(Dummy->Info.Tagged) { Mode = Dummy->Info.s.st_mode; for(i=0;i<12;i++) { if(ModTableOn[i].On) Mode |= ModTableOn[i].Mode; if(ModTableOff[i].On) Mode &= ~(ModTableOff[i].Mode); } strcpy(DummyStr,WorkingDir[AL]); if(DummyStr[strlen(DummyStr) - 1] != PATH_SEPARATOR_CHAR) strcat(DummyStr,PATH_SEPARATOR_STR); if(IS_DIR(Dummy->Info.s.st_mode)) strcat(DummyStr,(Dummy->Info.Name) + 1); else strcat(DummyStr,Dummy->Info.Name); if(chmod(DummyStr,Mode) == -1) { InitAnswerBoxItem(&InfoMsg); if(IS_DIR(Dummy->Info.s.st_mode)) AddAnswerBoxItem(&InfoMsg, "Impossible to change the mode for the directory"); else AddAnswerBoxItem(&InfoMsg, "Impossible to change the mode for the file"); AddAnswerBoxItem(&InfoMsg,DummyStr); switch(errno) { case ENOENT: AddAnswerBoxItem(&InfoMsg,"File or directory not found."); break; case EACCES: case EPERM: AddAnswerBoxItem(&InfoMsg,"Permission denied."); break; case EROFS: AddAnswerBoxItem(&InfoMsg,"File system is read-only."); break; case ENOLINK: AddAnswerBoxItem(&InfoMsg,"Remote link no longer active."); break; case EMULTIHOP: AddAnswerBoxItem(&InfoMsg,"Multiple remote machines link."); break; } InfoBox(ErrorNorm,ErrorInv," Change Mode ",InfoMsg,0,0,DOUBLE_FRAMED); } else { Dummy->Info.Tagged = 0; Dummy->Info.s.st_mode = Mode; } } RedisplayWin(AL); if(Current[AL]->Info.Tagged) PaintString(InvZone[AL].Lig,InvZone[AL].Col, InvZone[AL].Length,MainWinTagRev); else PaintString(InvZone[AL].Lig,InvZone[AL].Col, InvZone[AL].Length,MainWinInv); } }