// // bidwatcher // copyright (c) 1999-2005 // Trent McNair (trent@rmci.net) // Tom McNair (tmcnair@cyberhighway.net) // Wayne Schlitt (wayne@midwestcs.com) // Ben Byer (bushing@users.sourceforge.net) // Kevin Dwyer (kevin@pheared.net) // // use of this code is restricted to the terms // of the GNU GPL, which should have been included in this // distribution. If not, see www.gnu.org/copyleft/gpl.html. // Here is the short version: // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // #ifndef AUCTION_H #define AUCTION_H #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include using namespace std; // This is the amount of time before Bidwatcher will give up on // fetching a web page. It is fairly common for something to "hang", // and a the quickest way to get the page loaded is to give up and // try again. // // If this value is too small, then bidwatcher may give up on a // request that is actually close to finishing. By giving up too // early, you end up having to do two requests, which takes more time. // It is probably better for this to be too large than too small. // // If this value is too large, then precious time will can be wasted // when a snipe is supposed to be executed. // // Actually, bidwatcher will detect hung connections quicker than the // TIMEOUT value. This is really more of the "maximum" timeout. #define TIMEOUT 20 // in seconds #define NORMAL_LOAD_TIME 4 // good for ISDN, ADSL, cable, T1 etc. #define INITIAL_LOAD_TIME ( \ NORMAL_LOAD_TIME \ + (20*1024)/(56000/10)) // ms to download a 20k page on 56k modem #define atoul(x) (strtoul(x, (char **) NULL, 10)) #define atoull(x) (strtoull(x, (char **) NULL, 10)) // Ultra cool Debugging foo. #define DHIGH 1 #define DMED 2 #define DLOW 3 #ifndef DEBUGGING #define DEBUGGING 0 #endif #if (DEBUGGING >= DHIGH) # define LOCUS "[%s:%d\t%s] " # define LOGPREFIX printf(LOCUS, __HERE__, getTimeStamp()) #else # define LOCUS "[%s:%d] " # define LOGPREFIX printf(LOCUS, __HERE__) #endif #define __HERE__ __FILE__, __LINE__ #define LOGIT(c) Logger ## c #define DPRINTF(n, d) if(DEBUGGING>=n) LOGPREFIX, printf d // is this the DEC c++ compiler? #if !defined (__DECCXX) // no, ok, output a warning message letting the usr know whether // or not debugging is on or off. // We should be quiet for general usage and not bother the general user with // scary warnings. # if (DEBUGGING > 0) # warning DEBUGGING is on. # else //# warning DEBUGGING is off. # endif #endif extern double avg_load_time; extern const char *const bw_subdir; gint secondticker_callback(gpointer data); gint bigdelay_callback(gpointer data); gint updatelist_callback(gpointer data); float calculateBidIncrement(float currentBid, const char *currency); // other constants #define HUGEBUFF (256*1024) #define MAXAUCS 100 #define BIGDELAY (2*60*60*1000) // in useconds #define AUTODEL (-24*60*60) // in seconds #define MAX_REDIR 5 #define MAX_STATUS_LEN 200 #define PREBID_DELAY 60 #define NUM_CONFIG_TABS 3 #define CONFIG_MAIN 0 #define CONFIG_COLOR 1 #define CONFIG_FONT 2 #define NUM_COLUMNS 8 #define COMMENT_LENGTH 200 #define FONT_FIX_DFL "-*-clean-medium-r-normal-*-*-120-*-*-c-*-*-*" #define FONT_CLEAN_DFL "-*-clean-medium-r-normal-*-*-140-*-*-c-*-*-*" #define ERR_STRING "Error: " // number of items in a static array #define array_elem(a) (sizeof(a)/sizeof(a[0])) struct URL { char fullurl[512], fullurlpost[512]; bool useproxy; char *proxyuser, *proxypass; string hostname; int port; URL(); // since there is dynamic memory involved, be safe. URL(char *newurl, char *postval, URL *proxy); URL(char *newurl, char *postval, URL *proxy, char *user, char *pass); ~URL(); void create(char *newurl, char *postval, URL *proxy); void freeHostInfo(bool free_pointer); }; // // Stucture to store auction information // struct auctioninfo { unsigned long long ItemNumber; /* Item Number (User Entered) */ char Description[129]; /* Description Of Item For sale */ char Comments[COMMENT_LENGTH];/* User-defined comments */ char currency[10]; /* Bid Currency for the auction */ float CurrentBid; /* Current Bid */ float FirstBid; /* First (or starting) Bid */ int Quantity; /* Quantity of Items For Sale */ int BidCount; /* Total Number of Bids */ char TimeLeft[51]; /* Time Left in Auction */ char Location[101]; /* Location of Item */ char Started[51]; /* Time when Auction Started */ char Ends[51]; /* Time/Data Auction Ends */ char Seller[76]; /* User Selling the Item */ char HighBidder[76]; /* Current High Bidder */ char BidInc[15]; /* Minimum Bid Increment */ char SellerRate[15]; /* Seller's eBay rating */ char BidderRate[15]; /* Bidder's eBay rating */ float BuyitNowPrice; /* Buy it Now price */ float snipeAmount; /* Our snipe amount */ int snipeQty; /* Our snipe dutch quantity */ char snipeKey[100]; /* Snipe key for this auction */ float myBidAmount; /* Our bid */ int myBidQuantity; /* Our bid quantity for dutch */ long int EndsValue; /* time auction ends in seconds */ long int UpdTime; /* time of last update */ char stat; /* status of auction for GUI */ char bidstatus; /* final status of bid/snipe */ char reserveMet; /* [y/n/x] = Status of reserve */ bool isBuyitNow; /* has it a buy-it-now */ bool isSnipe; /* Is this a snipe or not? */ bool isPreBid; /* Needs pre-bid for snipe */ int AuctionType; /* Type: ebay/ebaymotors/etc. */ URL *infourl; /* URL for auction info */ URL *bidurl; /* URL for bidding/sniping */ int magic; /* Used to detect corrupt lists */ int isEndless; /* For non-auction auctions */ char Feedbackn[15]; /* client feedback */ float Shipping[3]; /* shipping prices */ char ShippingCur[3][10]; /* currency of shipping */ auctioninfo(); ~auctioninfo(); int getinfo(); bool parseaucinfo(const char *); void getkey(float bid, int quantity); int bid(bool); double currentPrize() const { return BidCount > 0 ? CurrentBid : FirstBid; } double minBid() const { return BidCount > 0 ? calculateBidIncrement(CurrentBid, currency) : FirstBid; } bool finalUpdated() const { return UpdTime > EndsValue; } }; typedef char string30[30]; class ConfigWindow; class GetPass; class AboutWindow; class PopupMenu; class DetailsWindow; class BidWindow; class CommentWindow; void CmUser(); void CmAddItem(); void CmTimeSync(); void CmUpdate(); void CmHelp(); void CmExit(); void CmCancelClicked(); void doubleClick(int); struct auctioninfo *addNewItem(unsigned long long); void timer1Up(); void timer2Up(); void timer3Up(); void timer4Up(); void CmMenu(); void CmDetails(); void CmViewFile(); void CmViewEnded(); void UpdateItem(); void launchBrowser(int choice); void deleteItem(); void flush(); void setupSnipe(auctioninfo *, int); void CmBid(); void CmUnBid(); void ClearSnipe(int); void CmWeb(); void CmEmail(char *); void TimeSync(); void resetTimeSyncURL(); void DoSnipe(int); void UpdateListItem(int); void UpdateList(); void ArrangeList(); void DeleteAuction(int); void ReadAucFile(); bool bigUpdate(); bool UpdateAll(bool); int Update(int max_time_diff, bool first_run, bool full_update); int updateitem(unsigned long long); int timeToNextEnd(bool snipe_only = false, int *idx = 0); int timeToNextSnipe(int *dix = 0); bool interfereWithSnipe(); bool haveEndedWithoutUpdate(); void UpdateLatest(); int GetUserBids(); int GetUserListings(); int UpdateAuction(auctioninfo *); void WriteLog(int); void WriteAucFile(); void showError(char *); void showBidStatus(char *); void showStatus(char *); void makeStyles(); void resetStyles(); GtkStyle *get_style(struct auctioninfo *, int); class BidWindow { public: struct auctioninfo * myauc; GtkWidget *window, *currentbidlabel, *timeleftlabel, *bidtext, *bidlabel, *quantitytext, *quantitylabel, *okbutton, *cancelbutton, *snipebutton, *bidbox, *quantitybox, *radio_bid, *radio_snipe; BidWindow(struct auctioninfo * auc); ~BidWindow(); }; class CommentWindow { public: struct auctioninfo *myauc; GtkWidget *window, *text, *scrolledwindow, *okbutton, *cancelbutton; CommentWindow(struct auctioninfo *auc); ~CommentWindow(); }; class DetailsWindow { public: struct auctioninfo * myauc; GtkWidget *window, *categorylabel, *infolabel, *hbox, *currentbidlabel, *sellerbutton, *bidderbutton, *cancelbutton; gint timeouttag; DetailsWindow(struct auctioninfo * auc); void fill(); void update(); ~DetailsWindow(); }; class EndedWindow { public: char issnipes, iscurrent; GtkWidget *window, *hbox, *textbuffer, *scrollbar, *monthbutton, *monthlabel, *okbutton; EndedWindow(char snipes,char current); void update(); ~EndedWindow(); }; class AboutWindow { public: GtkWidget *window, *aboutlabel, *okbutton; AboutWindow(); ~AboutWindow(); }; class GetPass { public: GtkWidget *window, *okbutton, *cancelbutton, *missinglabel, *useridlabel, *passlabel, *useridentry, *passentry, *useridbox, *passbox; GetPass(); ~GetPass(); }; class ConfigWindow { public: GtkWidget *window; GtkWidget *notebook, *bookbox[NUM_CONFIG_TABS], *tab_label[NUM_CONFIG_TABS]; GtkWidget *useridbox, *passwordbox, *browserbox, *emailbox, *proxybox; GtkWidget *useridlabel,*useridtext,*passwordlabel,*passwordtext, *browserlabel,*browsertext,*mailclientlabel,*mailclienttext, *proxylabel,*proxytext,*proxyuserlabel,*proxypasslabel, *proxyusertext,*proxypasstext,*listingcheck, *bidcheck, *startupcheck, *deletecheck, *snipebox, *snipespin, *snipelabel, *okbutton, *cancelbutton, *label_security, *radio_sec_low, *radio_sec_medium, *radio_sec_high, *security_box, *location_check, *size_check, *user_frame, *sys_frame, *toggle_frame, *usertable, *systable, *toggletable, *country_option, *country_option_menu, *glade_menuitem, *country_box, *country_label, *font_table, *fixed_font_text, *fixed_font_label, *clean_font_text, *clean_font_label, *font_frame; GtkObject *snipeadj; GtkWidget *update_prio1_spin, *update_prio1_label, *update_prio1_box; GtkWidget *update_prio2_spin, *update_prio2_label, *update_prio2_box; GtkWidget *update_prio3_spin, *update_prio3_label, *update_prio3_box; GtkWidget *update_prio4_spin, *update_prio4_label, *update_prio4_box; GtkObject *update_prio1_adj, *update_prio2_adj, *update_prio3_adj, *update_prio4_adj; GtkWidget *colorseldlg; GtkWidget *color_ended_box, *color_ended_label; bool listing, bid, startup, del, location, size; GtkStyle *color_button_style; GtkWidget *color_button; ConfigWindow(); ~ConfigWindow(); }; class ErrorWindow { public: GtkWidget *window,*messagelabel, *okbutton; ErrorWindow(char *message); ~ErrorWindow(); }; class ConfirmWindow { public: GtkWidget *window,*messagelabel, *okbutton, *cancelbutton; ConfirmWindow(char *message); ~ConfirmWindow(); }; // Save a file using a temporary and renaming. class FopenW { public: FopenW(const char *file); ~FopenW() { close(); } operator FILE*() const { return fp; } int close(); private: FILE *fp; const char *real_name; char *temp_name; }; inline int fclose(FopenW &obj) { return obj.close(); } // redirect standard call int fclose(const FopenW &obj); // never implemented: catch inappropriate use as linker error. char *StripHtmlTags(const char *stringToStrip); char *StripAndTab(const char *stringToStrip); int ProcessBidSubmission(char *Buff, char *lineBuff, int lineBuffLen); int ProcessBid(char *Buff); int ParseEmailAddress(char *Buff, char *emailAddress); void encode_password(char *dest, const char *src); void decode_password(char *dest, const char *src); long int CalcTimeLeft (long int endTime, int ebayOffset); int stringTimeLeft (struct auctioninfo *auc, int ebayOffset, char *chTimeLeft); void MakeFileName(char *prefix2, char *fileName, bool thisMonth); void ClearBidMakeUp(struct auctioninfo *NewAuction) ; long int CalcEndsValue(char *Ends); long int CalcTimeLeft (long int endTime, int ebayOffset); void MakeClockTime(int offSet, char *theTime); char *parseRows(const char * fromBuff); unsigned long long *ParseList(char *); void strip_commas(char *p); void strip_newlines(char *p); void strip_crlf(char *p); void translate_date(char *date); bool GetAucInfo(char *Buff, struct auctioninfo *NewAuction); int calcTimeDiff (char *buffer); int fetchURL(URL *url, int Post, char **Buff, char *cookejar, int redir); char *stristr(const char *haystack, const char *needle); char translate_special(const char *input, int *len); char *getTimeStamp(); // next 3 functions were copied and slightly modified from the // gnu wget project. The project can be found at // http://www.gnu.org/software/wget/wget.html. // How many bytes it will take to store LEN bytes in base64. inline unsigned long long BASE64_LENGTH(unsigned long long len) { return 4 * (len + 2) / 3; } // Authorization support: We support one authorization scheme: // * `Basic' scheme, consisting of base64-ing USER:PASSWORD string; void base64_encode (const char *s, char *store, int length); void basic_authentication_encode (const char *user, const char *passwd, char **encstr); // like strncpy but always with \0 at dst[len], so len bytes are copied void strnzcpy(char *dst, const char *src, size_t len); #define STRNZCPY(dst, src) strnzcpy(dst, src, sizeof(dst) - 1) // like strncmp(str1, str2, strlen(str1)) int srnzcmp(const char *str1, const char *str2); int find_auction_index(unsigned long long aucnum); int find_auction_index(struct auctioninfo *auc); struct auctioninfo *find_auction(unsigned long long aucnum); extern bool cancelPressed; extern URL *proxyurl; extern int numbids; extern char authID[76]; extern char authPASS[76]; extern struct auctioninfo * auction[MAXAUCS+1]; extern string30 auctionlist[MAXAUCS + 1]; /* so many return codes! */ #define ERROR -1 /* ProcessBidSubmission */ #define PBS_SUCCESS 1 #define PBS_BIDTOOLOW 2 #define PBS_BADQUANTITY 3 #define PBS_AUCTIONOVER 4 #define PBS_PREAPPROVAL 5 /* ProcessBid */ #define PB_HIGHBID 1 #define PB_OUTBID 2 #define PB_BIDTOOLOW 3 #define PB_BADQUANTITY 4 #define PB_AUCTIONOVER 5 #define PB_BADUSER 6 /* ParseEmailAddress */ #define PEA_SUCCESS 1 #define PEA_BADUSER 2 /* Network Functions (i.e. FetchURL) */ #define NET_SUCCESS 1 #define NET_NETERROR 2 #define NET_TIMEOUT 3 #define NET_USERCANCEL 4 #define NET_MAXREDIR 5 #define NET_REDIRSUCCESS 6 /* GetUserAuctions */ #define GUA_BADUSER -2 #define GUA_CGIDOWN -5 #define GUA_TIMEOUT -4 #define GUA_SUCCESS 1 /* Info from auctioninfo::getinfo */ #define INFO_ERROR_RANGE 0x1000 #define INFO_SUCCESS (INFO_ERROR_RANGE | NET_SUCCESS) #define INFO_NETERROR (INFO_ERROR_RANGE | NET_NETERROR) #define INFO_TIMEOUT (INFO_ERROR_RANGE | NET_TIMEOUT) #define INFO_USERCANCEL (INFO_ERROR_RANGE | NET_USERCANCEL) #define INFO_CGIDOWN (INFO_ERROR_RANGE | NET_MAXREDIR) #define INFO_BADAUCTION (INFO_ERROR_RANGE | NET_REDIRSUCCESS) void getAdultCookie(char *, char *); // We can make a bunch of these and make cases for all of em. #define TYPE_EBAY 0 #define TYPE_EBAYMOTORSCAR 1 //Ebay motors auctions that are cars #define TYPE_EBAYMOTORS 2 //Auctions on motors that aren't cars // Security levels #define SEC_LOW 0 // Write everything to file, keep in memory #define SEC_MED 1 // Write user to file, keep in memory #define SEC_HIGH 2 // Write nothing to file, keep nothing in memory #define VIEWURL "http://cgi.%s/ws/eBayISAPI.dll?ViewItem&item=%llu" #endif // AUCTION_H