User *login(int sd, SOCKADDR *c, int cLen, User *head, char *ipAddr) { char username[MAX_NAME_LEN]; char password[MAX_NAME_LEN]; User *user; int i; // Prompt for user name sendEncrypt(sd, "\nUsername: "******"\nPassword: ", BUFFER_SIZE, 0, c, cLen); sendDone(sd, c, cLen); recvDecrypt(sd, password, MAX_NAME_LEN, c, &cLen); // Search for the given username user = findUserByUsername(head, username); //Crypt(password, MAX_NAME_LEN, 0); // If found and password matches, return user type if (user && !strcmp(user->password, password)) { // Get IP address strcpy(user->ipAddr, ipAddr); return user; } return NULL; }
int changePassword(int sd, SOCKADDR *c, int cLen, User *user) { char buffer[BUFFER_SIZE]; char newP1[MAX_NAME_LEN]; char newP2[MAX_NAME_LEN]; // Dislpay selection sendEncrypt(sd, BORDER, BUFFER_SIZE, 0, c, cLen); sendEncrypt(sd, "\nYou selected option '3 - Change Password'\n\n", BUFFER_SIZE, 0, c, cLen); // Prompt for current password sendEncrypt(sd, "Please enter your current password: "******"\n\nPlease enter a new password: "******"%s", newP1); sendEncrypt(sd, "\n\nRe-enter the new password: "******"%s", newP2); } else { sendEncrypt(sd, "\n\nThe password you entered is not valid. Returning to the main menu.", BUFFER_SIZE, 0, c, cLen); sendEncrypt(sd, BORDER, BUFFER_SIZE, 0, c, cLen); return 0; } // Verify new password if (!strcmp(newP1, newP2)) { strcpy(user->password, newP1); sendEncrypt(sd, "\n\nPassword successfully changed.\n", BUFFER_SIZE, 0, c, cLen); } else { sendEncrypt(sd, "\n\nThe passwords you entered do not match. Your password is unchanged.", BUFFER_SIZE, 0, c, cLen); } sendEncrypt(sd, BORDER, BUFFER_SIZE, 0, c, cLen); return 0; }
DpmsInterface::DpmsInterface(OutputInterface *output, wl_resource *parentResource, DpmsManagerInterface *manager) : Resource(new Private(this, manager, parentResource, output)) { connect(output, &OutputInterface::dpmsSupportedChanged, this, [this] { sendSupported(); sendDone(); } ); connect(output, &OutputInterface::dpmsModeChanged, this, [this] { sendMode(); sendDone(); } ); }
char ynOption(char *message, int sd, SOCKADDR *c, int cLen) { char buffer[BUFFER_SIZE]; // Find length of message string //for (int i=0; message[i]!='\0'; i++) {} // Send message and Y/N option sendEncrypt(sd, message, BUFFER_SIZE, 0, c, cLen); sendEncrypt(sd, "Y/N? ", BUFFER_SIZE, 0, c, cLen); sendDone(sd, c, cLen); // Receive user response recvDecrypt(sd, buffer, BUFFER_SIZE, c, &cLen); if (!stricmp(buffer, "Y")) return TRUE; // return TRUE if yes else if (!stricmp(buffer, "N")) return FALSE; else if (!stricmp(buffer, "timeout")) return 'T'; // Indicates timeout occurred else { sendEncrypt(sd, "\n\nUnrecognized response. Returning to main menu.", BUFFER_SIZE, 0, c, cLen); return FALSE; } }
//-------------------------------------------------------------------------------------------------- void NextionComponent::command_txt(const char* value) { send(this->name); send(F2C(".txt=\"")); send(value); send(F2C("\"")); sendDone(); }
//-------------------------------------------------------------------------------------------------- void NextionComponent::command_click(bool isReleaseEvent) { send(F2C("click ")); send(this->name); send(","); send(isReleaseEvent ? "0" : "1"); sendDone(); }
//-------------------------------------------------------------------------------------------------- void NextionComponent::command_vis(uint8_t val) { send(F2C("vis ")); send(this->name); send(","); String s; s = val; send(s.c_str()); sendDone(); }
//-------------------------------------------------------------------------------------------------- void NextionComponent::send(const char* cmd,int32_t param) { String strParam; strParam = param; send(this->name); send("."); send(cmd); send("="); send(strParam.c_str()); sendDone(); }
//-------------------------------------------------------------------------------------------------- void NextionComponent::command_pconum(uint8_t val, uint16_t color) { String num; num = val; send(this->name); send(F2C(".pco")); send(num.c_str()); send("="); num = color; send(num.c_str()); sendDone(); }
TextIn::TextIn(QWidget *parent) : QMainWindow(parent), ui(new Ui::TextIn) { ui->setupUi(this); ui->buttonBox->button(QDialogButtonBox::Cancel)->hide(); ui->buttonBox->button(QDialogButtonBox::Ok)->setText("&Send"); ui->lenLabel->setText("0/"+QString::number(MAX_LEN)); m_settingsDlg = new SettingsDialog(this); firstrun(); m_waitingToLogin = false; m_talker = new Talker(this); connect(m_talker, SIGNAL(loginFinished(bool)), this, SLOT(loginDone(bool))); connect(m_talker, SIGNAL(sendFinished()), this, SLOT(sendDone())); login(); }
int seeBalanceSelected(int sd, SOCKADDR *c, int cLen, User *head) { int accountNum; char buffer[BUFFER_SIZE]; char result; User *customer; // Prompt user for account number sendEncrypt(sd, BORDER, BUFFER_SIZE, 0, c, cLen); sendEncrypt(sd, "\nYou selected option '1 - Report balance of a selected customer'\n\n", BUFFER_SIZE, 0, c, cLen); sendEncrypt(sd, "Account number of customer: ", BUFFER_SIZE, 0, c, cLen); sendDone(sd, c, cLen); // Receive account number RECV_DECRYPT(sd, buffer, BUFFER_SIZE, c, &cLen); if (sscanf(buffer, "%d", &accountNum) != 1) { sendEncrypt(sd, "\n\nError reading account number. Returning to main menu.", BUFFER_SIZE, 0, c, cLen); sendEncrypt(sd, BORDER, BUFFER_SIZE, 0, c, cLen); return 0; } // Search linked list for the selected account number if ( !(customer = findUserByAcctNum(head, accountNum)) ) { sendEncrypt(sd, "\n\nError. Account number does not exist in the database. Returning to main menu.", BUFFER_SIZE, 0, c, cLen); sendEncrypt(sd, BORDER, BUFFER_SIZE, 0, c, cLen); return 0; } // Send account information and prompt for more sprintf(buffer, "\n\n-->Balance of account %d: $%.2f\n\nWould you like to view another account? ", customer->acctNum, (float)customer->balance/100); // build display string if ((result = ynOption(buffer, sd, c, cLen)) == 'T') return -1; if (result) seeBalanceSelected(sd, c, cLen, head); // call this function recursively if additional lookups requested else sendEncrypt(sd, BORDER, BUFFER_SIZE, 0, c, cLen); return 0; }
scannerwindow::scannerwindow(QList<int> parameters, QMainWindow *parent, bool load, QTextStream* stream): QObject(parent) { this->parameters=parameters; widget = new QWidget(); widget->setAttribute(Qt::WA_DeleteOnClose); graph = new Q3DSurface(); container = QWidget::createWindowContainer(graph, widget); container->setAttribute(Qt::WA_AcceptTouchEvents); widget->setGeometry( QStyle::alignedRect( Qt::LeftToRight, Qt::AlignTop, widget->size(), qApp->desktop()->availableGeometry() ) ); bitmapForward=new QCustomPlot(widget); bitmapBackward=new QCustomPlot(widget); bitmapCombined=new QCustomPlot(widget); bitmapForward->setContextMenuPolicy(Qt::CustomContextMenu); bitmapBackward->setContextMenuPolicy(Qt::CustomContextMenu); bitmapCombined->setContextMenuPolicy(Qt::CustomContextMenu); bitmapBackward->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); bitmapForward->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); bitmapCombined->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); initializeBitmapForward(bitmapForward); initializeBitmapBackward(bitmapBackward); initializeBitmapCombined(bitmapCombined); if (!graph->hasContext()) { QMessageBox msgBox; msgBox.setText("Couldn't initialize the OpenGL context."); msgBox.exec(); } QSize screenSize = graph->screen()->size(); container->setMinimumSize(QSize(screenSize.width() / 3, screenSize.height()/4)); container->setMaximumSize(screenSize); container->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); container->setFocusPolicy(Qt::StrongFocus); bitmapBackward->setMinimumSize(screenSize.width()/4, screenSize.height()/4); bitmapForward->setMinimumSize(screenSize.width()/4, screenSize.height()/4); bitmapCombined->setMinimumSize(screenSize.width()/4, screenSize.height()/4); QHBoxLayout *hLayout = new QHBoxLayout(widget); QVBoxLayout *vLayout = new QVBoxLayout(); QSplitter *hSplitterMain = new QSplitter(); QSplitter *vSplitterRight = new QSplitter(); hLayout->setSizeConstraint(QBoxLayout::SizeConstraint::SetMinimumSize); vSplitterRight->addWidget(bitmapForward); vSplitterRight->addWidget(bitmapBackward); vSplitterRight->addWidget(bitmapCombined); vSplitterRight->setOrientation(Qt::Orientation::Vertical); vSplitterRight->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding)); hSplitterMain->setOrientation(Qt::Orientation::Horizontal); hSplitterMain->addWidget(container); hSplitterMain->addWidget(vSplitterRight); hSplitterMain->setStyleSheet("QSplitter::handle {background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0,stop:0 rgba(255, 255, 255, 0),stop:0.407273 rgba(200, 200, 200, 255),stop:0.4825 rgba(101, 104, 113, 235), stop:0.6 rgba(255, 255, 255, 0));}"); vSplitterRight->setStyleSheet("QSplitter::handle {background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0,stop:0 rgba(255, 255, 255, 0),stop:0.407273 rgba(200, 200, 200, 255),stop:0.4825 rgba(101, 104, 113, 235), stop:0.6 rgba(255, 255, 255, 0));}"); hLayout->addWidget(hSplitterMain); hLayout->addLayout(vLayout); vLayout->setAlignment(Qt::AlignTop); widget->setWindowTitle(QStringLiteral("AFM Scan")); QGroupBox *modelGroupBox = new QGroupBox(QStringLiteral("Scan")); if(!load){ AFM_Scan_3D_RB = new QPushButton(widget); AFM_Scan_3D_RB->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred)); AFM_Scan_3D_RB->setText(QStringLiteral("Start Scan")); AFM_Scan_3D_RB->setCheckable(true); AFM_Scan_3D_RB->setChecked(false); } SaveSurface = new QPushButton(widget); SaveSurface->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred)); SaveSurface->setText(QStringLiteral("Save Data")); BitmapView = new QPushButton(widget); BitmapView->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred)); BitmapView->setText(QStringLiteral("Save BMP")); QVBoxLayout *modelVBox = new QVBoxLayout; if(!load){ modelVBox->addWidget(AFM_Scan_3D_RB); } modelVBox->addWidget(BitmapView); modelVBox->addWidget(SaveSurface); modelGroupBox->setLayout(modelVBox); QGroupBox *selectionGroupBox = new QGroupBox(QStringLiteral("Selection Mode")); selectionGroupBox->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed)); QCheckBox *piezoMove = new QCheckBox(widget); piezoMove->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed)); piezoMove->setText(QStringLiteral("Piezo")); piezoMove->setChecked(true); modelVBox->addWidget(piezoMove); QRadioButton *modeNoneRB = new QRadioButton(widget); modeNoneRB->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed)); modeNoneRB->setText(QStringLiteral("No selection")); modeNoneRB->setChecked(false); QRadioButton *modeItemRB = new QRadioButton(widget); modeItemRB->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed)); modeItemRB->setText(QStringLiteral("Item")); modeItemRB->setChecked(false); QRadioButton *modeSliceRowRB = new QRadioButton(widget); modeSliceRowRB->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed)); modeSliceRowRB->setText(QStringLiteral("Row Slice")); modeSliceRowRB->setChecked(false); QRadioButton *modeSliceColumnRB = new QRadioButton(widget); modeSliceColumnRB->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed)); modeSliceColumnRB->setText(QStringLiteral("Column Slice")); modeSliceColumnRB->setChecked(false); QVBoxLayout *selectionVBox = new QVBoxLayout; selectionVBox->addWidget(modeNoneRB); selectionVBox->addWidget(modeItemRB); selectionVBox->addWidget(modeSliceRowRB); selectionVBox->addWidget(modeSliceColumnRB); selectionGroupBox->setLayout(selectionVBox); QSlider *axisCameraSliderZ = new QSlider(Qt::Horizontal, widget); axisCameraSliderZ->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred)); axisCameraSliderZ->setMinimum(0); axisCameraSliderZ->setMaximum(179); axisCameraSliderZ->setTickInterval(1); axisCameraSliderZ->setEnabled(true); QSlider *axisCameraSliderY = new QSlider(Qt::Horizontal, widget); axisCameraSliderY->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred)); axisCameraSliderY->setMinimum(0); axisCameraSliderY->setMaximum(180); axisCameraSliderY->setTickInterval(0); axisCameraSliderY->setEnabled(true); QComboBox *themeList = new QComboBox(widget); themeList->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed)); themeList->addItem(QStringLiteral("Qt")); themeList->addItem(QStringLiteral("Primary Colors")); themeList->addItem(QStringLiteral("Digia")); themeList->addItem(QStringLiteral("Stone Moss")); themeList->addItem(QStringLiteral("Army Blue")); themeList->addItem(QStringLiteral("Retro")); themeList->addItem(QStringLiteral("Ebony")); themeList->addItem(QStringLiteral("Isabelle")); QGroupBox *colorGroupBox = new QGroupBox(QStringLiteral("Custom gradient")); QLinearGradient grBtoY(0, 0, 1, 100); grBtoY.setColorAt(1.0, Qt::black); grBtoY.setColorAt(0.67, Qt::blue); grBtoY.setColorAt(0.33, Qt::red); grBtoY.setColorAt(0.0, Qt::yellow); QPixmap pm(24, 100); QPainter pmp(&pm); pmp.setBrush(QBrush(grBtoY)); pmp.setPen(Qt::NoPen); pmp.drawRect(0, 0, 24, 100); QPushButton *gradientBtoYPB = new QPushButton(widget); gradientBtoYPB->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed)); gradientBtoYPB->setIcon(QIcon(pm)); gradientBtoYPB->setIconSize(QSize(24, 100)); QLinearGradient grGtoR(0, 0, 1, 100); grGtoR.setColorAt(1.0, Qt::darkGreen); grGtoR.setColorAt(0.5, Qt::yellow); grGtoR.setColorAt(0.2, Qt::red); grGtoR.setColorAt(0.0, Qt::darkRed); pmp.setBrush(QBrush(grGtoR)); pmp.drawRect(0, 0, 24, 100); QPushButton *gradientGtoRPB = new QPushButton(widget); gradientGtoRPB->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed)); gradientGtoRPB->setIcon(QIcon(pm)); gradientGtoRPB->setIconSize(QSize(24, 100)); QHBoxLayout *colorHBox = new QHBoxLayout; colorHBox->addWidget(gradientBtoYPB); colorHBox->addWidget(gradientGtoRPB); colorGroupBox->setLayout(colorHBox); vLayout->addWidget(modelGroupBox); vLayout->addWidget(selectionGroupBox); vLayout->addWidget(new QLabel(QStringLiteral("Camera Position"))); vLayout->addWidget(axisCameraSliderZ); vLayout->addWidget(axisCameraSliderY); vLayout->addWidget(new QLabel(QStringLiteral("Theme"))); vLayout->addWidget(themeList); vLayout->addWidget(colorGroupBox); widget->show(); modifier= new SurfaceGraph(graph, widget,parameters); if(!load){ QObject::connect(parent, SIGNAL(plotDataReceived(QList <QByteArray>)), modifier, SLOT(dataHandler(QList <QByteArray>))); QObject::connect(AFM_Scan_3D_RB, SIGNAL (toggled(bool)), this, SLOT(AFMButtonHandler(bool))); QObject::connect(this, SIGNAL (AFMStart()), modifier, SLOT (enableAFMModel())); QObject::connect(this, SIGNAL (AFMDone()), parent, SLOT (sendDone())); QObject::connect(this, SIGNAL (AFMStart()), parent, SLOT (sendGo())); QObject::connect(this, SIGNAL (AFMStart()), parent, SLOT(sendReady()));}
void *updatethreadproc(void*) { char tempDir[PATH_MAX] = ""; /* Flawfinder: ignore */ FSRef tempDirRef; char temp[PATH_MAX] = ""; /* Flawfinder: ignore */ // *NOTE: This buffer length is used in a scanf() below. char deviceNode[1024] = ""; /* Flawfinder: ignore */ LLFILE *downloadFile = NULL; OSStatus err; ProcessSerialNumber psn; char target[PATH_MAX] = ""; /* Flawfinder: ignore */ FSRef targetRef; FSRef targetParentRef; FSVolumeRefNum targetVol; FSRef trashFolderRef; Boolean replacingTarget = false; memset(&tempDirRef, 0, sizeof(tempDirRef)); memset(&targetRef, 0, sizeof(targetRef)); memset(&targetParentRef, 0, sizeof(targetParentRef)); try { // Attempt to get a reference to the Second Life application bundle containing this updater. // Any failures during this process will cause us to default to updating /Applications/Second Life.app { FSRef myBundle; err = GetCurrentProcess(&psn); if(err == noErr) { err = GetProcessBundleLocation(&psn, &myBundle); } if(err == noErr) { // Sanity check: Make sure the name of the item referenced by targetRef is "Second Life.app". FSRefMakePath(&myBundle, (UInt8*)target, sizeof(target)); llinfos << "Updater bundle location: " << target << llendl; } // Our bundle should be in Second Life.app/Contents/Resources/AutoUpdater.app // so we need to go up 3 levels to get the path to the main application bundle. if(err == noErr) { err = FSGetCatalogInfo(&myBundle, kFSCatInfoNone, NULL, NULL, NULL, &targetRef); } if(err == noErr) { err = FSGetCatalogInfo(&targetRef, kFSCatInfoNone, NULL, NULL, NULL, &targetRef); } if(err == noErr) { err = FSGetCatalogInfo(&targetRef, kFSCatInfoNone, NULL, NULL, NULL, &targetRef); } // And once more to get the parent of the target if(err == noErr) { err = FSGetCatalogInfo(&targetRef, kFSCatInfoNone, NULL, NULL, NULL, &targetParentRef); } if(err == noErr) { FSRefMakePath(&targetRef, (UInt8*)target, sizeof(target)); llinfos << "Path to target: " << target << llendl; } // Sanity check: make sure the target is a bundle with the right identifier if(err == noErr) { // Assume the worst... err = -1; if(isFSRefViewerBundle(&targetRef)) { // This is the bundle we're looking for. err = noErr; replacingTarget = true; } } // Make sure the target's parent directory is writable. if(err == noErr) { if(!isDirWritable(targetParentRef)) { // Parent directory isn't writable. llinfos << "Target parent directory not writable." << llendl; err = -1; replacingTarget = false; } } if(err != noErr) { Boolean isDirectory; llinfos << "Target search failed, defaulting to /Applications/" << gProductName << ".app." << llendl; // Set up the parent directory err = FSPathMakeRef((UInt8*)"/Applications", &targetParentRef, &isDirectory); if((err != noErr) || (!isDirectory)) { // We're so hosed. llinfos << "Applications directory not found, giving up." << llendl; throw 0; } snprintf(target, sizeof(target), "/Applications/%s.app", gProductName); memset(&targetRef, 0, sizeof(targetRef)); err = FSPathMakeRef((UInt8*)target, &targetRef, NULL); if(err == fnfErr) { // This is fine, just means we're not replacing anything. err = noErr; replacingTarget = false; } else { replacingTarget = true; } // Make sure the target's parent directory is writable. if(err == noErr) { if(!isDirWritable(targetParentRef)) { // Parent directory isn't writable. llinfos << "Target parent directory not writable." << llendl; err = -1; replacingTarget = false; } } } // If we haven't fixed all problems by this point, just bail. if(err != noErr) { llinfos << "Unable to pick a target, giving up." << llendl; throw 0; } } // Find the volID of the volume the target resides on { FSCatalogInfo info; err = FSGetCatalogInfo( &targetParentRef, kFSCatInfoVolume, &info, NULL, NULL, NULL); if(err != noErr) throw 0; targetVol = info.volume; } // Find the temporary items and trash folders on that volume. err = FSFindFolder( targetVol, kTrashFolderType, true, &trashFolderRef); if(err != noErr) throw 0; #if 0 // *HACK for DEV-11935 see below for details. FSRef tempFolderRef; err = FSFindFolder( targetVol, kTemporaryFolderType, true, &tempFolderRef); if(err != noErr) throw 0; err = FSRefMakePath(&tempFolderRef, (UInt8*)temp, sizeof(temp)); if(err != noErr) throw 0; #else // *HACK for DEV-11935 the above kTemporaryFolderType query was giving // back results with path names that seem to be too long to be used as // mount points. I suspect this incompatibility was introduced in the // Leopard 10.5.2 update, but I have not verified this. char const HARDCODED_TMP[] = "/tmp"; strncpy(temp, HARDCODED_TMP, sizeof(HARDCODED_TMP)); #endif // 0 *HACK for DEV-11935 // Skip downloading the file if the dmg was passed on the command line. std::string dmgName; if(gDmgFile != NULL) { dmgName = basename((char *)gDmgFile); char * dmgDir = dirname((char *)gDmgFile); strncpy(tempDir, dmgDir, sizeof(tempDir)); err = FSPathMakeRef((UInt8*)tempDir, &tempDirRef, NULL); if(err != noErr) throw 0; chdir(tempDir); goto begin_install; } else { // Continue on to download file. dmgName = "SecondLife.dmg"; } strncat(temp, "/SecondLifeUpdate_XXXXXX", (sizeof(temp) - strlen(temp)) - 1); if(mkdtemp(temp) == NULL) { throw 0; } strncpy(tempDir, temp, sizeof(tempDir)); temp[sizeof(tempDir) - 1] = '\0'; llinfos << "tempDir is " << tempDir << llendl; err = FSPathMakeRef((UInt8*)tempDir, &tempDirRef, NULL); if(err != noErr) throw 0; chdir(tempDir); snprintf(temp, sizeof(temp), "SecondLife.dmg"); downloadFile = LLFile::fopen(temp, "wb"); /* Flawfinder: ignore */ if(downloadFile == NULL) { throw 0; } { CURL *curl = curl_easy_init(); curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1); // curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &curl_download_callback); curl_easy_setopt(curl, CURLOPT_FILE, downloadFile); curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0); curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, &curl_progress_callback_func); curl_easy_setopt(curl, CURLOPT_URL, gUpdateURL); curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1); sendProgress(0, 1, CFSTR("Downloading...")); CURLcode result = curl_easy_perform(curl); curl_easy_cleanup(curl); if(gCancelled) { llinfos << "User cancel, bailing out."<< llendl; throw 0; } if(result != CURLE_OK) { llinfos << "Error " << result << " while downloading disk image."<< llendl; throw 0; } fclose(downloadFile); downloadFile = NULL; } begin_install: sendProgress(0, 0, CFSTR("Mounting image...")); LLFile::mkdir("mnt", 0700); // NOTE: we could add -private at the end of this command line to keep the image from showing up in the Finder, // but if our cleanup fails, this makes it much harder for the user to unmount the image. std::string mountOutput; boost::format cmdFormat("hdiutil attach %s -mountpoint mnt"); cmdFormat % dmgName; FILE* mounter = popen(cmdFormat.str().c_str(), "r"); /* Flawfinder: ignore */ if(mounter == NULL) { llinfos << "Failed to mount disk image, exiting."<< llendl; throw 0; } // We need to scan the output from hdiutil to find the device node it uses to attach the disk image. // If we don't have this information, we can't detach it later. while(mounter != NULL) { size_t len = fread(temp, 1, sizeof(temp)-1, mounter); temp[len] = 0; mountOutput.append(temp); if(len < sizeof(temp)-1) { // End of file or error. int result = pclose(mounter); if(result != 0) { // NOTE: We used to abort here, but pclose() started returning // -1, possibly when the size of the DMG passed a certain point llinfos << "Unexpected result closing pipe: " << result << llendl; } mounter = NULL; } } if(!mountOutput.empty()) { const char *s = mountOutput.c_str(); const char *prefix = "/dev/"; char *sub = strstr(s, prefix); if(sub != NULL) { sub += strlen(prefix); /* Flawfinder: ignore */ sscanf(sub, "%1023s", deviceNode); /* Flawfinder: ignore */ } } if(deviceNode[0] != 0) { llinfos << "Disk image attached on /dev/" << deviceNode << llendl; } else { llinfos << "Disk image device node not found!" << llendl; throw 0; } // Get an FSRef to the new application on the disk image FSRef sourceRef; FSRef mountRef; snprintf(temp, sizeof(temp), "%s/mnt", tempDir); llinfos << "Disk image mount point is: " << temp << llendl; err = FSPathMakeRef((UInt8 *)temp, &mountRef, NULL); if(err != noErr) { llinfos << "Couldn't make FSRef to disk image mount point." << llendl; throw 0; } sendProgress(0, 0, CFSTR("Searching for the app bundle...")); err = findAppBundleOnDiskImage(&mountRef, &sourceRef); if(err != noErr) { llinfos << "Couldn't find application bundle on mounted disk image." << llendl; throw 0; } else { llinfos << "found the bundle." << llendl; } sendProgress(0, 0, CFSTR("Preparing to copy files...")); FSRef asideRef; char aside[MAX_PATH]; /* Flawfinder: ignore */ // this will hold the name of the destination target CFStringRef appNameRef; if(replacingTarget) { // Get the name of the target we're replacing HFSUniStr255 appNameUniStr; err = FSGetCatalogInfo(&targetRef, 0, NULL, &appNameUniStr, NULL, NULL); if(err != noErr) throw 0; appNameRef = FSCreateStringFromHFSUniStr(NULL, &appNameUniStr); // Move aside old version (into work directory) err = FSMoveObject(&targetRef, &tempDirRef, &asideRef); if(err != noErr) { llwarns << "failed to move aside old version (error code " << err << ")" << llendl; throw 0; } // Grab the path for later use. err = FSRefMakePath(&asideRef, (UInt8*)aside, sizeof(aside)); } else { // Construct the name of the target based on the product name char appName[MAX_PATH]; /* Flawfinder: ignore */ snprintf(appName, sizeof(appName), "%s.app", gProductName); appNameRef = CFStringCreateWithCString(NULL, appName, kCFStringEncodingUTF8); } sendProgress(0, 0, CFSTR("Copying files...")); llinfos << "Starting copy..." << llendl; // Copy the new version from the disk image to the target location. err = FSCopyObjectSync( &sourceRef, &targetParentRef, appNameRef, &targetRef, kFSFileOperationDefaultOptions); // Grab the path for later use. err = FSRefMakePath(&targetRef, (UInt8*)target, sizeof(target)); if(err != noErr) throw 0; llinfos << "Copy complete. Target = " << target << llendl; if(err != noErr) { // Something went wrong during the copy. Attempt to put the old version back and bail. (void)FSDeleteObject(&targetRef); if(replacingTarget) { (void)FSMoveObject(&asideRef, &targetParentRef, NULL); } throw 0; } else { // The update has succeeded. Clear the cache directory. sendProgress(0, 0, CFSTR("Clearing cache...")); llinfos << "Clearing cache..." << llendl; char mask[LL_MAX_PATH]; /* Flawfinder: ignore */ snprintf(mask, LL_MAX_PATH, "%s*.*", gDirUtilp->getDirDelimiter().c_str()); gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE,""),mask); llinfos << "Clear complete." << llendl; } } catch(...) { if(!gCancelled) if(gFailure == noErr) gFailure = -1; } // Failures from here on out are all non-fatal and not reported. sendProgress(0, 3, CFSTR("Cleaning up...")); // Close disk image file if necessary if(downloadFile != NULL) { llinfos << "Closing download file." << llendl; fclose(downloadFile); downloadFile = NULL; } sendProgress(1, 3); // Unmount image if(deviceNode[0] != 0) { llinfos << "Detaching disk image." << llendl; snprintf(temp, sizeof(temp), "hdiutil detach '%s'", deviceNode); system(temp); /* Flawfinder: ignore */ } sendProgress(2, 3); // Move work directory to the trash if(tempDir[0] != 0) { // chdir("/"); // FSDeleteObjects(tempDirRef); llinfos << "Moving work directory to the trash." << llendl; err = FSMoveObject(&tempDirRef, &trashFolderRef, NULL); if(err != noErr) { llwarns << "failed to move files to trash, (error code " << err << ")" << llendl; } // snprintf(temp, sizeof(temp), "rm -rf '%s'", tempDir); // printf("%s\n", temp); // system(temp); } if(!gCancelled && !gFailure && (target[0] != 0)) { llinfos << "Touching application bundle." << llendl; snprintf(temp, sizeof(temp), "touch '%s'", target); system(temp); /* Flawfinder: ignore */ llinfos << "Launching updated application." << llendl; snprintf(temp, sizeof(temp), "open '%s'", target); system(temp); /* Flawfinder: ignore */ } sendDone(); return(NULL); }
int addNewCustomer(int sd, SOCKADDR *c, int cLen, User **head) { char buffer[BUFFER_SIZE]; char newP1[MAX_NAME_LEN], newP2[MAX_NAME_LEN]; User *newCustomer = (User *)malloc(sizeof(User)); float deposit; int pAttempts = 0; int uniqueUsername = 0; if (!newCustomer) { sendEncrypt(sd, "\n\nMemory error encountered. Returning to main menu.", BUFFER_SIZE, 0, c, cLen); sendEncrypt(sd, BORDER, BUFFER_SIZE, 0, c, cLen); return 0; } // Initialize *newCustomer = ZERO_USER; // Dislpay selection sendEncrypt(sd, BORDER, BUFFER_SIZE, 0, c, cLen); sendEncrypt(sd, "\nYou selected option '3 - Add a new customer to the system.'\n\n", BUFFER_SIZE, 0, c, cLen); // Prompt for new user's info sendEncrypt(sd, "Please enter the following information for the new user\n", BUFFER_SIZE, 0, c, cLen); sendEncrypt(sd, "\nFirst Name: ", BUFFER_SIZE, 0, c, cLen); sendDone(sd, c, cLen); RECV_DECRYPT(sd, newCustomer->firstName, MAX_NAME_LEN, c, &cLen); sendEncrypt(sd, "\nLast Name: ", BUFFER_SIZE, 0, c, cLen); sendDone(sd, c, cLen); RECV_DECRYPT(sd, newCustomer->lastName, MAX_NAME_LEN, c, &cLen); do { sendEncrypt(sd, "\nUsername: "******"\nThe username entered already exists. Please choose another name.\n", BUFFER_SIZE, 0, c, cLen); } while (!uniqueUsername); do { sendEncrypt(sd, "\nPassword: "******"\nRe-enter Password: "******"\n\nThe passwords you entered do not match.\n\n", BUFFER_SIZE, 0, c, cLen); ++pAttempts; } while (pAttempts < 3); // Verify new password if (pAttempts == 3) { sendEncrypt(sd, "Returning to the main menu.", BUFFER_SIZE, 0, c, cLen); sendEncrypt(sd, BORDER, BUFFER_SIZE, 0, c, cLen); free(newCustomer); return 0; } sendEncrypt(sd, "\nInitial deposit: $", BUFFER_SIZE, 0, c, cLen); sendDone(sd, c, cLen); RECV_DECRYPT(sd, buffer, MAX_NAME_LEN, c, &cLen); sscanf(buffer, "%f", &deposit); newCustomer->balance = (unsigned int)(deposit*100); // Generate a random account number srand((unsigned)time(NULL)); newCustomer->acctNum = 100000 + rand() / (RAND_MAX / (999998 - 100000 + 1) + 1); // Just in case by some strange bad luck, the acctnum exists, keep trying while (findUserByAcctNum(*head, newCustomer->acctNum)) newCustomer->acctNum = 100000 + rand() / (RAND_MAX / (999998 - 100000 + 1) + 1); // Set type to Customer newCustomer->userType = 'C'; // Add new user to list newCustomer->next = *head; *head = newCustomer; // Notify manager that new customer has been added sendEncrypt(sd, "\nThe new user has been added with the following information:\n\n", BUFFER_SIZE, 0, c, cLen); sprintf(buffer, "Name: %s %s\n", newCustomer->firstName, newCustomer->lastName); sendEncrypt(sd, buffer, BUFFER_SIZE, 0, c, cLen); sprintf(buffer, "Username: %s\n", newCustomer->username); sendEncrypt(sd, buffer, BUFFER_SIZE, 0, c, cLen); sprintf(buffer, "Account Number: %d\n", newCustomer->acctNum); sendEncrypt(sd, buffer, BUFFER_SIZE, 0, c, cLen); return 0; }
int transferToCustomer(int sd, SOCKADDR *c, int cLen, User *user, User *head) { int acctRx, i=0, periodCnt=0; float transfer = 0.0, tmp; char buffer[BUFFER_SIZE]; char result; User *userRx; // Dislpay selection sendEncrypt(sd, BORDER, BUFFER_SIZE, 0, c, cLen); sendEncrypt(sd, "\nYou selected option '2 - Transfer money to another customer account'\n\n", BUFFER_SIZE, 0, c, cLen); // Display balance and prompt for transfer amount sprintf(buffer, "Your account (%d) has the current balance of $%.2f\n", user->acctNum, (float)(user->balance)/100); sendEncrypt(sd, buffer, BUFFER_SIZE, 0, c, cLen); sendEncrypt(sd, "Enter transfer amount: $", BUFFER_SIZE, 0, c, cLen); sendDone(sd, c, cLen); // Receive transfer amount RECV_DECRYPT(sd, buffer, BUFFER_SIZE, c, &cLen); if (sscanf(buffer, "%f", &transfer) != 1) { sendEncrypt(sd, "\n\nError reading transfer amount. Returning to main menu.", BUFFER_SIZE, 0, c, cLen); sendEncrypt(sd, BORDER, BUFFER_SIZE, 0, c, cLen); return 0; } // Validate transfer amount for (i=0; buffer[i] != '\0'; i++) { if (buffer[i] == '.') periodCnt++; else if (buffer[i]<48 || buffer[i]>57) { periodCnt=2; break; } } for (tmp = (100*transfer); tmp > 0.99; tmp--){} if (tmp > 0 || periodCnt > 1) // Test if too many digits after decimal or too many periods { sendEncrypt(sd, "\n\nError. Transfer amount is invalid. Returning to main menu.", BUFFER_SIZE, 0, c, cLen); sendEncrypt(sd, BORDER, BUFFER_SIZE, 0, c, cLen); return 0; } else if ( (transfer*100) > user->balance) { sendEncrypt(sd, "\n\nError. Transfer amount is greater than current balance. Returning to main menu.", BUFFER_SIZE, 0, c, cLen); sendEncrypt(sd, BORDER, BUFFER_SIZE, 0, c, cLen); return 0; } // Prompt user for the giving account number sendEncrypt(sd, "\n\nAccount number to receive transfer funds: ", BUFFER_SIZE, 0, c, cLen); sendDone(sd, c, cLen); // Receive account number RECV_DECRYPT(sd, buffer, BUFFER_SIZE, c, &cLen); if (sscanf(buffer, "%d", &acctRx) != 1) { sendEncrypt(sd, "\n\nError reading account number. Returning to main menu.", BUFFER_SIZE, 0, c, cLen); sendEncrypt(sd, BORDER, BUFFER_SIZE, 0, c, cLen); return 0; } else if ( !(userRx = findUserByAcctNum(head, acctRx)) ) { sendEncrypt(sd, "\n\nError. Account number does not exist in the database. Returning to main menu.", BUFFER_SIZE, 0, c, cLen); sendEncrypt(sd, BORDER, BUFFER_SIZE, 0, c, cLen); return 0; } // Confirm and complete sprintf(buffer, "\n\nTransfer $%.2f from account %d ($%.2f) to account %d? ", transfer, user->acctNum, (float)(user->balance)/100, userRx->acctNum); if ((result = ynOption(buffer, sd, c, cLen)) == 'T') return -1; if(result) { user->balance -= (int)(transfer*100); userRx->balance += (int)(transfer*100); sprintf(buffer, "Transferred $%.2f\nAccount %d | New balance: $%.2f\n\n", transfer, user->acctNum, (float)(user->balance)/100); sendEncrypt(sd, buffer, BUFFER_SIZE, 0, c, cLen); } else sendEncrypt(sd, "\n\nTransaction canceled. Returning to main menu.", BUFFER_SIZE, 0, c, cLen); sendEncrypt(sd, BORDER, BUFFER_SIZE, 0, c, cLen); return 0; }
int main(int argc, char *argv[]) { static struct sockaddr_in ZERO_SOCKADDR; WSADATA w; struct sockaddr_in client, server = ZERO_SOCKADDR; SOCKADDR *c = (SOCKADDR *)&client; int cLen = (int)sizeof(struct sockaddr_in); int sd = 0; char *dbPath = NULL; unsigned short port = 0; User *head = NULL; char doLogin = FALSE; char doShutDown = FALSE; time_t currTime; int option = 0; char ipAddr[MAX_IP_LEN]; char initialized = FALSE; // Test for correct number of arguments if (argc != 3) { usage(); exit(0); } dbPath = argv[1]; port = atoi(argv[2]); // Validate port number if (!port || port < 256 || port > 65535) { fprintf(stderr, "Invalid port number.\n"); usage(); exit(0); } // Open and parse the database file head = readDatabase(dbPath); if (!head) DieWithError("Error reading database file.\n"); // Initialize Winsock if (WSAStartup(MAKEWORD(2, 0), &w)) DieWithError("WSAStartup() failed."); // Open a datagram socket sd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if (sd == INVALID_SOCKET) DieWithError("Could not create socket.\n"); // Clear out server struct server = ZERO_SOCKADDR; // Set family, port, and address server.sin_family = AF_INET; server.sin_port = htons(port); server.sin_addr.s_addr = htonl(INADDR_ANY); // Bind to the local address if (bind(sd, (struct sockaddr *)&server, sizeof(struct sockaddr_in)) == SOCKET_ERROR) { closesocket(sd); DieWithError("bind() failed"); } printf("\nWaiting for connection...\n\n"); for (;;) // Run forever { char buffer[BUFFER_SIZE]; User *clientUser; // Shut down the server if the flag is set if (doShutDown == TRUE) break; // Wait for client to send initial packet to confirm connection if (!doLogin && recvDecrypt(sd, buffer, BUFFER_SIZE, c, &cLen) == SOCKET_ERROR) { fprintf(stderr, "recvfrom() failed.\n"); continue; } // Login on initial connection and if flag is set if(!strcmp(buffer, "connect") || doLogin) { // Get IP address if first transmission if (!initialized) { recvDecrypt(sd, buffer, BUFFER_SIZE, c, &cLen); sscanf(buffer, "%s", &ipAddr); } // Loop until successful login while (!(clientUser = login(sd, c, cLen, head, ipAddr))) sendEncrypt(sd, "\nInvalid credentials. Please try again.\n", BUFFER_SIZE, 0, c, cLen); initialized = TRUE; } // Display successful login currTime = time(NULL); printf("%.24s : %s %s has logged in from %s.\n", ctime(&currTime), clientUser->firstName, clientUser->lastName, clientUser->ipAddr); sprintf(buffer, "\n\nLogin successful. Welcome, %s %s!\n", clientUser->firstName, clientUser->lastName); sendEncrypt(sd, buffer, BUFFER_SIZE, 0, c, cLen); sprintf(buffer, "User type: %s\n", clientUser->userType == 'C' ? "Customer" : "Manager"); sendEncrypt(sd, buffer, BUFFER_SIZE, 0, c, cLen); if ((long long)clientUser->lastLogin > 0) sprintf(buffer, "Last login: %.24s\n", ctime(&clientUser->lastLogin)); else sprintf(buffer, "Last login: N/A\n"); sendEncrypt(sd, buffer, BUFFER_SIZE, 0, c, cLen); sprintf(buffer, "Last IP address: %s\n\n", clientUser->ipAddr); sendEncrypt(sd, buffer, BUFFER_SIZE, 0, c, cLen); // Set the last login time to the current time clientUser->lastLogin = currTime; // Initialize login flag doLogin = FALSE; while (doLogin == FALSE && doShutDown == FALSE) { // Print menu for correct user type switch(clientUser->userType) { case 'M': // Manager sendEncrypt(sd, "\nRequest Code\t Action\n\n", BUFFER_SIZE, 0, c, cLen); sendEncrypt(sd, "1\t\t Report balance of a selected customer\n", BUFFER_SIZE, 0, c, cLen); sendEncrypt(sd, "2\t\t Transfer money between two accounts\n", BUFFER_SIZE, 0, c, cLen); sendEncrypt(sd, "3\t\t Add a new customer to the system\n", BUFFER_SIZE, 0, c, cLen); sendEncrypt(sd, "4\t\t See the list of customers and their account information\n", BUFFER_SIZE, 0, c, cLen); sendEncrypt(sd, "5\t\t Report customer accounts sorted by balance\n", BUFFER_SIZE, 0, c, cLen); sendEncrypt(sd, "6\t\t See the total balance of all customers\n", BUFFER_SIZE, 0, c, cLen); sendEncrypt(sd, "7\t\t Shut down the server\n", BUFFER_SIZE, 0, c, cLen); sendEncrypt(sd, "8\t\t Logout\n", BUFFER_SIZE, 0, c, cLen); break; case 'C': // Customer sendEncrypt(sd, "Request Code\t Action\n", BUFFER_SIZE, 0, c, cLen); sendEncrypt(sd, "1\t\t Report balance of the customer\n", BUFFER_SIZE, 0, c, cLen); sendEncrypt(sd, "2\t\t Transfer money to another customer account\n", BUFFER_SIZE, 0, c, cLen); sendEncrypt(sd, "3\t\t Change password\n", BUFFER_SIZE, 0, c, cLen); sendEncrypt(sd, "4\t\t Logout\n", BUFFER_SIZE, 0, c, cLen); break; default: // Shouldn't reach here since it loops until successful login. break; } sendEncrypt(sd, "\nPlease enter a Request Code: ", BUFFER_SIZE, 0, c, cLen); sendDone(sd, c, cLen); // Blocking wait for menu option from client if(recvDecrypt(sd, buffer, BUFFER_SIZE, c, &cLen) == (BUFFER_SIZE+1)) { doLogin = TRUE; continue; } // Get user input if (sscanf(buffer, "%d", &option) != 1) option = -1; // Perform appropriate action if (clientUser->userType == 'M') // Manager { switch(option) { case 1: if(seeBalanceSelected(sd, c, cLen, head) == -1){ doLogin = TRUE;} break; case 2: if(transferBetweenAccounts(sd, c, cLen, head) == -1){ doLogin = TRUE;} break; case 3: if(addNewCustomer(sd, c, cLen, &head) == -1){ doLogin = TRUE;} break; case 4: listCustomers(sd, c, cLen, head); break; case 5: sortByBalance(sd, c, cLen, &head); listCustomers(sd, c, cLen, head); break; case 6: totalBalanceOfAll(sd, c, cLen, head); break; case 7: doShutDown = TRUE; break; // Sets flag to shut down server case 8: doLogin = TRUE; break; // Sets flag to loop back to login state default: sendEncrypt(sd, "\n\nInvalid input. Please enter a valid option.\n\n", BUFFER_SIZE, 0, c, cLen); break; } } else if (clientUser->userType == 'C') // Customer { switch(option) { case 1: seeUserBalance(sd, c, cLen, clientUser); break; case 2: if(transferToCustomer(sd, c, cLen, clientUser, head) == -1){ doLogin = TRUE;} break; case 3: if(changePassword(sd, c, cLen, clientUser) == -1){ doLogin = TRUE;} break; case 4: doLogin = TRUE; break; // Sets flag to loop back to login state default: sendEncrypt(sd, "\n\nInvalid input. Please enter a valid option.\n\n", BUFFER_SIZE, 0, c, cLen); break; } } else{} } // Reached when log out OR shut down flag is set to true sendEncrypt(sd, "\n\nLogging out.", BUFFER_SIZE, 0, c, cLen); currTime=time(NULL); printf("%.24s : %s %s has logged out.\n\n", ctime(&currTime), clientUser->firstName, clientUser->lastName); writeDatabase(dbPath, head); if (doShutDown == FALSE) sendEncrypt(sd, BORDER, BUFFER_SIZE, 0, c, cLen); } // Reached when shut down flag is set to true sendEncrypt(sd, BORDER, BUFFER_SIZE, 0, c, cLen); sendEncrypt(sd, "\nThe server has shut down. Client is closing. Thank you.\n\n", BUFFER_SIZE, 0, c, cLen); sendEncrypt(sd, "close", BUFFER_SIZE, 0, c, cLen); // message to close the client printf("Server is shutting down by client request.\n\n"); }
int transferBetweenAccounts(int sd, SOCKADDR *c, int cLen, User *head) { int acct1, acct2; int i=0, periodCnt=0; float transfer = 0.0, tmp; char buffer[BUFFER_SIZE]; char result; User *customer1, *customer2; // Prompt user for the giving account number sendEncrypt(sd, BORDER, BUFFER_SIZE, 0, c, cLen); sendEncrypt(sd, "\nYou selected option '2 - Transfer money between two accounts'\n", BUFFER_SIZE, 0, c, cLen); sendEncrypt(sd, "\nTransfer from (account number): ", BUFFER_SIZE, 0, c, cLen); sendDone(sd, c, cLen); // Receive account number RECV_DECRYPT(sd, buffer, BUFFER_SIZE, c, &cLen); if (sscanf(buffer, "%d", &acct1) != 1) { sendEncrypt(sd, "\n\nError reading account number. Returning to main menu.", BUFFER_SIZE, 0, c, cLen); sendEncrypt(sd, BORDER, BUFFER_SIZE, 0, c, cLen); return 0; } // Search linked list for the selected account 1 if ( !(customer1 = findUserByAcctNum(head, acct1)) ) { sendEncrypt(sd, "\n\nError. Account number does not exist in database. Returning to main menu.", BUFFER_SIZE, 0, c, cLen); sendEncrypt(sd, BORDER, BUFFER_SIZE, 0, c, cLen); return 0; } // Display balance and prompt for transfer amount sprintf(buffer, "\n\nAccount %d has the current balance of $%.2f\n", customer1->acctNum, (float)customer1->balance/100); sendEncrypt(sd, buffer, BUFFER_SIZE, 0, c, cLen); sendEncrypt(sd, "Enter transfer amount: $", BUFFER_SIZE, 0, c, cLen); sendDone(sd, c, cLen); // Receive transfer amount RECV_DECRYPT(sd, buffer, BUFFER_SIZE, c, &cLen); if (sscanf(buffer, "%f", &transfer) != 1) { sendEncrypt(sd, "\n\nError reading transfer amount. Returning to main menu.", BUFFER_SIZE, 0, c, cLen); sendEncrypt(sd, BORDER, BUFFER_SIZE, 0, c, cLen); return 0; } // Validate transfer amount for (i=0; buffer[i] != '\0'; i++) { if (buffer[i] == '.') periodCnt++; else if (buffer[i]<48 || buffer[i]>57) { periodCnt=99; // Set the count high and leave loop break; } } for (tmp = (100*transfer); tmp > 0.99; tmp--){} if (tmp > 0 || periodCnt > 1) // Test if too many digits after decimal or too many periods { sendEncrypt(sd, "\n\nError. Transfer amount is invalid. Returning to main menu.", BUFFER_SIZE, 0, c, cLen); sendEncrypt(sd, BORDER, BUFFER_SIZE, 0, c, cLen); return 0; } else if ( (transfer*100) > customer1->balance ) { sendEncrypt(sd, "\n\nError. Transfer amount is greater than customer balance. Returning to main menu.", BUFFER_SIZE, 0, c, cLen); sendEncrypt(sd, BORDER, BUFFER_SIZE, 0, c, cLen); return 0; } // Prompt user for the receiving account number sendEncrypt(sd, "\n\nTransfer to (account number): ", BUFFER_SIZE, 0, c, cLen); sendDone(sd, c, cLen); // Receive account number RECV_DECRYPT(sd, buffer, BUFFER_SIZE, c, &cLen); if (sscanf(buffer, "%d", &acct2) != 1) { sendEncrypt(sd, "\n\nError reading account number. Returning to main menu.", BUFFER_SIZE, 0, c, cLen); sendEncrypt(sd, BORDER, BUFFER_SIZE, 0, c, cLen); return 0; } // Search linked list for the selected account 2 if ( !(customer2 = findUserByAcctNum(head, acct2)) ) { sendEncrypt(sd, "\n\nError. Account number does not exist in database. Returning to main menu.", BUFFER_SIZE, 0, c, cLen); sendEncrypt(sd, BORDER, BUFFER_SIZE, 0, c, cLen); return 0; } // Confirm and complete sprintf(buffer, "\n\nTransfer $%.2f from account %d ($%.2f) to account %d ($%.2f)?\n", transfer, customer1->acctNum, (float)(customer1->balance)/100, customer2->acctNum, (float)(customer2->balance)/100); if ((result = ynOption(buffer, sd, c, cLen)) == 'T') return -1; if(result) { customer1->balance -= (int)(transfer*100); customer2->balance += (int)(transfer*100); sprintf(buffer, "\n\nTransferred $%.2f\nAccount %d | New balance: $%.2f\nAccount %d | New balance: $%.2f\n", transfer, customer1->acctNum, (float)(customer1->balance)/100, customer2->acctNum, (float)(customer2->balance)/100); sendEncrypt(sd, buffer, BUFFER_SIZE, 0, c, cLen); sendEncrypt(sd, BORDER, BUFFER_SIZE, 0, c, cLen); } else { sendEncrypt(sd, "\n\nTransaction canceled. Returning to main menu.", BUFFER_SIZE, 0, c, cLen); sendEncrypt(sd, BORDER, BUFFER_SIZE, 0, c, cLen); } return 0; }