Chapter 13. Programming Languages

So many languages, so little time

Aside from everything else that Linux does, it provides for some extraordinary programming languages to make repetitive tasks, or ones that don't seem easy to fix, very easy to accomplish.

Numerous programming languages are available for Linux. There are literally scores, or maybe hundreds, depending on how you choose to split a few hairs. A large portion of these, and nearly all of the more popular ones, have at least one implementation under Linux. To attempt to give even a brief summary of all of them would be a small book in itself. We have tried to cover the most important ones, those that we (or others we know) use and ones which are especially interesting. You may, of course, use any language that suits your needs, and not all languages are appropriate for all situations.

In this chapter, we take a break from the format in the other chapters. Two of the sections are written explicitly from a singular viewpoint: Perl and Python. Each of us has our own reasons for using the languages we use for a particular task. Mark still doesn't understand why object-oriented programming (OOP) is so cool and downloads endless extensions to Perl, whereas Cary recognizes the usefulness of Python and does nearly all his programming with it, including large amounts of Common Gateway Interface (CGI) work.

C

http://www.fsf.org/software/gcc/gcc.html

http://www.accu.org/

We are not extensive C programmers. We know enough to hack C up a little and write small programs, but C is such an important language in a UNIX-like system, it is rightly placed first in our list. The kernel and most of the everyday commands and tools you use are written in C. If you don't know C now, in the course of compiling and installing software, you will at least become a little familiar with it.

GCC is the "native" C compiler for Linux. It supports everything a good compiler should: optimization, debugging, ANSI C support, and POSIX compliance. More than a lot of compilers are shipped with or are available for some commercial OSes. SunOS 4 in particular had a very lame compiler, but it was enough to compile the first stage of GCC to bootstrap your way up to a full GCC compiler, which is all we ever used it for.

C is the most popular compiled language for high-performance, general programming. Because it is compiled, it is typically faster than an interpreted language like Perl or Python[1]. C is also a fairly low-level language. This typically leads to longer development times for software. On the other hand, because it is a low-level language, it is possible to tune code to achieve higher performance than high-level languages.

Because C compilers exist for virtually every OS and platform, it is usually possible to port a C program to other platforms. Architecture or OS-specific libraries obviously complicate this process (GUI libraries especially), but frequently analogs exist on the target platform.

When it comes right down to it, C is the foundation for all the other languages discussed here in that their compilers and/or interpreters are or were (some of the compiled languages can compile their own compilers) written at least partially in C. While nearly all of them offer high-level methods or functions for accomplishing various tasks, a proficient enough C programmer can write a program to do it just as fast, if not faster.

The reason people use higher-level (often interpreted) languages is that the development time for applications is much shorter. For the smaller tasks often addressed by high-level languages, the performance trade-off is more than acceptable. It is also very easy to write a program and then test it out. Since the programs written in Perl or Python are small, there are few requirements for building makefiles or waiting for code to compile. You can write and test in seconds. This is not to say that larger applications can't be written in an interpreted language. Grail is a Web browser written in Python (using its Tcl/Tk interface and the tkinter module), which has acceptable performance. Additionally, HotJava is a browser written in Java, which is a byte-compiled language; it too has decent performance. While neither is as feature-packed as Netscape, both have support for HTML 3.2 plus frames, among other things.

C++

http://www.accu.org/

C++ is an object-oriented, compiled language whose roots lie in C (as its name suggests). It is not as popular as C, mainly because both it and OOP are younger than C. C++ and C mix very well together: It is easy to link object files from either language and thus mix the two languages within an application. VRweb, a VRML scene viewer, and MySQL, a freeware database server, are two applications that do this. Since windowing systems are thought of as object-oriented, many libraries and programming for X are done solely in C++ (like the Qt library, the basis behind KDE).

GNU's g++ is the C++ compiler shipped with Red Hat. To dispel a common misconception, knowledge of C is not necessary to learn C++. While it is certainly useful to know C before learning C++, it's no more a necessity than knowing Basic before learning FORTRAN. They're two separate languages.

For applications where an OO language is better suited or desired, and the performance of a compiled language is necessary, C++ is the most popular choice. It is more and more frequently used in GUIs, databases, and other applications where classes and inheritance occur naturally and an OO approach is a more efficient way of coding.

Perl[2]

