telnetneg.c-Dateireferenz

#include <thing/properties.h>
#include <telnet.h>
Include-Abhängigkeitsdiagramm für telnetneg.c:

gehe zum Quellcode dieser Datei

Makrodefinitionen

#define NEED_PROTOTYPES

Funktionen

mapping query_telnet_neg ()
private int send_telnet_neg (int *arr)
string * query_terminals ()
static void modify_prompt ()
void telnet_neg (int command, int option, int *optargs)
static void startup_telnet_negs ()
protected void send_telnet_timing_mark ()

Variablen

static mapping TN
static string * Terminals
static string last_received_termtype

Makro-Dokumentation

#define NEED_PROTOTYPES

Definiert in Zeile 15 der Datei telnetneg.c.


Dokumentation der Funktionen

static void modify_prompt (  )  [static]

Definiert in Zeile 76 der Datei telnetneg.c.

Benutzt DO, EOR, IAC, P_PROMPT, QueryProp(), TELOPT_EOR, text() und TN.

Wird benutzt von telnet_neg().

00076                             {
00077     string text;
00078     closure rp;
00079 
00080     // renew_prompt() wird momentan nur in Magiershells implementiert.
00081     if (closurep(rp=symbol_function("renew_prompt",this_object()))) {
00082                 funcall(rp);
00083     }
00084     else {
00085         if ( !(text = QueryProp( P_PROMPT )) || text == "" )
00086             text = "> ";
00087                 
00088         if ( mappingp(TN) && mappingp(TN["received"])
00089              && (TN["received"][TELOPT_EOR,1] == DO) )
00090             set_prompt( lambda( ({}),
00091                                 ({ #'efun::binary_message/*'*/,
00092                                         ({ #'+/*'*/,
00093                                                 ({ #'to_array/*'*/,
00094                                                         text }),
00095                                                 ({ #'({/*'*/, IAC, EOR }) })
00096                                         })
00097                                 ), this_object()
00098                         );
00099         else
00100             set_prompt( text, this_object() );
00101     }
00102 }

Hier ist ein Graph der zeigt, was diese Funktion aufruft:

Hier ist ein Graph der zeigt, wo diese Funktion aufgerufen wird:

mapping query_telnet_neg (  ) 

Definiert in Zeile 27 der Datei telnetneg.c.

Benutzt TN.

00028 {
00029     if ( !mappingp(TN) || !TN )
00030         TN = ([]);
00031 
00032     return TN;
00033 }

string* query_terminals (  ) 

Definiert in Zeile 70 der Datei telnetneg.c.

Benutzt Terminals.

00071 { 
00072     return Terminals;
00073 }

private int send_telnet_neg ( int *  arr  ) 

Definiert in Zeile 37 der Datei telnetneg.c.

Benutzt DO, DONT, IAC, SB, TN, WILL und WONT.

00038 {
00039     int res;
00040     
00041     if ( sizeof(arr) < 3 )
00042         return efun::binary_message(arr);
00043     
00044     if ( !TN["sent"] )
00045         TN["sent"] = m_allocate(3,3);
00046     
00047     if ( arr[0] == IAC ){
00048         switch (arr[1]){
00049         case DO:
00050         case DONT:
00051             TN["sent"][arr[2],1] = arr[1];
00052             break;
00053         case WILL:
00054         case WONT:
00055             TN["sent"][arr[2],0] = arr[1];
00056             break;
00057         case SB:
00058             TN["sent"][arr[2],2] = arr[1..];
00059             break;
00060         default:
00061             break;  
00062         }
00063     }
00064     
00065     return efun::binary_message(arr);
00066 }

protected void send_telnet_timing_mark (  ) 

Definiert in Zeile 490 der Datei telnetneg.c.

Benutzt DO, IAC und TELOPT_TM.

Wird benutzt von CheckTelnetKeepAlive().

00490                                          {
00491   binary_message( ({IAC, DO, TELOPT_TM}), 1 );
00492 }

Hier ist ein Graph der zeigt, wo diese Funktion aufgerufen wird:

static void startup_telnet_negs (  )  [static]

Definiert in Zeile 386 der Datei telnetneg.c.

Benutzt break_string(), c, i, P_TTY_COLS, P_TTY_ROWS, P_TTY_SHOW, P_TTY_TYPE, Query(), Set(), TELOPT_NAWS, TELOPT_TTYPE, Terminals, TN und xx.

00387 {
00388   mapping sent, recd;
00389   mixed optargs;
00390   int i;
00391   mixed *xx;
00392   
00393   Set( P_TTY_TYPE, 0 );  //avoid ANY mistakes...
00394   TN = (mapping) previous_object()->query_telnet_neg();//from login.c
00395   Terminals = (string *) previous_object()->query_terminals();//from login.c
00396 
00397   // in login.c gibt es noch keine "echten" Properties - deshalb hier noch
00398   // einmal richtig setzen
00399 
00400   Set( P_TTY_COLS, previous_object()->Query(P_TTY_COLS) );
00401   Set( P_TTY_ROWS, previous_object()->Query(P_TTY_ROWS) );
00402 
00403   if ( !TN )
00404       TN = ([]);
00405   
00406   if ( !TN["sent"] )
00407       TN["sent"] = m_allocate(3,3);
00408   
00409   if ( !TN["received"] )
00410       TN["received"] = m_allocate(3,3);
00411   
00412   sent = TN["sent"];
00413   recd = TN["received"];
00414   
00415   if ( optargs = recd[TELOPT_NAWS,2] ){
00416       int c, l;
00417       
00418       if ( sizeof(optargs) == 4 ){
00419           if ( !optargs[1] )
00420               c = optargs[0];
00421           else
00422               c = optargs[1] + optargs[0] * 256;
00423           
00424           if ( c < 20 ){
00425               c = 80;
00426         
00427               if (Query(P_TTY_SHOW))
00428                    tell_object( this_object(),
00429                            break_string("Dein Fenster ist schmaler als 20"
00430                                         +" Zeichen? Du scherzt. ;-) Ich"
00431                                         +" benutze den Standardwert von 80"
00432                                         +" Zeichen.\n", 78,
00433                                         "Der GameDriver teilt Dir mit: ") );
00434           }
00435       
00436           if ( !optargs[3] )
00437               l = optargs[2];
00438           else
00439               l = 256 * optargs[2] + optargs[3];
00440           
00441           if ( l > 100 ){
00442               l = 100;
00443               if (Query(P_TTY_SHOW))
00444                   tell_object( this_object(),
00445                            break_string("Tut mir leid, aber ich kann nur bis zu"
00446                                         +" 100 Zeilen verwalten.\n",
00447                                         (c ? c-2 : 78),
00448                                         "Der GameDriver teilt Dir mit: " ) );
00449           }
00450           
00451           if ( l < 3 ){
00452               if (Query(P_TTY_SHOW))
00453                   tell_object( this_object(),
00454                            break_string("Du willst weniger als drei Zeilen"
00455                                         +" benutzen? Glaub ich Dir nicht - ich"
00456                                         +" benutze den Standardwert von 24"
00457                                         +" Zeilen.\n", (c ? c-2 : 78),
00458                                         "Der GameDriver teilt Dir mit: " ) );
00459               l = 24;
00460           }
00461       
00462           if ( ((int) Query(P_TTY_ROWS) != l) ||
00463                ((int) Query(P_TTY_COLS) != c) ){
00464               Set( P_TTY_ROWS, l );
00465               Set( P_TTY_COLS, c );
00466               if (Query(P_TTY_SHOW))
00467                   tell_object( this_object(),
00468                            break_string("Du hast Deine Fenstergroesse auf "+l
00469                                         +" Zeilen und "+c
00470                                         +" Spalten geaendert.\n", c-2,
00471                                         "Der GameDriver teilt Dir mit: ") );
00472           }
00473       }
00474   }
00475   
00476   if ( recd[TELOPT_TTYPE,2] ){
00477       if ( !sizeof(Terminals) )
00478           return;
00479       
00480       if ( Terminals[0][0..3] == "dec-" )
00481           Terminals[0] = Terminals[0][4..];
00482       
00483       if ( Terminals[0] == "linux" )
00484           Terminals[0] = "vt100";
00485       
00486       Set( P_TTY_TYPE, Terminals[0] );
00487   }
00488 }

Hier ist ein Graph der zeigt, was diese Funktion aufruft:

void telnet_neg ( int  command,
int  option,
int *  optargs 
)

Definiert in Zeile 106 der Datei telnetneg.c.

Benutzt break_string(), c, DO, DONT, EOR, i, IAC, LM_FORWARDMASK, LM_MODE, MODE_EDIT, modify_prompt(), old_explode(), P_TTY_COLS, P_TTY_ROWS, P_TTY_SHOW, P_TTY_TYPE, Query(), SB, SE, send_telnet_neg(), Set(), TELOPT_ENVIRON, TELOPT_LINEMODE, TELOPT_NAWS, TELOPT_NEWENV, TELOPT_TSPEED, TELOPT_TTYPE, TELOPT_XDISPLOC, TELQUAL_IS, TELQUAL_SEND, Terminals, TN, WILL, WONT und xx.

00107 {
00108     mapping recd, sent;
00109     int i, l, c;
00110     mixed *xx;
00111     string tmpterminal;
00112     string text, text2;
00113     int tmpxx;
00114 
00115     l = 0;
00116     c = 0;
00117 
00118   //hmm. WILL/WONT DO/DONT SB_IS 
00119     if ( !mappingp(TN) || !TN )
00120         TN=([]);
00121     
00122     if ( !TN["received"] )
00123         TN["received"] = m_allocate(3,3);
00124     
00125     if ( !TN["sent"] )
00126         TN["sent"] = m_allocate(3,3);
00127 
00128     recd = (mapping) TN["received"];
00129     sent = (mapping) TN["sent"];
00130 
00131     if ( command == WILL || command == WONT ){
00132         recd[option,0] = command;
00133         
00134         if ( !sent[option,1] && command == WILL ){
00135             //we support everything. (yeah ;)
00136             efun::binary_message(({IAC, DO, option}));
00137             sent[option,1] = DO;
00138         }
00139         
00140         if ( command == WILL ){
00141             switch (option){
00142             case TELOPT_NAWS: 
00143                 break;//no more things needed.
00144                 
00145             case TELOPT_LINEMODE:
00146                 send_telnet_neg(({ IAC, SB, option, LM_MODE, MODE_EDIT, IAC,
00147                                        SE }));
00148                 //flush on 0d and 0a...
00149                 send_telnet_neg(({ IAC, SB, option, DO, LM_FORWARDMASK, 0,
00150                                       0x40|0x08, IAC, SE }));
00151                 sent[TELOPT_LINEMODE,2] = MODE_EDIT;
00152                 break;
00153 
00154             case TELOPT_TTYPE:
00155                 send_telnet_neg(({ IAC, SB, TELOPT_TTYPE, TELQUAL_SEND, IAC,
00156                                        SE }));
00157                 sent[TELOPT_TTYPE,2] = TELQUAL_SEND;
00158                 break;
00159 
00160             case TELOPT_TSPEED:
00161                 send_telnet_neg(({ IAC, SB, TELOPT_TSPEED, TELQUAL_SEND, IAC,
00162                                        SE }));
00163                 sent[TELOPT_TTYPE,2] = TELQUAL_SEND;
00164                 break;
00165                 
00166             case TELOPT_NEWENV:
00167             case TELOPT_ENVIRON:
00168                 efun::binary_message(({ IAC, SB, option, TELQUAL_SEND, IAC,
00169                                             SE }));
00170                 sent[option,2] = TELQUAL_SEND;
00171                 break;
00172                 
00173             case TELOPT_XDISPLOC:
00174                 send_telnet_neg(({ IAC, SB, TELOPT_XDISPLOC, TELQUAL_SEND, IAC,
00175                                        SE }));
00176                 break;
00177                 
00178             default:
00179                 break;
00180             }
00181         }
00182         
00183         return;
00184     }
00185     
00186     if ( command == DONT || command == DO ){
00187         //wir machen nix als telnet client...jedenfalls in der lib.
00188         recd[option,1] = command;
00189         
00190         if ( !sent[option,0] && command == DO ){
00191             if ( option == TELOPT_EOR){
00192                 sent[option,0] = WILL;
00193                 efun::binary_message(({IAC, WILL, option}));
00194             }
00195             else{
00196                 sent[option,0] = WONT;
00197                 efun::binary_message(({IAC, WONT, option}));
00198             }
00199         }
00200 
00201         //der Aufruf in base.c kommt fuer Magier meist zu frueh
00202         // (und fuer Spieler gar nicht ;-)
00203         if ( option == TELOPT_EOR && command == DO ){
00204             efun::binary_message( ({ IAC, EOR }) );
00205             modify_prompt();
00206         }
00207         
00208 
00209         return;
00210     }
00211     
00212     if ( command == SB ){
00213         switch (option){
00214         case TELOPT_NAWS:
00215             recd[option,2] = optargs;
00216             if ( sizeof(optargs) != 4 ){ 
00217                 break_string( sprintf("Dein Client hat einen Fehler beim"
00218                                       +"Aushandeln der TELOPT_NAWS - er hat"
00219                                       +"IAC SB %O IAC SE gesendet!\n",
00220                                       optargs), 78,
00221                               "Der GameDriver teilt Dir mit: " );
00222                 break;
00223             }
00224             
00225             if ( interactive(this_object()) ){
00226                 if ( !optargs[1] )
00227                     c = optargs[0];
00228                 else
00229                     c = optargs[1] + optargs[0] * 256;
00230 
00231                 if ( c < 35 ){
00232                     if (Query(P_TTY_SHOW))
00233                         tell_object( this_object(),
00234                                  break_string("Dein Fenster ist schmaler als"
00235                                               +" 35 Zeichen? Du scherzt. ;-)"
00236                                               +" Ich benutze den Standardwert"
00237                                               +" von 80 Zeichen.\n", 78,
00238                                               "Der GameDriver teilt Dir mit: ")
00239                                  );
00240                     c = 80;
00241                 }
00242                 
00243                 if ( !optargs[3] )
00244                     l = optargs[2];
00245                 else
00246                     l = 256 * optargs[2] + optargs[3];
00247                 
00248                 if ( l > 100 ){
00249                     l = 100;
00250                     if (Query(P_TTY_SHOW))
00251                         tell_object( this_object(),
00252                                  break_string("Tut mir leid, aber ich kann"
00253                                               +" nur bis zu 100 Zeilen"
00254                                               +" verwalten.\n", (c ? c-2 : 78),
00255                                               "Der GameDriver teilt Dir mit: " )
00256                                  );
00257                 }
00258                 
00259                 if ( l < 3 ){
00260                     if (Query(P_TTY_SHOW))
00261                         tell_object( this_object(),
00262                                  break_string("Du willst weniger als drei"
00263                                               +" Zeilen benutzen? Glaub ich"
00264                                               +" Dir nicht - ich benutze den"
00265                                               +" Standardwert von 24"
00266                                               +" Zeilen.\n", (c ? c-2 : 78),
00267                                               "Der GameDriver teilt Dir mit: " )
00268                                  );
00269                     l = 24;
00270                 }
00271 
00272                 if ( ((int) Query(P_TTY_ROWS) != l) ||
00273                      ((int) Query(P_TTY_COLS) != c) ){
00274                     Set( P_TTY_ROWS, l );
00275                     Set( P_TTY_COLS, c );
00276                     
00277                     if (Query(P_TTY_SHOW))
00278                         tell_object( this_object(),
00279                                  break_string("Du hast Deine Fenstergroesse auf"
00280                                               +" "+l+" Zeilen und "+c+
00281                                               " Spalten geaendert.\n", c-2,
00282                                               "Der GameDriver teilt Dir mit: ")
00283                                  );
00284                 }
00285             }
00286             break;
00287             
00288         case TELOPT_TTYPE:
00289             //NOTE: We do not do multiple SB SENDs due to some weird
00290             //bugs in IBM3270 emulating telnets which crash if we
00291             //do that.
00292             if ( sizeof(optargs) < 1 )
00293                 break;
00294 
00295             if ( optargs[0] != TELQUAL_IS )
00296                 break;
00297 
00298             tmpterminal = lower_case( to_string(optargs[1..]) );
00299             if ( !Terminals )
00300                 Terminals = ({ tmpterminal });
00301             else
00302                 Terminals += ({ tmpterminal });
00303             
00304             if ( Query(P_TTY_TYPE) )
00305                 Set( P_TTY_TYPE, Terminals[0] );
00306             
00307             recd[option,2] = Terminals;
00308             break;
00309             
00310         case TELOPT_TSPEED:
00311             if ( sizeof(optargs) < 2 )
00312                 break;
00313             
00314             if ( optargs[0] != TELQUAL_IS )
00315                 break;
00316             
00317             recd[option,2] = to_string( optargs[1..] );
00318             break;
00319             
00320     case TELOPT_ENVIRON:
00321     case TELOPT_NEWENV:
00322         if ( sizeof(optargs) < 3 )
00323             break;
00324         
00325         if ( optargs[0] != TELQUAL_IS )
00326         break;
00327         
00328         optargs = optargs[2..]; //first kill the TELQUAL_IS
00329         recd[option,2] = ([]);
00330         text = "";
00331         text2 = 0;
00332         
00333       for ( i = 0; i < sizeof(optargs) ; i++ ){
00334           tmpxx = optargs[i];
00335           
00336           if ( tmpxx < 5 ){
00337               if ( text && text2 ){
00338                   recd[option,2][text] = text2;
00339                   text2 = 0;
00340                   text = "";
00341               }
00342               else
00343                   text2 = "";
00344           }
00345           else
00346               if ( text2 )
00347                   text2 += sprintf("%c", tmpxx);
00348               else
00349                   text += sprintf("%c", tmpxx);
00350       }
00351       
00352       if ( text && text2 )
00353           recd[option,2][text] = text2;
00354 
00355       text = implode( old_explode(sprintf("%O\n", recd[option,2]), "\n"), "" )
00356           +"\n";
00357 
00358       /*
00359       if ( find_player("marcus") )
00360           tell_object( find_player("marcus"), text );
00361       else
00362           log_file( "marcus.rep", text );
00363       */
00364       break;
00365       
00366     case TELOPT_XDISPLOC:
00367         if ( optargs[0] != TELQUAL_IS )
00368             recd[TELOPT_XDISPLOC,2] = optargs;
00369         else
00370             recd[TELOPT_XDISPLOC,2] = lower_case( to_string(optargs[1..]) );
00371         break;
00372         
00373         case TELOPT_LINEMODE:
00374             break;
00375             
00376         default:
00377             //printf( "TELOPT:%d %d %O\n", command, option, optargs );
00378             break;
00379         }
00380         return;
00381     }
00382 }

Hier ist ein Graph der zeigt, was diese Funktion aufruft:


Variablen-Dokumentation

string last_received_termtype [static]

Definiert in Zeile 23 der Datei telnetneg.c.

string* Terminals [static]

Definiert in Zeile 22 der Datei telnetneg.c.

Wird benutzt von query_terminals(), startup_telnet_negs() und telnet_neg().

mapping TN [static]
Erzeugt am Thu Jun 3 14:42:57 2010 für MorgenGrauen Mudlib von  doxygen 1.6.3