/* * Choose Message Editor */ void Chg_FsMsged() { int z; char temp[81]; ReadExitinfo(); Enter(2); /* Now using the */ pout(LIGHTMAGENTA, BLACK, (char *)Language(372)); /* Line/Fullscreen/External */ colour(LIGHTCYAN, BLACK); snprintf(temp, 81, " %s ", Language(387 + (exitinfo.MsgEditor & 3))); PUTSTR(temp); /* Editor */ pout(LIGHTMAGENTA, BLACK, (char *)Language(390)); Enter(1); if (strlen(CFG.externaleditor)) /* Select: 1) Fullscreen editor, 2) External editor */ pout(WHITE, BLACK, (char *)Language(373)); else /* Select: 1) Fullscreen editor */ pout(WHITE, BLACK, (char *)Language(438)); alarm_on(); z = toupper(Readkey()); if (z == Keystroke(373, 0)) { exitinfo.MsgEditor = FSEDIT; Syslog('+', "User selected fullscreen editor"); } else if ((z == Keystroke(373, 1) && strlen(CFG.externaleditor))) { exitinfo.MsgEditor = EXTEDIT; Syslog('+', "User selected external editor"); } Enter(2); /* Now using the */ pout(LIGHTMAGENTA, BLACK, (char *)Language(372)); /* Line/Fullscreen/External */ colour(LIGHTCYAN, BLACK); snprintf(temp, 81, " %s ", Language(387 + (exitinfo.MsgEditor & 3))); PUTSTR(temp); /* Editor */ pout(LIGHTMAGENTA, BLACK, (char *)Language(390)); Enter(2); sleep(2); WriteExitinfo(); }
void CKeyState::fakeAllKeysUp() { Keystrokes keys; for (KeyButton i = 0; i < IKeyState::kNumButtons; ++i) { if (m_syntheticKeys[i] > 0) { keys.push_back(Keystroke(i, false, false, m_keyClientData[i])); m_keys[i] = 0; m_syntheticKeys[i] = 0; } } fakeKeys(keys, 1); }
void CKeyState::fakeAllKeysUp() { Keystrokes keys; for (KeyButton i = 0; i < IKeyState::kNumButtons; ++i) { if (m_syntheticKeys[i] > 0) { keys.push_back(Keystroke(i, false, false, m_keyClientData[i])); m_keys[i] = 0; m_syntheticKeys[i] = 0; } } fakeKeys(keys, 1); memset(&m_serverKeys, 0, sizeof(m_serverKeys)); m_activeModifiers.clear(); m_mask = pollActiveModifiers(); }
bool KeyState::fakeKeyUp(KeyButton serverID) { // if we haven't seen this button go down then ignore it KeyButton localID = m_serverKeys[serverID & kButtonMask]; if (localID == 0) { return false; } // get the sequence of keys to simulate key release Keystrokes keys; keys.push_back(Keystroke(localID, false, false, m_keyClientData[localID])); // note keys down --m_keys[localID]; --m_syntheticKeys[localID]; m_serverKeys[serverID] = 0; // check if this is a modifier ModifierToKeys::iterator i = m_activeModifiers.begin(); while (i != m_activeModifiers.end()) { if (i->second.m_button == localID && !i->second.m_lock) { // modifier is no longer down KeyModifierMask mask = i->first; ModifierToKeys::iterator tmp = i; ++i; m_activeModifiers.erase(tmp); if (m_activeModifiers.count(mask) == 0) { // no key for modifier is down so deactivate modifier m_mask &= ~mask; LOG((CLOG_DEBUG1 "new state %04x", m_mask)); } } else { ++i; } } // generate key events fakeKeys(keys, 1); return true; }
void CKeyMap::addKeystrokes(EKeystroke type, const KeyItem& keyItem, ModifierToKeys& activeModifiers, KeyModifierMask& currentState, Keystrokes& keystrokes) const { KeyButton button = keyItem.m_button; UInt32 data = keyItem.m_client; switch (type) { case kKeystrokePress: keystrokes.push_back(Keystroke(button, true, false, data)); if (keyItem.m_generates != 0) { if (!keyItem.m_lock || (currentState & keyItem.m_generates) == 0) { // add modifier key and activate modifier activeModifiers.insert(std::make_pair( keyItem.m_generates, keyItem)); currentState |= keyItem.m_generates; } else { // deactivate locking modifier activeModifiers.erase(keyItem.m_generates); currentState &= ~keyItem.m_generates; } } break; case kKeystrokeRelease: keystrokes.push_back(Keystroke(button, false, false, data)); if (keyItem.m_generates != 0 && !keyItem.m_lock) { // remove key from active modifiers std::pair<ModifierToKeys::iterator, ModifierToKeys::iterator> range = activeModifiers.equal_range(keyItem.m_generates); for (ModifierToKeys::iterator i = range.first; i != range.second; ++i) { if (i->second.m_button == button) { activeModifiers.erase(i); break; } } // if no more keys for this modifier then deactivate modifier if (activeModifiers.count(keyItem.m_generates) == 0) { currentState &= ~keyItem.m_generates; } } break; case kKeystrokeRepeat: keystrokes.push_back(Keystroke(button, false, true, data)); keystrokes.push_back(Keystroke(button, true, true, data)); // no modifier changes on key repeat break; case kKeystrokeClick: keystrokes.push_back(Keystroke(button, true, false, data)); keystrokes.push_back(Keystroke(button, false, false, data)); // no modifier changes on key click break; case kKeystrokeModify: case kKeystrokeUnmodify: if (keyItem.m_lock) { // we assume there's just one button for this modifier if (m_halfDuplex.count(button) > 0) { if (type == kKeystrokeModify) { // turn half-duplex toggle on (press) keystrokes.push_back(Keystroke(button, true, false, data)); } else { // turn half-duplex toggle off (release) keystrokes.push_back(Keystroke(button, false, false, data)); } } else { // toggle (click) keystrokes.push_back(Keystroke(button, true, false, data)); keystrokes.push_back(Keystroke(button, false, false, data)); } } else if (type == kKeystrokeModify) { // press modifier keystrokes.push_back(Keystroke(button, true, false, data)); } else { // release all the keys that generate the modifier that are // currently down std::pair<ModifierToKeys::const_iterator, ModifierToKeys::const_iterator> range = activeModifiers.equal_range(keyItem.m_generates); for (ModifierToKeys::const_iterator i = range.first; i != range.second; ++i) { keystrokes.push_back(Keystroke(i->second.m_button, false, false, i->second.m_client)); } } if (type == kKeystrokeModify) { activeModifiers.insert(std::make_pair( keyItem.m_generates, keyItem)); currentState |= keyItem.m_generates; } else { activeModifiers.erase(keyItem.m_generates); currentState &= ~keyItem.m_generates; } break; } }
bool CKeyMap::keysForKeyItem(const KeyItem& keyItem, SInt32& group, ModifierToKeys& activeModifiers, KeyModifierMask& currentState, KeyModifierMask desiredState, KeyModifierMask overrideModifiers, bool isAutoRepeat, Keystrokes& keystrokes) const { static const KeyModifierMask s_notRequiredMask = KeyModifierAltGr | KeyModifierNumLock | KeyModifierScrollLock; // add keystrokes to adjust the group if (group != keyItem.m_group) { group = keyItem.m_group; keystrokes.push_back(Keystroke(group, true, false)); } EKeystroke type; if (keyItem.m_dead) { // adjust modifiers for dead key if (!keysForModifierState(keyItem.m_button, group, activeModifiers, currentState, keyItem.m_required, keyItem.m_sensitive, 0, keystrokes)) { LOG((CLOG_DEBUG1 "unable to match modifier state for dead key %d", keyItem.m_button)); return false; } // press and release the dead key type = kKeystrokeClick; } else { // if this a command key then we don't have to match some of the // key's required modifiers. KeyModifierMask sensitive = keyItem.m_sensitive & ~overrideModifiers; // XXX -- must handle pressing a modifier. in particular, if we want // to synthesize a KeyID on level 1 of a KeyButton that has Shift_L // mapped to level 0 then we must release that button if it's down // (in order to satisfy a shift modifier) then press a different // button (any other button) mapped to the shift modifier and then // the Shift_L button. // match key's required state LOG((CLOG_DEBUG1 "state: %04x,%04x,%04x", currentState, keyItem.m_required, sensitive)); if (!keysForModifierState(keyItem.m_button, group, activeModifiers, currentState, keyItem.m_required, sensitive, 0, keystrokes)) { LOG((CLOG_DEBUG1 "unable to match modifier state (%04x,%04x) for key %d", keyItem.m_required, keyItem.m_sensitive, keyItem.m_button)); return false; } // match desiredState as closely as possible. we must not // change any modifiers in keyItem.m_sensitive. and if the key // is a modifier, we don't want to change that modifier. LOG((CLOG_DEBUG1 "desired state: %04x %04x,%04x,%04x", desiredState, currentState, keyItem.m_required, keyItem.m_sensitive)); if (!keysForModifierState(keyItem.m_button, group, activeModifiers, currentState, desiredState, ~(sensitive | keyItem.m_generates), s_notRequiredMask, keystrokes)) { LOG((CLOG_DEBUG1 "unable to match desired modifier state (%04x,%04x) for key %d", desiredState, ~keyItem.m_sensitive & 0xffffu, keyItem.m_button)); return false; } // repeat or press of key type = isAutoRepeat ? kKeystrokeRepeat : kKeystrokePress; } addKeystrokes(type, keyItem, activeModifiers, currentState, keystrokes); return true; }
const CKeyMap::KeyItem* CKeyMap::mapCharacterKey(Keystrokes& keys, KeyID id, SInt32 group, ModifierToKeys& activeModifiers, KeyModifierMask& currentState, KeyModifierMask desiredMask, bool isAutoRepeat) const { // find KeySym in table KeyIDMap::const_iterator i = m_keyIDMap.find(id); if (i == m_keyIDMap.end()) { // unknown key LOG((CLOG_DEBUG1 "key %04x is not on keyboard", id)); return NULL; } const KeyGroupTable& keyGroupTable = i->second; // find best key in any group, starting with the active group SInt32 keyIndex = -1; SInt32 numGroups = getNumGroups(); SInt32 groupOffset; LOG((CLOG_DEBUG1 "find best: %04x %04x", currentState, desiredMask)); for (groupOffset = 0; groupOffset < numGroups; ++groupOffset) { SInt32 effectiveGroup = getEffectiveGroup(group, groupOffset); keyIndex = findBestKey(keyGroupTable[effectiveGroup], currentState, desiredMask); if (keyIndex != -1) { LOG((CLOG_DEBUG1 "found key in group %d", effectiveGroup)); break; } } if (keyIndex == -1) { // no mapping for this keysym LOG((CLOG_DEBUG1 "no mapping for key %04x", id)); return NULL; } // get keys to press for key SInt32 effectiveGroup = getEffectiveGroup(group, groupOffset); const KeyItemList& itemList = keyGroupTable[effectiveGroup][keyIndex]; if (itemList.empty()) { return NULL; } const KeyItem& keyItem = itemList.back(); // make working copy of modifiers ModifierToKeys newModifiers = activeModifiers; KeyModifierMask newState = currentState; SInt32 newGroup = group; // add each key for (size_t j = 0; j < itemList.size(); ++j) { if (!keysForKeyItem(itemList[j], newGroup, newModifiers, newState, desiredMask, 0, isAutoRepeat, keys)) { LOG((CLOG_DEBUG1 "can't map key")); keys.clear(); return NULL; } } // add keystrokes to restore modifier keys if (!keysToRestoreModifiers(keyItem, group, newModifiers, newState, activeModifiers, keys)) { LOG((CLOG_DEBUG1 "failed to restore modifiers")); keys.clear(); return NULL; } // add keystrokes to restore group if (newGroup != group) { keys.push_back(Keystroke(group, true, true)); } // save new modifiers activeModifiers = newModifiers; currentState = newState; return &keyItem; }
const CKeyMap::KeyItem* CKeyMap::mapCommandKey(Keystrokes& keys, KeyID id, SInt32 group, ModifierToKeys& activeModifiers, KeyModifierMask& currentState, KeyModifierMask desiredMask, bool isAutoRepeat) const { static const KeyModifierMask s_overrideModifiers = 0xffffu; // find KeySym in table KeyIDMap::const_iterator i = m_keyIDMap.find(id); if (i == m_keyIDMap.end()) { // unknown key LOG((CLOG_DEBUG1 "key %04x is not on keyboard", id)); return NULL; } const KeyGroupTable& keyGroupTable = i->second; // find the first key that generates this KeyID const KeyItem* keyItem = NULL; SInt32 numGroups = getNumGroups(); for (SInt32 groupOffset = 0; groupOffset < numGroups; ++groupOffset) { SInt32 effectiveGroup = getEffectiveGroup(group, groupOffset); const KeyEntryList& entryList = keyGroupTable[effectiveGroup]; for (size_t i = 0; i < entryList.size(); ++i) { if (entryList[i].size() != 1) { // ignore multikey entries continue; } // only match based on shift; we're after the right button // not the right character. we'll use desiredMask as-is, // overriding the key's required modifiers, when synthesizing // this button. const KeyItem& item = entryList[i].back(); if ((item.m_required & KeyModifierShift & desiredMask) == (item.m_sensitive & KeyModifierShift & desiredMask)) { LOG((CLOG_DEBUG1 "found key in group %d", effectiveGroup)); keyItem = &item; break; } } if (keyItem != NULL) { break; } } if (keyItem == NULL) { // no mapping for this keysym LOG((CLOG_DEBUG1 "no mapping for key %04x", id)); return NULL; } // make working copy of modifiers ModifierToKeys newModifiers = activeModifiers; KeyModifierMask newState = currentState; SInt32 newGroup = group; // don't try to change CapsLock desiredMask = (desiredMask & ~KeyModifierCapsLock) | (currentState & KeyModifierCapsLock); // add the key if (!keysForKeyItem(*keyItem, newGroup, newModifiers, newState, desiredMask, s_overrideModifiers, isAutoRepeat, keys)) { LOG((CLOG_DEBUG1 "can't map key")); keys.clear(); return NULL; } // add keystrokes to restore modifier keys if (!keysToRestoreModifiers(*keyItem, group, newModifiers, newState, activeModifiers, keys)) { LOG((CLOG_DEBUG1 "failed to restore modifiers")); keys.clear(); return NULL; } // add keystrokes to restore group if (newGroup != group) { keys.push_back(Keystroke(group, true, true)); } // save new modifiers activeModifiers = newModifiers; currentState = newState; return keyItem; }
const CKeyMap::KeyItem* CKeyMap::mapKey(Keystrokes& keys, KeyID id, SInt32 group, ModifierToKeys& activeModifiers, KeyModifierMask& currentState, KeyModifierMask desiredMask, bool isAutoRepeat) const { LOG((CLOG_DEBUG1 "mapKey %04x (%d) with mask %04x, start state: %04x", id, id, desiredMask, currentState)); // handle group change if (id == kKeyNextGroup) { keys.push_back(Keystroke(1, false, false)); return NULL; } else if (id == kKeyPrevGroup) { keys.push_back(Keystroke(-1, false, false)); return NULL; } const KeyItem* item; switch (id) { case kKeyShift_L: case kKeyShift_R: case kKeyControl_L: case kKeyControl_R: case kKeyAlt_L: case kKeyAlt_R: case kKeyMeta_L: case kKeyMeta_R: case kKeySuper_L: case kKeySuper_R: case kKeyAltGr: case kKeyCapsLock: case kKeyNumLock: case kKeyScrollLock: item = mapModifierKey(keys, id, group, activeModifiers, currentState, desiredMask, isAutoRepeat); break; case kKeySetModifiers: if (!keysForModifierState(0, group, activeModifiers, currentState, desiredMask, desiredMask, 0, keys)) { LOG((CLOG_DEBUG1 "unable to set modifiers %04x", desiredMask)); return NULL; } return &m_modifierKeyItem; case kKeyClearModifiers: if (!keysForModifierState(0, group, activeModifiers, currentState, currentState & ~desiredMask, desiredMask, 0, keys)) { LOG((CLOG_DEBUG1 "unable to clear modifiers %04x", desiredMask)); return NULL; } return &m_modifierKeyItem; default: if (isCommand(desiredMask)) { item = mapCommandKey(keys, id, group, activeModifiers, currentState, desiredMask, isAutoRepeat); } else { item = mapCharacterKey(keys, id, group, activeModifiers, currentState, desiredMask, isAutoRepeat); } break; } if (item != NULL) { LOG((CLOG_DEBUG1 "mapped to %03x, new state %04x", item->m_button, currentState)); } return item; }
void Write_Email(void) { faddr *Dest = NULL; int i; char *orgbox; if (HasNoEmail()) return; orgbox = xstrcpy(sMailbox); SetEmailArea((char *)"mailbox"); WhosDoingWhat(READ_POST, NULL); clear(); for (i = 0; i < (TEXTBUFSIZE + 1); i++) Message[i] = (char *) calloc(MAX_LINE_LENGTH +1, sizeof(char)); Line = 1; Msg_New(); Enter(1); colour(LIGHTBLUE, BLACK); /* Posting message in area: */ pout(LIGHTBLUE, BLACK, (char *) Language(156)); PUTSTR((char *)"\"mailbox\""); Enter(2); /* From : */ pout(YELLOW, BLACK, (char *) Language(157)); if (CFG.EmailMode != E_PRMISP) { /* * If not permanent connected to the internet, use fidonet.org style addressing. */ Dest = fido2faddr(CFG.EmailFidoAka); snprintf(Msg.From, 101, "%s@%s (%s)", exitinfo.sUserName, ascinode(Dest, 0x2f), exitinfo.sUserName); } else snprintf(Msg.From, 101, "%s@%s (%s)", exitinfo.Name, CFG.sysdomain, exitinfo.sUserName); for (i = 0; i < strlen(Msg.From); i++) { if (Msg.From[i] == ' ') Msg.From[i] = '_'; if (Msg.From[i] == '@') break; } pout(CFG.MsgInputColourF, CFG.MsgInputColourB, Msg.From); Syslog('b', "Setting From: %s", Msg.From); Enter(1); /* To : */ pout(YELLOW, BLACK, (char *) Language(158)); colour(CFG.MsgInputColourF, CFG.MsgInputColourB); alarm_on(); GetstrU(Msg.To, 63); if ((strcmp(Msg.To, "")) == 0) { for (i = 0; i < (TEXTBUFSIZE + 1); i++) free(Message[i]); SetEmailArea(orgbox); free(orgbox); return; } /* Subject : */ pout(YELLOW, BLACK, (char *) Language(161)); colour(CFG.MsgInputColourF, CFG.MsgInputColourB); alarm_on(); GetstrP(Msg.Subject, 65, 0); mbse_CleanSubject(Msg.Subject); if ((strcmp(Msg.Subject, "")) == 0) { Enter(1); /* Abort Message [y/N] ?: */ pout(CYAN, BLACK, (char *) Language(162)); alarm_on(); if (toupper(Readkey()) == Keystroke(162, 0)) { for (i = 0; i < (TEXTBUFSIZE + 1); i++) free(Message[i]); SetEmailArea(orgbox); free(orgbox); return; } } Msg.Private = TRUE; if (Edit_Msg()) { Save_Email(FALSE); } for (i = 0; i < (TEXTBUFSIZE + 1); i++) free(Message[i]); SetEmailArea(orgbox); free(orgbox); }
/* * The panel bar under the message while email reading */ int EmailPanel(void) { int input; WhosDoingWhat(READ_POST, NULL); /* (A)gain, (N)ext, (L)ast, (R)eply, (E)nter, (D)elete, (Q)uit, e(X)port */ pout(WHITE, RED, (char *) Language(214)); if (exitinfo.Security.level >= CFG.sysop_access) PUTSTR((char *)", (!)"); PUTSTR((char *)": "); alarm_on(); input = toupper(Readkey()); if (input == '!') { if (exitinfo.Security.level >= CFG.sysop_access) { if (Kludges) Kludges = FALSE; else Kludges = TRUE; Read_a_Email(LastNum); } } else if (input == Keystroke(214, 0)) { /* (A)gain */ Read_a_Email(LastNum); } else if (input == Keystroke(214, 4)) { /* (P)ost */ Write_Email(); Read_a_Email(LastNum); } else if (input == Keystroke(214, 2)) { /* (L)ast */ if (LastNum > EmailBase.Lowest) LastNum--; Read_a_Email(LastNum); } else if (input == Keystroke(214, 3)) { /* (R)eply */ Reply_Email(TRUE); Read_a_Email(LastNum); } else if (input == Keystroke(214, 5)) { /* (Q)uit */ /* Quit */ pout(WHITE, BLACK, (char *) Language(189)); Enter(1); return FALSE; } else if (input == Keystroke(214, 7)) { /* e(X)port */ Export_a_Email(LastNum); Read_a_Email(LastNum); } else if (input == '+') { if (Msg.Reply) LastNum = Msg.Reply; Read_a_Email(LastNum); } else if (input == '-') { if (Msg.Original) LastNum = Msg.Original; Read_a_Email(LastNum); } else if (input == Keystroke(214, 6)) { /* (D)elete */ // Delete_EmailNum(LastNum); if (LastNum < EmailBase.Highest) { LastNum++; Read_a_Email(LastNum); } else { return FALSE; } } else { /* Next */ pout(WHITE, BLACK, (char *) Language(216)); if (LastNum < EmailBase.Highest) LastNum++; else return FALSE; Read_a_Email(LastNum); } return TRUE; }
/* * Scan for new files, called from menu. */ int NewfileScan(int AskStart) { FILE *pAreas; int ifDate, itDate; char *temp, *Date; int Found, Count = 0; _Tag T; struct _fdbarea *fdb_area = NULL; Date = calloc(81, sizeof(char)); temp = calloc(81, sizeof(char)); iLineCount = 2; arecno = 1; /* Reset Area Number to One */ if (AskStart) { Enter(2); /* Search for new since your last call [Y/n]: */ pout(LIGHTCYAN, BLACK, (char *) Language(273)); colour(CFG.InputColourF, CFG.InputColourB); if (toupper(Readkey()) == Keystroke(273, 1)) { Enter(1); /* Enter new date to search for [DD-MM-YYYY]: */ pout(GREEN, BLACK, (char *) Language(274)); colour(CFG.InputColourF, CFG.InputColourB); GetDate(temp, 10); } else { strcpy(temp, LastLoginDate); } } else { strcpy(temp, LastLoginDate); } Syslog('+', "NewfileScan() since %s", temp); clear(); /* File Search by Date */ pout(WHITE, BLACK, (char *) Language(275)); Enter(2); Date[0] = temp[6]; /* Swap the date around */ Date[1] = temp[7]; /* Instead of DD-MM-YYYY */ Date[2] = temp[8]; /* Let it equal YYYYMMDD */ Date[3] = temp[9]; /* Swap the date around */ Date[4] = temp[3]; /* Swap the date around */ Date[5] = temp[4]; /* because when you convert */ Date[6] = temp[0]; /* a string to an int you */ Date[7] = temp[1]; /* loose the front Zero */ Date[8] = '\0'; /* making the number smaller */ itDate = atol(Date); InitTag(); if ((pAreas = OpenFareas(FALSE)) == NULL) return 0; while (fread(&area, areahdr.recsize, 1, pAreas) == 1) { if ((Access(exitinfo.Security, area.LTSec)) && (area.Available) && (strlen(area.Password) == 0) && (area.New)) { if ((fdb_area = mbsedb_OpenFDB(arecno, 30))) { Sheader(); Found = FALSE; Nopper(); while (fread(&fdb, fdbhdr.recsize, 1, fdb_area->fp) == 1) { strcpy(temp, StrDateDMY(fdb.UploadDate)); /* Realloc Space for Date */ Date[0] = temp[6]; /* Swap the date around */ Date[1] = temp[7]; /* Instead of DD-MM-YYYY */ Date[2] = temp[8]; /* Let it equal YYYYMMDD */ Date[3] = temp[9]; /* Swap the date around */ Date[4] = temp[3]; /* Swap the date around */ Date[5] = temp[4]; /* because when you convert */ Date[6] = temp[0]; /* a string to an int you */ Date[7] = temp[1]; /* loose the front Zero */ Date[8] = '\0'; /* making the number smaller */ /* and invalid to this cause */ ifDate = atol(Date); if (ifDate >= itDate) { if (!Found) { Enter(2); if (iLC(2) == 1) { free(Date); free(temp); mbsedb_CloseFDB(fdb_area); fclose(pAreas); return 1; } Found = TRUE; } memset(&T, 0, sizeof(T)); T.Area = arecno; T.Active = FALSE; T.Size = fdb.Size; strncpy(T.SFile, fdb.Name, 12); strncpy(T.LFile, fdb.LName, 80); SetTag(T); Count++; if (ShowOneFile() == 1) { free(Date); free(temp); mbsedb_CloseFDB(fdb_area); fclose(pAreas); return 1; } } /* End of if */ } /* End of while */ mbsedb_CloseFDB(fdb_area); /* * Add 2 blank lines after found files. */ if (Found) { Enter(2); if (iLC(2) == 1) { free(Date); free(temp); fclose(pAreas); return 1; } } } /* End of open filebase */ } /* End of check new files scan */ arecno++; /* Go to next file area */ } /* End of Main */ if (Count) Syslog('+', "Found %d new files", Count); fclose(pAreas); Enter(1); if (Count) Mark(); else Pause(); free(temp); free(Date); return 1; }
/* * Edit the list of tagged files. */ void EditTaglist() { FILE *tf; int i, x, Fg, Count; char *temp; if ((tf = fopen("taglist", "r+")) == NULL) { Enter(1); /* No files tagged. */ pout(CFG.HiliteF, CFG.HiliteB, (char *) Language(361)); Enter(2); Pause(); return; } temp = calloc(81, sizeof(char)); if (utf8) chartran_init((char *)"CP437", (char *)"UTF-8", 'B'); while (TRUE) { clear(); fseek(tf, 0, SEEK_SET); Count = 0; /* # Area Active Size Cost File */ /* 123 12345 123456 12345678 12345 */ pout(CFG.HiliteF, CFG.HiliteB, (char *) Language(355)); Enter(1); colour(LIGHTGREEN, BLACK); PUTSTR(chartran(fLine_str(79))); while ((fread(&Tag, sizeof(Tag), 1, tf) == 1)) { Count++; if (Tag.Active) Fg = WHITE; else Fg = LIGHTGRAY; snprintf(temp, 81, "%3d ", Count); pout(Fg, BLACK, temp); Fg--; snprintf(temp, 81, "%5d ", Tag.Area); pout(Fg, BLACK, temp); Fg--; if (Tag.Active) /* Yes */ snprintf(temp, 81, "%-6s ", (char *) Language(356)); else /* No */ snprintf(temp, 81, "%-6s ", (char *) Language(357)); pout(Fg, BLACK, temp); Fg--; snprintf(temp, 81, "%8d ", (int)(Tag.Size)); pout(Fg, BLACK, temp); Fg--; snprintf(temp, 81, "%5d ", Tag.Cost); pout(Fg, BLACK, temp); Fg--; snprintf(temp, 81, "%s", Tag.LFile); pout(Fg, BLACK, temp); Enter(1); } colour(LIGHTGREEN, BLACK); PUTSTR(chartran(fLine_str(79))); /* (T)oggle active, (E)rase all, (ENTER) to continue: */ pout(WHITE, RED, (char *) Language(358)); i = toupper(Readkey()); colour(CFG.CRColourF, CFG.CRColourB); if (i == Keystroke(358, 0)) { Enter(2); /* Enter file number, 1.. */ snprintf(temp, 81, "%s%d ", (char *) Language(359), Count); PUTSTR(temp); GetstrC(temp, 5); x = atoi(temp); if ((x > 0) && (x <= Count)) { if (fseek(tf, (x - 1) * sizeof(Tag), SEEK_SET) == 0) { if (fread(&Tag, sizeof(Tag), 1, tf) == 1) { if (Tag.Active) Tag.Active = FALSE; else Tag.Active = TRUE; fseek(tf,(x - 1) * sizeof(Tag), SEEK_SET); fwrite(&Tag, sizeof(Tag), 1, tf); } } } } chartran_close(); if (i == Keystroke(358, 1)) { fclose(tf); unlink("taglist"); free(temp); return; } if ((i == '\r') || (i == '\n')) { fclose(tf); free(temp); return; } } }
/* * Select filearea, called from menu. */ void FileArea_List(char *Option) { FILE *pAreas; int iAreaCount = 6, Recno = 1, iOldArea, iAreaNum = 0; int iGotArea = FALSE; /* Flag to check if user typed in area */ int offset; char *temp; /* * Save old area, incase he picks a invalid area */ iOldArea = iAreaNumber; if ((pAreas = OpenFareas(FALSE)) == NULL) return; /* * Count howmany records there are */ fseek(pAreas, 0, SEEK_END); iAreaNum = (ftell(pAreas) - areahdr.hdrsize) / areahdr.recsize; /* * If there are menu options, select area direct. */ if (strlen(Option) != 0) { if (strcmp(Option, "F+") == 0) { while (TRUE) { iAreaNumber++; if (iAreaNumber > iAreaNum) iAreaNumber = 1; offset = areahdr.hdrsize + ((iAreaNumber - 1) * areahdr.recsize); if (fseek(pAreas, offset, 0) != 0) { printf("Can't move pointer here"); } fread(&area, areahdr.recsize, 1, pAreas); if ((Access(exitinfo.Security, area.LTSec)) && (area.Available) && (strlen(area.Password) == 0)) break; } } if (strcmp(Option, "F-") == 0) { while (TRUE) { iAreaNumber--; if (iAreaNumber < 1) iAreaNumber = iAreaNum; offset = areahdr.hdrsize + ((iAreaNumber - 1) * areahdr.recsize); if (fseek(pAreas, offset, 0) != 0) { printf("Can't move pointer here"); } fread(&area, areahdr.recsize, 1, pAreas); if ((Access(exitinfo.Security, area.LTSec)) && (area.Available) && (strlen(area.Password) == 0)) break; } } SetFileArea(iAreaNumber); Syslog('+', "File area %lu %s", iAreaNumber, sAreaDesc); fclose(pAreas); return; } /* * Interactive mode */ clear(); Enter(1); /* File Areas */ pout(CFG.HiliteF, CFG.HiliteB, (char *) Language(298)); Enter(2); temp = calloc(81, sizeof(char)); fseek(pAreas, areahdr.hdrsize, 0); while (fread(&area, areahdr.recsize, 1, pAreas) == 1) { if ((Access(exitinfo.Security, area.LTSec)) && (area.Available)) { area.Name[31] = '\0'; snprintf(temp, 81, "%5d", Recno); pout(WHITE, BLACK, temp); snprintf(temp, 81, " %c ", 46); pout(LIGHTBLUE, BLACK, temp); snprintf(temp, 81, "%-31s", area.Name); pout(CYAN, BLACK, temp); iAreaCount++; if ((iAreaCount % 2) == 0) { Enter(1); } else { PUTCHAR(' '); } } Recno++; if ((iAreaCount / 2) == rows) { /* More (Y/n/=/Area #): */ pout(CFG.MoreF, CFG.MoreB, (char *) Language(207)); /* * Ask user for Area or enter to continue */ colour(CFG.InputColourF, CFG.InputColourB); GetstrC(temp, 7); if (toupper(*(temp)) == Keystroke(207, 1)) break; if ((strcmp(temp, "")) != 0) { iGotArea = TRUE; break; } iAreaCount = 2; } } /* * If user type in area above during area listing * don't ask for it again */ if (!iGotArea) { Enter(1); /* Select Area: */ pout(CFG.HiliteF, CFG.HiliteB, (char *) Language(232)); colour(CFG.InputColourF, CFG.InputColourB); GetstrC(temp, 80); } /* * Check if user pressed ENTER */ if ((strcmp(temp, "")) == 0) { fclose(pAreas); return; } iAreaNumber = atoi(temp); /* * Do a check in case user enters a negative value */ if (iAreaNumber < 1) iAreaNumber = 1; offset = areahdr.hdrsize + ((iAreaNumber - 1) * areahdr.recsize); if (fseek(pAreas, offset, 0) != 0) printf("Can't move pointer there."); else fread(&area, areahdr.recsize, 1, pAreas); /* * Do a check if area is greater or less number than allowed, * security access level, is oke, and the area is active. */ if (iAreaNumber > iAreaNum || iAreaNumber < 1 || (Access(exitinfo.Security, area.LTSec) == FALSE) || (strlen(area.Name) == 0)) { Enter(1); /* Invalid area specified - Please try again ...*/ pout(LIGHTRED, BLACK, (char *) Language(233)); Enter(2); Pause(); fclose(pAreas); iAreaNumber = iOldArea; SetFileArea(iAreaNumber); free(temp); return; } SetFileArea(iAreaNumber); Syslog('+', "File area %lu %s", iAreaNumber, sAreaDesc); /* * Check if file area has a password, if it does ask user for it */ if ((strlen(area.Password)) > 2) { Enter(2); /* Please enter Area Password: */ pout(WHITE, BLACK, (char *) Language(299)); colour(CFG.InputColourF, CFG.InputColourB); GetstrC(temp, 20); Enter(1); if ((strcmp(temp, area.Password)) != 0) { /* Password is incorrect */ pout(LIGHTRED, BLACK, (char *) Language(234)); Syslog('!', "Incorrect File Area # %d password given: %s", iAreaNumber, temp); SetFileArea(iOldArea); } else { /* Password is correct */ pout(WHITE, BLACK, (char *) Language(235)); } Enter(2); Pause(); } free(temp); fclose(pAreas); }
/* * Delete files from home directory */ void Delete_Home() { char *temp, *temp1, msg[81]; int i; temp = calloc(PATH_MAX, sizeof(char)); temp1 = calloc(PATH_MAX, sizeof(char)); snprintf(temp, PATH_MAX, "%s/%s/wrk/", CFG.bbs_usersdir, exitinfo.Name); Enter(1); /* Please enter filename to delete: */ pout(LIGHTBLUE, BLACK, (char *) Language(292)); colour(CFG.InputColourF, CFG.InputColourB); GetstrC(temp1, 80); if (strcmp(temp1, "") == 0) { free(temp); free(temp1); return; } if (temp1[0] == '.') { Enter(1); /* Sorry you may not delete hidden files ...*/ pout(LIGHTRED, BLACK, (char *) Language(293)); } else { strcat(temp, temp1); if ((access(temp, R_OK)) == 0) { Enter(1); /* Delete file: */ /* Are you Sure? [Y/n]: */ snprintf(msg, 81, "%s %s, %s", (char *) Language(368), temp1, (char *) Language(369)); pout(LIGHTGREEN, BLACK, msg); i = toupper(Readkey()); if (i == Keystroke(369, 0) || i == 13) { i = unlink(temp); if (i == -1) { Enter(1); /* Unable to delete file ... */ pout(LIGHTRED, BLACK, (char *) Language(294)); } else { Syslog('+', "Delete %s from homedir", temp1); } } else { Enter(2); /* Aborting ... */ pout(DARKGRAY, BLACK, (char *) Language(116)); } } else { Enter(1); /* Invalid filename, please try again ... */ pout(LIGHTRED, BLACK, (char *) Language(295)); } } Enter(2); free(temp); free(temp1); Pause(); }
/* * Edit signature file with a simple line editor. */ int editsignature(void) { FILE *fp; int i, x; char *temp, *temp1; temp = calloc(PATH_MAX, sizeof(char)); temp1 = calloc(PATH_MAX, sizeof(char)); snprintf(temp, PATH_MAX, "%s/%s/.signature", CFG.bbs_usersdir, exitinfo.Name); while (TRUE) { Enter(1); /* Functions available: */ poutCR(CFG.HiliteF, CFG.HiliteB, (char *) Language(113)); Enter(1); /* (L)ist, (R)eplace text, (E)dit line, (A)bort, (S)ave */ pout(YELLOW, RED, (char *) Language(114)); Enter(2); /* Select: */ pout(CFG.HiliteF, CFG.HiliteB, (char *) Language(115)); alarm_on(); i = toupper(Readkey()); Enter(1); if (i == Keystroke(114, 3)) { /* Aborting... */ pout(CFG.HiliteF, CFG.HiliteB, (char *) Language(116)); Syslog('+', "User aborted .signature editor"); free(temp); free(temp1); return TRUE; } else if (i == Keystroke(114, 2)) { Enter(1); /* Edit which line: */ snprintf(temp, 80, " %s", (char *) Language(118)); pout(CFG.HiliteF, CFG.HiliteB, temp); colour(CFG.InputColourF, CFG.InputColourB); GetstrC(temp, 3); if ((strcmp(temp, "")) == 0) break; i = atoi(temp); if ((i < 1) || (i > MAXSIGLINES)) { Enter(1); /* Line does not exist. */ poutCR(LIGHTRED, BLACK, (char *) Language(119)); break; } x = strlen(sLiNE[i-1]); snprintf(temp, 80, "%d:", i); pout(LIGHTRED, BLACK, temp); pout(CFG.InputColourF, CFG.InputColourB, sLiNE[i-1]); GetstrP(sLiNE[i-1], LENSIGLINES-1, x); } else if (i == Keystroke(114, 0)) { /* List lines */ toprow(); for (i = 0; i < MAXSIGLINES; i++) { snprintf(temp, 80, "%d:", i+1); pout(LIGHTRED, BLACK, temp); poutCR(CFG.MoreF, CFG.MoreB, sLiNE[i]); } botrow(); } else if (i == Keystroke(114, 4)) { Enter(1); /* Saving... */ pout(CFG.HiliteF, CFG.HiliteB, (char *) Language(340)); /* Open TextFile for Writing NextUser Info */ snprintf(temp, PATH_MAX, "%s/%s/.signature", CFG.bbs_usersdir, exitinfo.Name); if ((fp = fopen(temp, "w")) == NULL) { WriteError("$Can't open %s", temp); free(temp); free(temp1); return TRUE; } for (i = 0; i < MAXSIGLINES; i++) { if (strlen(sLiNE[i])) fprintf(fp, "%s\n", sLiNE[i]); } fclose(fp); Syslog('+', "User Saved .signature"); free(temp); free(temp1); return TRUE; } else if (i == Keystroke(114, 1)) { Enter(1); /* Edit which line: */ pout(CFG.HiliteF, CFG.HiliteB, (char *) Language(118)); colour(CFG.InputColourF, CFG.InputColourB); GetstrC(temp, 3); if ((strcmp(temp, "")) == 0) break; i = atoi(temp); if ((i < 1) || (i > MAXSIGLINES)) { Enter(1); /* Line does not exist. */ poutCR(LIGHTRED, BLACK, (char *) Language(119)); break; } Enter(1); /* Line reads: */ poutCR(CFG.MoreF, CFG.MoreB, (char *) Language(186)); snprintf(temp, 81, "%d:%s", i, sLiNE[i-1]); poutCR(CFG.MoreF, CFG.MoreB, temp); Enter(1); /* Text to replace: */ pout(CFG.HiliteF, CFG.HiliteB, (char *) Language(195)); colour(CFG.InputColourF, CFG.InputColourB); GetstrC(temp, LENSIGLINES-1); if ((strcmp(temp, "")) == 0) break; /* Replacement text: */ pout(CFG.HiliteF, CFG.HiliteB, (char *) Language(196)); colour(CFG.InputColourF, CFG.InputColourB); GetstrC(temp1, LENSIGLINES-1); if ((strcmp(temp1, "")) == 0) break; strreplace(sLiNE[i-1], temp, temp1); } else Enter(1); } free(temp); free(temp1); return FALSE; }