http://www.perl.com/

To begin, my primary job isn't to be a CGI programmer. There is CGI work involved, but I have a lot of little things that I work on. I need a general-purpose language where I can write fast, test fast, and get on to the next project. Since we have multiple servers, I want my code to be as portable as possible, allowing me to run on Solaris or Linux (even NT) with only minor changes.

One of the first projects I worked on involved Remedy, our call tracking software. One feature I wanted to add was the ability to have E-mail that comes in or out to be automatically added to a customer's call. This involves a few steps:

  1. Make sure the Subject: line for a call has a four-digit number. This would be the call number.

  2. Extract that four-digit number.

  3. Take the body of the message and the sender and add them to the call.

The first two items are actually easy, since Perl was designed as a more powerful version of awk, the pattern-matching program. Searching the Internet produced a group of people who gave a Perl interface to Remedy. This interface allowed me to log in to the Remedy server, modify the database to add the new entry, and then log out. The total size of the program was under 100 lines of code, and most of it was re-used from a sample program that came with the interface.

Another project was to monitor our phone system and make a listing every day of the number of incoming calls and the average length of each call. Someone else wrote a program to get the information and dump it in a file. All I had to do was open the file, read through until I hit a certain day's records, and then add up the times. Since Perl is made for string manipulation, I can pull out the hours, minutes, and seconds of a call, convert them all to seconds, and then build a total number of seconds of incoming calls for the day. I can then divide that by the number of calls, divide again to get hours, minutes, and seconds, and dump that into another file. If you add a cron process to do this every night right after midnight, there's the program.

Last, I have the CGI work. Most of the work on our Web site is on our internal network (some call it an intranet). This allows us to have a common repository for information—how the phones work, what drive letters are which NFS mount, even schedules listing when people will be out of the office. This last one requires the CGI work. I have a SQL database program called PostgreSQL, which (you got it!) has a Perl interface. Perl also has a CGI interface, so I can build my form and CGI script all into one compact (under 200 lines) file. In one instance, a user can enter their name, what day they'll be out, and why they'll be out. This information then gets entered into the database. In another form, a person can enter data and query the database.

Why Perl over other languages? I've known Perl for a few years and have gotten used to how quickly you can write a program and get it working. Plus you don't have to worry about all the memory, pointers, include files, and compiler problems that exist in C. I wouldn't want to write anything big in it, but my projects typically don't require large programs. They're mostly small programs, and probably smaller in terms of line count than a comparable C program. Why not Python or another language? I don't need the OOP that Python provides[3]. Other scripting languages (such as sh or csh) have all the functionality built into Perl already, but Perl has the form of a real language and is something I'm much more used to, coming from my Pascal and M days.

There are a host of applications I've started using, from MRTG (http://www.mrtg.com/) to Mozilla's Bugzilla bug-tracking program (http://www.mozilla.com/). These are all written in Perl and that make use of Perl's ability to have an almost unlimited number of plug-ins. From databases to Web programming to bug tracking, Perl does the job for me.

Python[4]

http://www.python.org

Now, unlike Mark, at least half of my job is CGI programming and ironically, I don't use Perl. I say ironically because anyone who has looked into doing CGI programming has undoubtedly noticed that most of it is done in Perl. In fact, it can be difficult to find a book that concentrates on writing CGI in any other language, but they are rumored to exist.

I used to be a huge Perl fan, but I didn't know any better then. I was actually just happy to be writing CGI. I discovered Python on my own near the end of my tenure in graduate school and wanted to learn it, but never really had the time or didn't think I did. Finally, about six months and two jobs later, I decided to finally learn another language. I really wasn't happy with Perl. I looked into Tcl and then Python again and decided to give the latter a whirl. I wrote my first "real" Python program, a CGI script, about a year ago and haven't looked back since.

Python is an object-oriented scripting language written by Guido van Rossum. It is dynamically typed, supports multiple inheritance, user-defined types, high-level dynamic types, and classes. As alluded to above, it is often compared to Perl, as the two are frequently used for similar tasks. It is younger than Perl, and as a result, its usage is less widespread. Despite this, Python has a large number of contributed modules for tasks, ranging from HTML generation to database interfacing to complex numerical calculations.

In general, you can use Python for any task where you could use any other scripting language. Python has a very clear syntax and is more extensible than other interpreted languages, with the possible exception of Tcl. It has also been shown to scale better than the average interpreted language. As an example of this, a Web browser has been written in Python using the Tkinter GUI interface. While not as high performance as compiled browsers, it is certainly tolerable. It is at least as fast as the HotJava browser, which is the most similar browser, being interpreted byte codes while Python is interpreted text.

Since it was designed as an object-oriented language from the ground up, the OO orientation is a very clean one, unlike the somewhat ad hoc OO of Perl 5. Also, development of Python on other platforms has taken place more or less concurrently, so Python is extremely portable.

Why do I like Python so much? Several reasons. First, the syntax is remarkably clear; my Python programs are much easier to read than in any other language I've used (FORTRAN, C, Basic, LISP, Bourne, and C shell). Second, program development is at least as fast as it was under Perl, usually faster. Third, I have discovered that I much prefer the OO approach to programming; inasmuch as any programming language can be said to work as my chaotic mind thinks, OOP comes closer than the "old-fashioned way," plus Python is consistently OO. Lastly, longer programs are much easier to develop and maintain.

Large CGI programs are uncommon, but certainly not unheard of. Most of the CGI I do is either a few dozen lines of code (for simple applications like reading data from a database or mailing form variables) or a couple hundred lines for more complicated stuff like inserting or updating a database or building GIFs with libgd. Now about that occasional big CGI application...

For example, I have a CGI script that processes new and renewing subscribers to the Web sites at my place of employment. It started off as a collection of small Perl scripts which checked, minimally formatted, and mailed the form variables to a Mac, where they were processed by Leads!, a front-end to 4D (a Mac DB I'd never heard of until I started the job). Needless to say, this was not the most robust way to populate our customer database. At the time, we had one subscription site and about a half-dozen types of subscriptions.

Since I started my current job, the number of subscription sites has tripled and the number of oddball marketing deals that are made has gone from zero to a half dozen or more, depending on whether I'm counting or someone from marketing is doing it; there has been an almost geometric rise in the number of different subscriptions. What started as a collection of hacked, canned Perl scripts is now a monolithic CGI of over 1,200 lines. It verifies and cross-checks as many as 40 variables; determines whether renewing members are adding sites, users, or both; inserts and/or updates as many as six tables in our membership database (at the moment, split over two DBMSs, though not for long); and prints out a nice membership certificate suitable for framing. Despite the ad hoc manner in which the group and later single script developed the code, it is still easy to read and understand—something that can rarely be said of a 1000+ line C shell or Perl script.

As much as I like Python, there are a few things about Perl that I miss. Chief among these is the regex implementation in Perl. It is wonderful. Fortunately, the next version of Python will have expanded regex capabilities that should rival Perl's. Another is the lack of string interpolation. Since Python doesn't use a $ or other symbol to distinguish variable names, this is difficult or impossible to do. I'm finding I don't miss the latter too terribly much these days, but I'm eagerly awaiting enhancements to Python's pattern-matching abilities.

There has been a fair bit of interest in making a compiler for Python, but this is not so straightforward, as Python is not a statically typed language (i.e., there are no variable declarations, a variable need not be of a constant size, and worse, a given variable name could represent a different type in various parts of a program, depending on what is assigned to it, though this is not particularly good programming style).

Python and GUIs

Several windowing toolkits exist for Python's various UNIX implementations. The most popular is tkinter, which provides an OO interface to Tcl/Tk. Tkinter provides the broadest cross-platform support, since it has been ported to Windows 95/NT and MacOS. There is also an extension for using the Athena and/or Motif (or LessTif if you have that instead) widget sets. With version 8 of Tcl/Tk promising a more native look and feel, Tkinter will likely become the GUI tool of choice for most implementations of Python.

Python on Other Platforms

Thirty-two-bit ports of Python exist for Windows 95/NT (Pythonwin) and MacOS (for both PowerPC and Motorola 68K-based Macs). WPY is a 16-bit Python for Windows 3.1 and OS/2. Additionally, a separate port exists for DOS. All of these ports, except DOS (for obvious reasons), have support for their OS's native windowing classes.

Lisp, Scheme, and Guile

http://www.cs.cmu.edu/Groups/AI/html/cltl/cltl2.html (Common Lisp)

http://www-swiss.ai.mit.edu/scheme-home.html (Scheme)

Lisp is a venerable language; its origins lie in the earliest days of artificial intelligence (AI) research in the mid-1950s. Machines like the IBM 704 and PDP-1 (yes, one not eleven) are associated with it. As computer technology progressed, Lisp was implemented on more and more architectures; no two implementations were completely interoperable so Lisp and its dialects became splintered. In the early to mid-1980s the Common Lisp specification was hammered out and an ANSI standard adopted.

Today, Common Lisp sports functions with variable numbers of arguments, a large library of utility functions (it is four decades old!), and an OOP facility. As you might guess, since it was developed for AI, Lisp also has a very sophisticated condition-handling system.

Scheme

Scheme is a much simpler dialect of Lisp. It has its own separate specification, about 50 pages in length, which lays out a conceptually elegant language. Interestingly, the Scheme specification is shorter than the index of Common Lisp: The Language.

Guile

Guile is an implementation of Scheme in an easily embeddable library. It aims to provide a cross-platform, machine-independent architecture for executing Scheme code. For Linux users, it is particularly important as it has been embedded in Gnome and as such is the preferred scripting language for Gnome. More information can be found at http://www.red-bean.com/guile.

Java

http://www.blackdown.org/

Sun's Java has weathered some growing pains over the last couple of years. While in many ways Java failed to live up to hyped-up expectations, it delivered on some promises and its user base continues to grow. Its architecture-neutral design (including its GUI tool, the AWT) delivers great portability. Like C++, it is an object-oriented language. Its popularity has given birth to large numbers of contributed extensions (classes) and a great deal of support on the 'net.

Java is different than the other languages here in that it is meant to be completely platform-neutral. Java code is compiled into platform-independent byte-code files that can then be run on a virtual machine (VM). Once a VM has been implemented on a machine, it will (in theory) run any "pure" Java program or applet. Sun has a program for certifying applications and Java implementations as "100% Pure Java." Part of the source licensing agreement from Sun requires that each JDK implementation pass all of Sun's compatibility tests before release. As more ports from Blackdown become available and pass the tests, they'll be posted to the Web site.

Java support can be compiled into the Linux kernel, allowing programs to be executed directly from the command line. Applets can be invoked this way as well, as long as Java binary support has been compiled directly into the kernel and not as a loadable module by setting the execute bit on the HTML file that references the applet class.

The feature that originally won Java much of its popularity is that the VM could be implemented in a Web browser and applets could run in the client VM provided by a Web server. At first the applets were mainly "gee whiz" things such as simple animations or moving text, clocks, and simple games like tic tac toe. However, because of the enormous amount of contributed code and additional tools and specifications, such as Java DBC (Database Connectivity), "real" applets (and applications) became much more easily realized.

Information on Java for Linux, including where to download the latest developer's kit, can be found at the URL listed above. You can also get a list of what ports are available and what tests passed.

In addition to the port of Sun's JDK, there are a number of open source Java compilers and interpreters. Gcj is an extension to egcs that aims to compile Java source and class files to native binaries. It is still under development, but work is progressing very rapidly. For more information, check http://sourceware.cygnus.com/java/gcj.html.

Kaffe is a clean room implementation of a Java VM and class libraries. It too is still in the beta stage. It implements most of the JDK 1.1 specification and parts of JDK 1.2. Kaffe comes with Red Hat. For more information, go to http://www.kaffe.org/.

Another clean JVM is Japhar, which is published under the LGPL. More information on this developing software is available at http://www.japhar.org/.

Guavac is a GPL compiler for Java. It comes with Red Hat as well. Unfortunately, its home page seems to have disappeared as of this writing.

BISS-AWT is a free replacement for the Java AWT. Rather than attempt to provide an OS-specific look and feel, it aims for its own consistent look and feel across all platforms. More information is at http://www.biss-net.com/biss-awt.html.

APIs for interfacing Java to virtually everything imaginable exist. A search through your favorite application's contributed software list will likely turn up a Java API.

Tcl/Tk

http://www.scriptics.com/

The Tool command language and Tk toolkit are the inventions of John Osterhout. Tcl is both a scripting language and a C library. Tk is not a separate language, but an extension to Tcl for interfacing to X; it is also available as a C library. Tcl and Tk have been ported to MacOS and Windows, making them good choices for cross-platform application development. However, interfaces for them exist for other languages as well, most notably the Tkinter module for Python.

Tcl by itself is actually not a particularly good scripting language. What it is designed for is "gluing" together other languages and programs. It is arguably the most extensible language listed here, with the possible exception of Python. By using Tcl and Tk together, you can quickly develop your own graphical interfaces to text-based programs (as an example).

The latest major release, version 8, enhances the level of native look and feel for Tk across X, MacOS, and Windows. This should make it very popular for building cross-platform GUIs. Those familiar with Tcl and Tk may recall that the last full releases of them were 7.6 and 4.2, respectively, and then may wonder what happened to versions 5, 6, and 7 of Tk. The version numbers of both were synchronized and Scriptics plans to release subsequent versions concurrently.

Because of Tcl's popularity, it has interfaces to several databases (MySQL, mSQL, and Sybase) and even a Netscape plug-in. Additionally, Tcl is, as of 7.6, year 2000-compliant. Scriptics has various applications for Tcl/Tk programming, including a commercial-grade Tk GUI builder, an on-the-fly compiler, and maintenance of the current, native look-and-feel ports to MacOS and Windows.

Tcl's extensibility has allowed for several extensions to both it and Tk. Extended Tcl (Tclx) provides additional functionality with the idea of creating a more standalone scripting language. ObjTcl is just what you might guess it is—a Tcl extension that allows for the use of OOP techniques. Tix is a set of extensions for Tk written in Tk. TkPerl is an interface to Tk for Perl 5.

One of the most useful Tcl extensions is Expect. It is a tool for interacting with other command-line-driven programs that require user interaction. Thus it is possible to automate any number of tasks which might otherwise require a much more complicated solution for automation.

SQL

The Structured Query Language (SQL) is the language used to talk to relational databases. In reality, it is a set of standards to which DBMS vendors add their own extensions. Because implementations of SQL differ so much, we didn't include a link for SQL; instead, we suggest you consult the documentation for your particular DBMS. We include a list of DBMS applications in our chapter on applications and in the chapter on the Red Hat application CD-ROM.

In general, SQL's syntax is fairly simple and English-like. Some implementation features function like embedded query statements, full regular expressions, or nearly full-blown programming languages. Others may support very little beyond being able to select, delete, insert, and update.

Here are a few simple examples of common SQL commands:

select * from table;

Gets all entries from all records in table.

select name,address from customer_list;

Gets only name and address from all records in customer_list.

select name,address from customer_list where cust_id=1;

Gets name and address from customer_list, where the cust_id field is equal to 1.

insert into table values (1, TRUE, "abcdef");

Creates a new record in table with the values 1 (integer), TRUE (Boolean), and "abcdef" (text).

SQL also defines things like Access Control Lists (ACLs), rollbacks (to undo changes to the database in the event of a problem), and in some cases, embedded applications. How each of these features operate, if the DBMS has that capability, is described in the documentation.

PHP

http://www.php.org/

Finally, a language we both agree on. While PHP isn't a true language for programming, it makes writing CGI scripts a lot easier. PHP has hooks into most databases we've listed, is embedded in HTML, and is easily added to the Apache Web server. Web-based mail readers, inventory tracking systems, order forms, and other sorts of programs have been written using PHP.

Since PHP is really for Web servers, we describe it in more detail in the Web server chapter. If you have to do a lot of CGI scripting and HTML programming at the same time, PHP is worth looking at.

Other Languages

There are literally scores of programming languages, certainly more than we have space to cover in any detail here. The languages already described are among the most popular on Linux and many other platforms, but many other languages bear mentioning as well.

Many readers have surely noticed we left out some old standbys.

Oldies but Goodies

FORTRAN

http://www.fortran.com/fortran/

FORTRAN is a venerable language designed mainly for numerical calculation. Its most common incarnation on Linux is in the form of g77, a FORTRAN 77 compiler. The g77 program can also be called f77, and is actually a call to GCC with a few extra options. The latest specification is FORTRAN 90, which is not as common as FORTRAN 77. Few compilers for FORTRAN 90 exist, and no free ones exist for Linux.

Basic

http://www.fys.ruu.nl/~bergmann/basic.html

This language is not as old as FORTRAN, but still popular for its simplicity; Microsoft's Visual Basic and VBScript have played a large part in keeping it popular despite its shortcomings. It has had and continues to have many different incarnations, both interpreted and compiled. Only recently has a Basic compiler become available for Linux. This may be a good programming language to start with if someone has never coded before. It also teaches the "it's not a bug, it's a feature" method of bug control after writing 10 GOTO 10.

Pascal

http://www.pascal-central.com/

Pascal is a language that has always been popular among computer scientists, both to teach good programming techniques and as a general-purpose programming language. Free compilers exist for Linux, and Red Hat includes a p2c program that converts Pascal to C, just in case you have all those high school programming assignments left.

COBOL

http://www.cobol.org/

Despite the fact that nearly everyone we know laughs at it, more lines of COBOL code have been written than any other language. Its usage is almost completely confined to financial-related applications, but there are an awful lot of banks, finance companies, and people interested in everyone else's money. It is not a language well suited for general programming tasks, but a free compiler exists and is shipped with some Linux distributions.

Of More Recent Vintage

Most of the languages we discuss next are somewhat newer than the previous ones. Also, few of them are included in any Linux distribution. Regardless, these are useful and powerful tools that you may wish to consider using in place of the more common languages.

Smalltalk

http://st-www.cs.uiuc.edu/

It is one of the fastest growing languages on the planet. Its usage is estimated to be growing at around 60 percent a year. It is a very high-level general programming language, which typically translates into short development time. Its syntax is easier to read, and the language itself is also easy to learn.

Smalltalk is about as purely object-oriented as it gets. Everything is an object, leading to very consistent methods of handling things. Smalltalk advocates the claim that it was "designed with the human being in mind."

Icon

http://www.cs.arizona.edu/icon/www/index.html

Icon is another high-level language, very high-level in fact. Its roots are in SNOBOL, though in its current incarnation, there is little resemblance. Beyond having very powerful and extensive string and data structure processing features, it does not specifically address a particular problem set. Its syntax is similar to C, but with a much higher level of semantics.

It is well suited to systems programming, though as a high-level compiled language, it is certainly useful and is used for shorter but computationally intensive tasks. Similar to Smalltalk, it was designed with the programmer in mind. This may not be as friendly as the Smalltalk slogan, but the point is clear: Icon's high-level design allows for rapid application development.

As an aside, the name Icon is not an acronym and it was chosen for the language before the term's usage to refer to window manager "icons."

Rexx

http://www.rexxla.org/

According to its creator, Rexx is "a procedural language that allows programs and algorithms to be written in a clear and structured way." Rexx's syntax is not particularly unique or unusual. It was designed to be a generic macro language to be used with another application. When its parser encounters a function that it doesn't recognize, it asks the application to handle it. This way, if Rexx is used as the macro language for multiple applications, users need to learn only one macro language and the functions for each application, which presumably will be known from normal use of the application.

Eiffel

http://www.eiffel-forum.org/

Eiffel is an OO, compiled language, designed for rapid development of clean, reusable software. There is a strong emphasis on mechanisms and techniques to promote reliability and low bug rates.

Eiffel is an open system and several commercial implementations exist. A GPL'd implementation exists as well. SmallEiffel is still in beta development, but is very usable. More information on it can be found at http://smalleiffel.loria.fr/.

Sather

http://www.icsi.berkeley.edu/~sather/

Sather's roots are in Eiffel. Early beta versions of it were nearly subsets of Eiffel 2.0; however, a major release later, both languages have gone their own ways. Sather was and is developed at the University of California, Berkeley, and as you might expect of a language developed at an educational institution, it is freeware.

Sather has garbage collection, multiple inheritance, is strongly typed, and its code can be compiled into C code. Its public license is very liberal to encourage users to contribute to its library.

Summary

We have literally just skimmed the surface of the scores (at least) of programming languages that are "officially" available and can be compiled for, or easily ported to, Linux. Certainly, we've tried to cover the most popular languages and those that come with most Linux distributions. More likely than not, one or more of these languages will meet your needs as a programmer. If not, a search on your favorite Web search engine will turn up collections of links to programming languages for you to try out.



[1] These are also known as high-level languages.

[2] Written by Mark.

[3] Perl 5 is OOP-based, and many modules take advantage of this style of programming.

[4] Written by Cary.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.15.229.111